Documentation
¶
Overview ¶
Package server provides the core HTTP server, routing, middleware, and handlers for the web application. It integrates all the sub-packages like database, caching, and background workers to serve the photo gallery.
Index ¶
- Constants
- type App
- func (app *App) AddCommonTemplateData(w http.ResponseWriter, r *http.Request, data map[string]any, partial bool) map[string]any
- func (app *App) ApplyConfig()
- func (app *App) Build(templateFS fs.FS, appDeps interfaces.ServerDeps, authSvc auth.AuthService, ...) error
- func (app *App) CheckAccountLockout(ctx context.Context, username string) (bool, error)
- func (app *App) ClearLoginAttempts(ctx context.Context, username string) error
- func (app *App) EnsureSession(getOptionsConfig func() *session.OptionsConfig)
- func (app *App) ExecRestart()
- func (app *App) GetAdminUsername(ctx context.Context, pool *dbconnpool.DbSQLConnPool) (string, error)
- func (app *App) GetConfig() *config.Config
- func (app *App) GetETagVersion() string
- func (app *App) GetEffectiveTheme(r *http.Request, getThemes func() []string, defaultTheme string) string
- func (app *App) GetUser(ctx context.Context, username string) (*session.User, error)
- func (app *App) ImagesDir() string
- func (app *App) IncrementETag() (string, error)
- func (app *App) InitForBatchLoad(opt getopt.Opt) error
- func (app *App) InitForIncrementETag(opt getopt.Opt) error
- func (app *App) InitForUnlock() error
- func (app *App) InvalidateHTTPCache()
- func (app *App) IsAuthenticated(w http.ResponseWriter, r *http.Request) bool
- func (app *App) IsRestartRequested() bool
- func (app *App) LogProfileLocation()
- func (app *App) ManualDiscoveryError() string
- func (app *App) RecordFailedLoginAttempt(ctx context.Context, username string) error
- func (app *App) ResetStats()
- func (app *App) RestartRequired() bool
- func (app *App) Run(minPoolWorkers, maxPoolWorkers int) error
- func (app *App) RunCacheBatchLoad() int
- func (app *App) Serve() error
- func (app *App) ServerError(w http.ResponseWriter, r *http.Request, err error)
- func (app *App) SetConfig(cfg *config.Config)
- func (app *App) SetConfigService(svc config.ConfigService)
- func (app *App) SetManualDiscoveryError(msg string)
- func (app *App) SetPreloadEnabled(enabled bool)
- func (app *App) SetPreloadService(pm cachepreload.PreloadService)
- func (app *App) SetRestartRequired(b bool)
- func (app *App) Shutdown()
- func (app *App) Start(ctx context.Context, cfg *config.Config, minPoolWorkers, maxPoolWorkers int, ...)
- func (app *App) StartCacheBatchLoad() (interfaces.StartCacheBatchLoadResult, error)
- func (app *App) StartPool(ctx context.Context, poolDone chan struct{}, normalizedImagesDir string, ...)
- func (app *App) TriggerDiscovery(ctx context.Context) error
- func (app *App) TriggerRestart()
- func (app *App) UnlockAccount(username string) error
- func (app *App) UpdateConfigWithPrecedence(c *config.Config, changedFields []string)
- func (app *App) UpdatePassword(ctx context.Context, passwordHash string) error
- func (app *App) UpdateUsername(ctx context.Context, username string) error
- func (app *App) WireMetrics(collector *metrics.Collector)
- type AppTestSeams
- type BatchedWrite
- type GalleryStats
- func (gs *GalleryStats) FirstDiscovery() string
- func (gs *GalleryStats) Folders() string
- func (gs *GalleryStats) FoldersCount() int64
- func (gs *GalleryStats) Images() string
- func (gs *GalleryStats) ImagesCount() int64
- func (gs *GalleryStats) ImagesSize() int64
- func (gs *GalleryStats) LastDiscovery() string
- type HandlerManager
- type HandlerManagerTestSeams
- type InfrastructureService
- func (s *InfrastructureService) CacheMW() *cachelite.HTTPCacheMiddleware
- func (s *InfrastructureService) CalibrateCacheSizeNow(ctx context.Context)
- func (s *InfrastructureService) DBRoPool() *dbconnpool.DbSQLConnPool
- func (s *InfrastructureService) DBRwPool() *dbconnpool.DbSQLConnPool
- func (s *InfrastructureService) GetConfigQueries(cpc *dbconnpool.CpConn) config.ConfigQueries
- func (s *InfrastructureService) GetHandlerQueries(cpc *dbconnpool.CpConn) interfaces.HandlerQueries
- func (s *InfrastructureService) GetMetadataQueries(cpc *dbconnpool.CpConn) interfaces.MetadataQueries
- func (s *InfrastructureService) IncrementETag(ctx context.Context, cfgService config.ConfigService) (string, error)
- func (s *InfrastructureService) InitializeHTTPCache(config *config.Config)
- func (s *InfrastructureService) InvalidateHTTPCache()
- func (s *InfrastructureService) ReconfigurePools(ctx context.Context, config *config.Config) error
- func (s *InfrastructureService) SchedulePragmaOptimize(ctx context.Context, mask int, reason string, ...)
- func (s *InfrastructureService) SetCacheOnGalleryHit(fn func(ctx context.Context, folderID int64, sessionID string))
- func (s *InfrastructureService) SetPragmaOptimizeListening(listening bool)
- func (s *InfrastructureService) SetupDB(ctx context.Context, cfg *config.Config)
- func (s *InfrastructureService) Shutdown()
- func (s *InfrastructureService) StartDQueDrain()
- func (s *InfrastructureService) StartWriteBatcher(ctx context.Context, deferDQueDrain bool, dqueMaxDiskBytes int64)
- func (s *InfrastructureService) WriteBatcher() *writebatcher.WriteBatcher[BatchedWrite]
- type InfrastructureTestSeams
- type MemoryReclaimerConfig
- type RuntimeManager
- func (m *RuntimeManager) ExecRestart()
- func (m *RuntimeManager) GalleryStats() *GalleryStats
- func (m *RuntimeManager) IsRestartRequested() bool
- func (m *RuntimeManager) RestartRequired() bool
- func (m *RuntimeManager) Serve(handler http.Handler, addr string) error
- func (m *RuntimeManager) SetOnListen(fn func())
- func (m *RuntimeManager) SetRestartRequired(b bool)
- func (m *RuntimeManager) TriggerRestart()
- type RuntimeManagerTestSeams
- type SessionAuthFacade
- func (s *SessionAuthFacade) CheckAccountLockout(ctx context.Context, username string, pool *dbconnpool.DbSQLConnPool) (bool, error)
- func (s *SessionAuthFacade) ClearLoginAttempts(ctx context.Context, username string, pool *dbconnpool.DbSQLConnPool) error
- func (s *SessionAuthFacade) EnsureSession(getOptionsConfig func() *session.OptionsConfig)
- func (s *SessionAuthFacade) GetAdminUsername(ctx context.Context, pool *dbconnpool.DbSQLConnPool) (string, error)
- func (s *SessionAuthFacade) GetEffectiveTheme(r *http.Request, getThemes func() []string, defaultTheme string) string
- func (s *SessionAuthFacade) GetUser(ctx context.Context, username string, roPool, rwPool *dbconnpool.DbSQLConnPool) (*session.User, error)
- func (s *SessionAuthFacade) IsAuthenticated(w http.ResponseWriter, r *http.Request) bool
- func (s *SessionAuthFacade) RecordFailedLoginAttempt(ctx context.Context, username string, pool *dbconnpool.DbSQLConnPool, ...) error
- func (s *SessionAuthFacade) UnlockAccountFromTask(ctx context.Context, username string, pool *dbconnpool.DbSQLConnPool) error
- type SubsystemManager
- func (m *SubsystemManager) HydrateFileProcessingStats(ctx context.Context)
- func (m *SubsystemManager) ResetStats()
- func (m *SubsystemManager) SetPreloadEnabled(enabled bool)
- func (m *SubsystemManager) Shutdown()
- func (m *SubsystemManager) Start(ctx context.Context, cfg *config.Config, minPoolWorkers, maxPoolWorkers int, ...)
- func (m *SubsystemManager) StartCacheBatchLoad(ctx context.Context) (interfaces.StartCacheBatchLoadResult, error)
- func (m *SubsystemManager) StartPool(ctx context.Context, poolDone chan struct{}, normalizedImagesDir string, ...)
- func (m *SubsystemManager) WireMetrics(collector *metrics.Collector)
Constants ¶
const (
// SQLiteDriverName is the name of the SQLite driver to use
SQLiteDriverName = "sqlite3"
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type App ¶
type App struct {
*InfrastructureService
ConfigManager *config.ConfigManager
SessionAuthFacade *SessionAuthFacade
HandlerManager *HandlerManager
RuntimeManager *RuntimeManager
SubsystemManager *SubsystemManager
// contains filtered or unexported fields
}
App holds the shared state and resources for the entire application. It manages database connections, worker pools, queues, caching, application context, and a task scheduler for recurring and one-time tasks.
Lock Ordering: To prevent deadlocks, always acquire locks in this order when holding multiple locks: 1. ConfigManager.ConfigMu 2. httpServerMu Never acquire a lower-ordered lock while holding a higher-ordered one.
func New ¶
New creates and initializes a new App instance. It sets up the application context, session secret, importer factory, and other core components.
func (*App) AddCommonTemplateData ¶ added in v0.8.0
func (app *App) AddCommonTemplateData(w http.ResponseWriter, r *http.Request, data map[string]any, partial bool) map[string]any
AddCommonTemplateData adds common template data (auth state, theme, version, and gallery statistics) to the template data map. GalleryStats is always included regardless of partial/full page: partial HTMX responses (dashboard polls, modal swaps) now render cards that need GalleryStats. GalleryStats is a live atomic-counter cache populated by async startup queries and incremental discovery updates.
func (*App) ApplyConfig ¶ added in v0.8.0
func (app *App) ApplyConfig()
ApplyConfig applies the loaded configuration values to App struct fields.
func (*App) Build ¶ added in v0.9.0
func (app *App) Build(templateFS fs.FS, appDeps interfaces.ServerDeps, authSvc auth.AuthService, sm session.SessionManager, dbRoPool, dbRwPool *dbconnpool.DbSQLConnPool, ctx context.Context, configService config.ConfigService, getETagVersion func() string, metricsCollector *metrics.Collector) error
Build creates all handler instances using ServerDeps.
func (*App) CheckAccountLockout ¶ added in v0.8.0
CheckAccountLockout checks if an account is locked and returns true if locked, false otherwise. If the lockout has expired, it clears the lockout.
func (*App) ClearLoginAttempts ¶ added in v0.8.0
ClearLoginAttempts clears failed login attempts for a username (called on successful login).
func (*App) EnsureSession ¶ added in v0.9.0
func (app *App) EnsureSession(getOptionsConfig func() *session.OptionsConfig)
EnsureSession creates the session store and manager if not already set.
func (*App) ExecRestart ¶ added in v0.9.0
func (app *App) ExecRestart()
ExecRestart replaces the current process image.
func (*App) GetAdminUsername ¶ added in v0.9.0
func (app *App) GetAdminUsername(ctx context.Context, pool *dbconnpool.DbSQLConnPool) (string, error)
GetAdminUsername retrieves the administrator's username from the database.
func (*App) GetETagVersion ¶
GetETagVersion returns the current ETag version string.
func (*App) GetEffectiveTheme ¶ added in v0.9.0
func (app *App) GetEffectiveTheme(r *http.Request, getThemes func() []string, defaultTheme string) string
GetEffectiveTheme returns the effective theme for a request.
func (*App) GetUser ¶ added in v0.8.0
GetUser retrieves the stored user details from the database for authentication. It returns a session.User struct containing the username and the stored password hash.
func (*App) IncrementETag ¶
IncrementETag loads current ETag, increments it, saves to database, and returns new value.
func (*App) InitForBatchLoad ¶ added in v0.3.0
InitForBatchLoad performs minimal initialization for cache batch load CLI. Sets root dir, opens DB pools, loads config, initializes HTTP cache, builds handler chain. No server start, no discovery, no worker pool.
func (*App) InitForIncrementETag ¶
InitForIncrementETag initializes minimal app state for the --increment-etag command. Similar to InitForUnlock, this sets up only what's needed for ETag operations.
func (*App) InitForUnlock ¶
InitForUnlock performs minimal initialization for the --unlock CLI command. Sets root dir and opens database pools; does not load config or start workers.
func (*App) InvalidateHTTPCache ¶ added in v0.8.0
func (app *App) InvalidateHTTPCache()
InvalidateHTTPCache clears all HTTP cache entries. Called when ETag version changes to avoid serving stale responses that may contain old cache-busting URLs.
func (*App) IsAuthenticated ¶ added in v0.9.0
IsAuthenticated reports whether the request has a valid authenticated session.
func (*App) IsRestartRequested ¶ added in v0.9.0
IsRestartRequested reports whether a process restart has been requested.
func (*App) LogProfileLocation ¶
func (app *App) LogProfileLocation()
LogProfileLocation logs the profile directory and stops the profiler if active. This should be called before shutdown to ensure profile location is logged to both console and file. Idempotent: safe to call multiple times.
func (*App) ManualDiscoveryError ¶ added in v0.15.0
ManualDiscoveryError returns the current manual discovery rebuild error, or an empty string if none. In-memory only; cleared on process restart.
func (*App) RecordFailedLoginAttempt ¶ added in v0.8.0
RecordFailedLoginAttempt records a failed login attempt and locks the account after the configured lockout threshold is exceeded.
func (*App) ResetStats ¶ added in v0.8.0
func (app *App) ResetStats()
ResetStats resets the file processing statistics counters.
func (*App) RestartRequired ¶
RestartRequired reports whether a restart is required for pending configuration changes to take effect.
func (*App) RunCacheBatchLoad ¶ added in v0.3.0
RunCacheBatchLoad runs the batch load and returns the exit code: 0 success, 1 error, 2 blocked.
func (*App) Serve ¶
Serve initializes the session store and starts the HTTP server on the configured port. It runs until the server encounters a fatal error, a process restart is requested (which shuts down the server so Serve returns), or the app context is cancelled.
func (*App) ServerError ¶ added in v0.8.0
ServerError logs an error and sends a generic 500 Internal Server Error response to the client.
func (*App) SetConfigService ¶ added in v0.9.0
func (app *App) SetConfigService(svc config.ConfigService)
SetConfigService sets the ConfigService used by the configuration manager.
func (*App) SetManualDiscoveryError ¶ added in v0.15.0
SetManualDiscoveryError sets or clears the manual discovery rebuild error. Passing an empty string clears it (e.g. when the operator acknowledges it).
func (*App) SetPreloadEnabled ¶ added in v0.8.0
SetPreloadEnabled enables or disables the cache preload manager. Safe to call even if preloadManager is nil (logs a warning).
func (*App) SetPreloadService ¶ added in v0.9.0
func (app *App) SetPreloadService(pm cachepreload.PreloadService)
SetPreloadService wires the preload service into gallery handlers.
func (*App) SetRestartRequired ¶ added in v0.8.0
SetRestartRequired marks the application as needing a restart for configuration changes to take effect.
func (*App) Shutdown ¶
func (app *App) Shutdown()
Shutdown gracefully stops the application: drains the write batcher, cancels the main context, waits for background goroutines and the worker pool, closes database pools and the logger. Safe to call multiple times.
func (*App) Start ¶ added in v0.9.0
func (app *App) Start(ctx context.Context, cfg *config.Config, minPoolWorkers, maxPoolWorkers int, imagesDir, normalizedImagesDir string, removeImagesDirPrefixFn func(string, string) (string, error), getRouter func() http.Handler, getHandlerQueries func(*dbconnpool.CpConn) interfaces.HandlerQueries, getETagVersion func() string)
Start creates all subsystems from config.
func (*App) StartCacheBatchLoad ¶ added in v0.8.0
func (app *App) StartCacheBatchLoad() (interfaces.StartCacheBatchLoadResult, error)
StartCacheBatchLoad attempts to start cache batch load. Returns blocked=true when discovery is active (caller should return 409). Starts the run in a goroutine on success.
func (*App) StartPool ¶ added in v0.9.0
func (app *App) StartPool(ctx context.Context, poolDone chan struct{}, normalizedImagesDir string, removeImagesDirPrefixFn func(string, string) (string, error), processor files.FileProcessor, onFileInserted func(int64))
StartPool launches the worker pool goroutine.
func (*App) TriggerDiscovery ¶ added in v0.8.0
TriggerDiscovery walks the images directory, waits for file processing to drain, then rebuilds file_folder_index. It updates module_state for "discovery" so batch load can guard against concurrent discovery.
func (*App) TriggerRestart ¶ added in v0.9.0
func (app *App) TriggerRestart()
TriggerRestart gracefully shuts down the server so Serve returns.
func (*App) UnlockAccount ¶
UnlockAccount unlocks a locked account by clearing failed attempts and removing the lockout.
func (*App) UpdateConfigWithPrecedence ¶ added in v0.7.0
UpdateConfigWithPrecedence stores configuration and reapplies CLI/env precedence rules.
func (*App) UpdatePassword ¶ added in v0.8.0
UpdatePassword updates the admin password hash in the config table. Uses gallerydb-generated queries (no inline SQL).
func (*App) UpdateUsername ¶ added in v0.8.0
UpdateUsername updates the admin username in the config table. Uses gallerydb-generated queries (no inline SQL).
func (*App) WireMetrics ¶ added in v0.9.0
WireMetrics connects subsystem metrics to the collector.
type AppTestSeams ¶ added in v0.9.0
type AppTestSeams struct {
// NewParseTemplates replaces ui.ParseTemplates in New().
NewParseTemplates func(fs.FS) error
// NewExit replaces os.Exit in New() when template parsing fails.
NewExit func(code int)
// Serve replaces App.Serve and RuntimeManager.Serve for tests.
Serve func(handler http.Handler, addr string) error
// ProfilerStart replaces profiler.Start in Run().
ProfilerStart func(cfg profiler.Config) (stop func(), err error)
// MemoryReclaimer replaces the memoryReclaimer goroutine in Run().
MemoryReclaimer func(cfg MemoryReclaimerConfig)
// ModuleStateActive replaces moduleStateService.IsActive in StartCacheBatchLoad.
ModuleStateActive func() (bool, error)
// BatchLoadManagerRun replaces batchLoadManager.Run in StartCacheBatchLoad.
BatchLoadManagerRun func(ctx context.Context) error
// GalleryStatsStartup replaces the async startup stats goroutine in Run().
GalleryStatsStartup func()
// TriggerDiscovery replaces the walk/drain/rebuild body inside app.TriggerDiscovery()
// when non-nil. Checked after CAS guard, discoveryRunning defer, GalleryStats markRunning,
// and module_state SetActive — startup and ServerDiscoveryPost always dispatch
// go app.TriggerDiscovery(context.Background()).
TriggerDiscovery func(context.Context) error
// RebuildFileFolderIndex replaces files.RebuildFileFolderIndex at discovery completion.
RebuildFileFolderIndex func(context.Context, *dbconnpool.DbSQLConnPool) error
// FallbackConfig supplies the config used when loadConfig fails in Run.
FallbackConfig func() *config.Config
// ConfigService replaces config.NewService(...) in setDB and reconfigurePoolsFromConfig.
ConfigService config.ConfigService
// LoadConfig replaces config.Load in loadConfig.
LoadConfig func() (*config.Config, error)
// Executable replaces os.Executable() in setRootDir.
Executable func() (string, error)
// SetupBootstrapLogging replaces logging.SetupBootstrap in setupBootstrapLogging.
SetupBootstrapLogging func(rootDir string, scheduler *scheduler.Scheduler, version string) (*log.Logger, error)
// DatabaseSetup replaces database.Setup in InitForUnlock/InitForIncrementETag.
DatabaseSetup func(ctx context.Context, rootDir string, cfg *config.Config) (database.DatabasePaths, *dbconnpool.DbSQLConnPool, *dbconnpool.DbSQLConnPool, error)
}
AppTestSeams holds optional test doubles for App lifecycle paths. The zero value means use production implementations.
type BatchedWrite ¶
type BatchedWrite struct {
File *files.File // File metadata + EXIF + thumbnails
CacheEntry *cachelite.HTTPCacheEntry // HTTP cache entries
FolderIndex *files.FolderIndexRow // file_folder_index navigation row
}
BatchedWrite is a union type for all high-volume database writes. Exactly one field should be non-nil per instance.
func (*BatchedWrite) GobDecode ¶ added in v0.3.0
func (bw *BatchedWrite) GobDecode(data []byte) error
GobDecode deserializes BatchedWrite from the gob-safe wire format, reconstructing the files.File (including its Thumbnail) and cache entry from their separately-encoded blobs.
func (BatchedWrite) GobEncode ¶ added in v0.3.0
func (bw BatchedWrite) GobEncode() ([]byte, error)
GobEncode serializes BatchedWrite into a gob-safe wire format. Since files.File now has its own GobEncode/GobDecode handling the *bytes.Buffer Thumbnail, we can encode it directly without copying or mutating the caller's object.
func (BatchedWrite) Size ¶
func (bw BatchedWrite) Size() int64
Size returns estimated memory cost in bytes for batch size limiting.
type GalleryStats ¶
type GalleryStats struct {
// contains filtered or unexported fields
}
GalleryStats holds live atomic counters for gallery statistics. Display methods return "N/A" when the counter is zero and a population process is running, or formatted values otherwise.
func (*GalleryStats) FirstDiscovery ¶
func (gs *GalleryStats) FirstDiscovery() string
FirstDiscovery returns the formatted timestamp of the first discovered file.
func (*GalleryStats) Folders ¶
func (gs *GalleryStats) Folders() string
Folders returns the formatted folder count or "N/A" if unpopulated.
func (*GalleryStats) FoldersCount ¶ added in v0.11.0
func (gs *GalleryStats) FoldersCount() int64
FoldersCount returns the raw folder count for expected-total calculations.
func (*GalleryStats) Images ¶
func (gs *GalleryStats) Images() string
Images returns the formatted image count or "N/A" if unpopulated.
func (*GalleryStats) ImagesCount ¶ added in v0.11.0
func (gs *GalleryStats) ImagesCount() int64
ImagesCount returns the raw image count for expected-total calculations.
func (*GalleryStats) ImagesSize ¶
func (gs *GalleryStats) ImagesSize() int64
ImagesSize returns the total image size in bytes, or -1 if stats are still being populated (running > 0 and counter is 0).
func (*GalleryStats) LastDiscovery ¶
func (gs *GalleryStats) LastDiscovery() string
LastDiscovery returns the formatted timestamp of the last discovered file.
type HandlerManager ¶ added in v0.8.0
type HandlerManager struct {
// contains filtered or unexported fields
}
HandlerManager owns HTTP handler groups and builds them from application dependencies.
func NewHandlerManager ¶ added in v0.8.0
func NewHandlerManager() *HandlerManager
NewHandlerManager constructs an empty handler manager.
func (*HandlerManager) Build ¶ added in v0.8.0
func (m *HandlerManager) Build( templateFS fs.FS, app interfaces.ServerDeps, authSvc auth.AuthService, sm session.SessionManager, dbRoPool, dbRwPool *dbconnpool.DbSQLConnPool, ctx context.Context, configService config.ConfigService, getETagVersion func() string, metricsCollector *metrics.Collector, ) error
Build creates all handler instances using ServerDeps.
func (*HandlerManager) SetPreloadService ¶ added in v0.8.0
func (m *HandlerManager) SetPreloadService(pm cachepreload.PreloadService)
SetPreloadService wires cache preload into gallery handlers.
type HandlerManagerTestSeams ¶ added in v0.9.0
HandlerManagerTestSeams holds optional test doubles for HandlerManager. The zero value means use production implementations.
type InfrastructureService ¶ added in v0.8.0
type InfrastructureService struct {
OnFolderCreated func()
ImporterFactory func(conn *sql.Conn, q *gallerydb.CustomQueries) files.Importer
// contains filtered or unexported fields
}
InfrastructureService owns database pools, HTTP cache, write batcher, and file-system paths. No context is stored — ctx is received as a parameter where needed.
func NewInfrastructureService ¶ added in v0.8.0
func NewInfrastructureService() *InfrastructureService
NewInfrastructureService constructs the infrastructure service with production defaults.
func (*InfrastructureService) CacheMW ¶ added in v0.8.0
func (s *InfrastructureService) CacheMW() *cachelite.HTTPCacheMiddleware
CacheMW returns the HTTP cache middleware, if initialized.
func (*InfrastructureService) CalibrateCacheSizeNow ¶ added in v0.10.0
func (s *InfrastructureService) CalibrateCacheSizeNow(ctx context.Context)
CalibrateCacheSizeNow runs the cache size SUM immediately (CLI / tests).
func (*InfrastructureService) DBRoPool ¶ added in v0.8.0
func (s *InfrastructureService) DBRoPool() *dbconnpool.DbSQLConnPool
DBRoPool returns the read-only database connection pool.
func (*InfrastructureService) DBRwPool ¶ added in v0.8.0
func (s *InfrastructureService) DBRwPool() *dbconnpool.DbSQLConnPool
DBRwPool returns the read-write database connection pool.
func (*InfrastructureService) GetConfigQueries ¶ added in v0.8.0
func (s *InfrastructureService) GetConfigQueries(cpc *dbconnpool.CpConn) config.ConfigQueries
GetConfigQueries returns configuration queries for the given connection.
func (*InfrastructureService) GetHandlerQueries ¶ added in v0.8.0
func (s *InfrastructureService) GetHandlerQueries(cpc *dbconnpool.CpConn) interfaces.HandlerQueries
GetHandlerQueries returns handler database queries for the given connection.
func (*InfrastructureService) GetMetadataQueries ¶ added in v0.8.0
func (s *InfrastructureService) GetMetadataQueries(cpc *dbconnpool.CpConn) interfaces.MetadataQueries
GetMetadataQueries returns metadata queries for the given connection.
func (*InfrastructureService) IncrementETag ¶ added in v0.8.0
func (s *InfrastructureService) IncrementETag(ctx context.Context, cfgService config.ConfigService) (string, error)
IncrementETag bumps the ETag version in config and rotates the HTTP cache.
func (*InfrastructureService) InitializeHTTPCache ¶ added in v0.8.0
func (s *InfrastructureService) InitializeHTTPCache(config *config.Config)
InitializeHTTPCache creates HTTP cache middleware when caching is enabled in config.
func (*InfrastructureService) InvalidateHTTPCache ¶ added in v0.8.0
func (s *InfrastructureService) InvalidateHTTPCache()
InvalidateHTTPCache rotates the HTTP cache table to drop all cached responses.
func (*InfrastructureService) ReconfigurePools ¶ added in v0.8.0
ReconfigurePools recreates database pools from loaded config.
func (*InfrastructureService) SchedulePragmaOptimize ¶ added in v0.10.0
func (s *InfrastructureService) SchedulePragmaOptimize(ctx context.Context, mask int, reason string, quiet func(ctx context.Context) bool, run func(func()))
SchedulePragmaOptimize schedules a one-shot PRAGMA optimize that runs when the system is quiet (quiet callback returns true) and the server is listening.
For mask == PragmaOptimizeFreshConnection (0x10002), the startup CAS ensures this runs at most once per process lifetime. Other masks bypass the CAS so event-driven callers (discovery, migration) can schedule independently.
Parameters:
- quiet: function that reports whether the system is idle enough
- run: function to launch the background goroutine (e.g. wg.Go)
func (*InfrastructureService) SetCacheOnGalleryHit ¶ added in v0.8.0
func (s *InfrastructureService) SetCacheOnGalleryHit(fn func(ctx context.Context, folderID int64, sessionID string))
SetCacheOnGalleryHit replaces the OnGalleryCacheHit callback (wired by SubsystemManager after preloadManager is created).
func (*InfrastructureService) SetPragmaOptimizeListening ¶ added in v0.10.0
func (s *InfrastructureService) SetPragmaOptimizeListening(listening bool)
SetPragmaOptimizeListening enables the startup PRAGMA optimize to proceed once the system is quiet. Must be called after the HTTP server calls onServerListening.
func (*InfrastructureService) SetupDB ¶ added in v0.8.0
func (s *InfrastructureService) SetupDB(ctx context.Context, cfg *config.Config)
SetupDB creates database pools and cache store. Write batcher startup and cache size calibration are deferred until after config load and pool resize.
func (*InfrastructureService) Shutdown ¶ added in v0.8.0
func (s *InfrastructureService) Shutdown()
Shutdown closes the write batcher. The real writeBatcher.Close error branch is unreachable in production because WriteBatcher.Close always returns nil; it is exercised via testSeams.ShutdownWriteBatcher.
func (*InfrastructureService) StartDQueDrain ¶ added in v0.10.0
func (s *InfrastructureService) StartDQueDrain()
StartDQueDrain begins draining persisted dque overflow after the server is listening.
func (*InfrastructureService) StartWriteBatcher ¶ added in v0.10.0
func (s *InfrastructureService) StartWriteBatcher(ctx context.Context, deferDQueDrain bool, dqueMaxDiskBytes int64)
StartWriteBatcher creates the unified write batcher after pools are ready.
func (*InfrastructureService) WriteBatcher ¶ added in v0.8.0
func (s *InfrastructureService) WriteBatcher() *writebatcher.WriteBatcher[BatchedWrite]
WriteBatcher returns the unified write batcher, if initialized.
type InfrastructureTestSeams ¶ added in v0.9.0
type InfrastructureTestSeams struct {
BuildWriteBatcher func(ctx context.Context, maxBatchSize int, flushInterval time.Duration) (*writebatcher.WriteBatcher[BatchedWrite], error)
ShutdownWriteBatcher func() error
PerformWALCheckpoint func(ctx context.Context)
PragmaOptimize func(ctx context.Context, pool dbPoolForCheckpoint)
WALCheckpointQuery func(ctx context.Context, conn *sql.Conn) (*sql.Rows, error)
GetCacheSizeBytes func(ctx context.Context, pool *dbconnpool.DbSQLConnPool) (int64, error)
GetCacheEntryCount func(ctx context.Context, pool *dbconnpool.DbSQLConnPool) (int64, error)
EvictLRU func(ctx context.Context, pool *dbconnpool.DbSQLConnPool, targetFree int64) (int64, int64, error)
FlushBatchedWrites func(ctx context.Context, tx *sql.Tx, batch []BatchedWrite) error
HandlerQueries interfaces.HandlerQueries
RecreatePoolsWithConfig func(ctx context.Context, dbPaths database.DatabasePaths, cfg *config.Config, oldRw, oldRo *dbconnpool.DbSQLConnPool) (*dbconnpool.DbSQLConnPool, *dbconnpool.DbSQLConnPool, error)
PragmaOptimizePollInterval time.Duration
PragmaOptimizeMaxWait time.Duration
// OnBeginTx is called (if non-nil) before production Get+BeginTx
// inside buildWriteBatcher's BeginTx closure. Observe-then-production:
// the hook runs first, then production Get + Conn.BeginTx always
// follows. The hook must not return *sql.Tx or Get a pool conn.
OnBeginTx func()
// OnPut is called (if non-nil) before production dbRwPool.Put(cpcRw)
// in OnSuccess/OnError. Observe-then-production: the hook runs first,
// then production Put always follows. The hook must not Put itself.
OnPut func()
}
InfrastructureTestSeams holds optional test doubles for InfrastructureService. The zero value means use production implementations.
type MemoryReclaimerConfig ¶
type MemoryReclaimerConfig struct {
InitialDelay time.Duration
CheckInterval time.Duration
IdleThreshold time.Duration
FreeMemFunc func()
}
MemoryReclaimerConfig holds the configuration for the memory reclaimer.
type RuntimeManager ¶ added in v0.8.0
type RuntimeManager struct {
// contains filtered or unexported fields
}
RuntimeManager owns application lifecycle, HTTP server, and restart state.
func NewRuntimeManager ¶ added in v0.8.0
func NewRuntimeManager(parent context.Context) *RuntimeManager
NewRuntimeManager constructs a runtime manager with a cancellable child context.
func (*RuntimeManager) ExecRestart ¶ added in v0.8.0
func (m *RuntimeManager) ExecRestart()
ExecRestart replaces the current process image with a fresh instance.
func (*RuntimeManager) GalleryStats ¶ added in v0.11.0
func (m *RuntimeManager) GalleryStats() *GalleryStats
GalleryStats returns the live atomic-counter cache, never nil.
func (*RuntimeManager) IsRestartRequested ¶ added in v0.8.0
func (m *RuntimeManager) IsRestartRequested() bool
IsRestartRequested reports whether a process restart has been requested.
func (*RuntimeManager) RestartRequired ¶ added in v0.8.0
func (m *RuntimeManager) RestartRequired() bool
RestartRequired reports whether configuration changes require a restart.
func (*RuntimeManager) Serve ¶ added in v0.8.0
func (m *RuntimeManager) Serve(handler http.Handler, addr string) error
Serve starts the HTTP server and blocks until shutdown, error, or context cancellation.
func (*RuntimeManager) SetOnListen ¶ added in v0.10.0
func (m *RuntimeManager) SetOnListen(fn func())
SetOnListen registers a callback invoked after the HTTP server begins listening.
func (*RuntimeManager) SetRestartRequired ¶ added in v0.8.0
func (m *RuntimeManager) SetRestartRequired(b bool)
SetRestartRequired records whether a configuration change requires process restart.
func (*RuntimeManager) TriggerRestart ¶ added in v0.8.0
func (m *RuntimeManager) TriggerRestart()
TriggerRestart gracefully shuts down the HTTP server to prepare for exec restart.
type RuntimeManagerTestSeams ¶ added in v0.9.0
type RuntimeManagerTestSeams struct {
Executable func() (string, error)
ExecCommand func(path string, args []string, env []string) error
Exit func(code int)
BeforeListen func()
Shutdown func(ctx context.Context) error
}
RuntimeManagerTestSeams holds optional test doubles for RuntimeManager. The zero value means use production implementations.
type SessionAuthFacade ¶ added in v0.9.0
type SessionAuthFacade struct {
// contains filtered or unexported fields
}
SessionAuthFacade owns session management and authentication.
func NewSessionAuthFacade ¶ added in v0.9.0
func NewSessionAuthFacade(sessionSecret string) *SessionAuthFacade
NewSessionAuthFacade constructs a facade for session and auth operations.
func (*SessionAuthFacade) CheckAccountLockout ¶ added in v0.9.0
func (s *SessionAuthFacade) CheckAccountLockout(ctx context.Context, username string, pool *dbconnpool.DbSQLConnPool) (bool, error)
CheckAccountLockout reports whether the account is currently locked.
func (*SessionAuthFacade) ClearLoginAttempts ¶ added in v0.9.0
func (s *SessionAuthFacade) ClearLoginAttempts(ctx context.Context, username string, pool *dbconnpool.DbSQLConnPool) error
ClearLoginAttempts resets failed login attempts after a successful login.
func (*SessionAuthFacade) EnsureSession ¶ added in v0.9.0
func (s *SessionAuthFacade) EnsureSession(getOptionsConfig func() *session.OptionsConfig)
EnsureSession initializes the cookie store and session manager if needed.
func (*SessionAuthFacade) GetAdminUsername ¶ added in v0.9.0
func (s *SessionAuthFacade) GetAdminUsername(ctx context.Context, pool *dbconnpool.DbSQLConnPool) (string, error)
GetAdminUsername returns the configured admin username from the database.
func (*SessionAuthFacade) GetEffectiveTheme ¶ added in v0.9.0
func (s *SessionAuthFacade) GetEffectiveTheme(r *http.Request, getThemes func() []string, defaultTheme string) string
GetEffectiveTheme resolves the active theme from cookie or configured default.
func (*SessionAuthFacade) GetUser ¶ added in v0.9.0
func (s *SessionAuthFacade) GetUser(ctx context.Context, username string, roPool, rwPool *dbconnpool.DbSQLConnPool) (*session.User, error)
GetUser loads the stored admin credentials for the given username.
func (*SessionAuthFacade) IsAuthenticated ¶ added in v0.9.0
func (s *SessionAuthFacade) IsAuthenticated(w http.ResponseWriter, r *http.Request) bool
IsAuthenticated reports whether the request has a valid authenticated session.
func (*SessionAuthFacade) RecordFailedLoginAttempt ¶ added in v0.9.0
func (s *SessionAuthFacade) RecordFailedLoginAttempt(ctx context.Context, username string, pool *dbconnpool.DbSQLConnPool, lockoutDuration int64, lockoutThreshold int64, sched *scheduler.Scheduler, unlockFn func(ctx context.Context, username string) error, ) error
RecordFailedLoginAttempt increments failed attempts and locks the account when the threshold is reached.
func (*SessionAuthFacade) UnlockAccountFromTask ¶ added in v0.9.0
func (s *SessionAuthFacade) UnlockAccountFromTask(ctx context.Context, username string, pool *dbconnpool.DbSQLConnPool) error
UnlockAccountFromTask clears a scheduled lockout for the given username.
type SubsystemManager ¶ added in v0.8.0
type SubsystemManager struct {
// contains filtered or unexported fields
}
SubsystemManager owns background processing subsystems.
func NewSubsystemManager ¶ added in v0.8.0
func NewSubsystemManager(infra *InfrastructureService) *SubsystemManager
NewSubsystemManager constructs a subsystem manager bound to infrastructure services.
func (*SubsystemManager) HydrateFileProcessingStats ¶ added in v0.15.0
func (m *SubsystemManager) HydrateFileProcessingStats(ctx context.Context)
HydrateFileProcessingStats loads the persisted last-run file processing counters into processingStats. Only the skip-startup-discovery incident path calls this (runDiscovery is false): when a startup walk runs, the walk and Run()'s completion monitor own the counters, and a hydrated TotalFound would make the monitor treat the run as started on stale data. InFlight is never hydrated — it is live state and is not persisted. Nil service or nil stats makes this a no-op.
func (*SubsystemManager) ResetStats ¶ added in v0.8.0
func (m *SubsystemManager) ResetStats()
ResetStats clears file-processing counters.
func (*SubsystemManager) SetPreloadEnabled ¶ added in v0.8.0
func (m *SubsystemManager) SetPreloadEnabled(enabled bool)
SetPreloadEnabled enables or disables cache preload scheduling.
func (*SubsystemManager) Shutdown ¶ added in v0.8.0
func (m *SubsystemManager) Shutdown()
Shutdown stops preload and file-processing subsystems and releases the discovery dque flock.
App.Shutdown orders cancel → poolDone → Shutdown, so production workers have already exited before the queue is closed; Close is for flock release, not a worker signal. SubsystemManager.Shutdown itself does not wait on poolDone, so direct tests that call Shutdown while workers are still live may observe ErrClosedQueue from workers — that is expected. Close is idempotent.
func (*SubsystemManager) Start ¶ added in v0.8.0
func (m *SubsystemManager) Start( ctx context.Context, cfg *config.Config, minPoolWorkers, maxPoolWorkers int, imagesDir, normalizedImagesDir string, removeImagesDirPrefixFn func(string, string) (string, error), getRouter func() http.Handler, getHandlerQueries func(*dbconnpool.CpConn) interfaces.HandlerQueries, getETagVersion func() string, )
Start creates all subsystems from config. Call after config is loaded and imagesDir is set but before handler building.
func (*SubsystemManager) StartCacheBatchLoad ¶ added in v0.8.0
func (m *SubsystemManager) StartCacheBatchLoad(ctx context.Context) (interfaces.StartCacheBatchLoadResult, error)
StartCacheBatchLoad starts background cache batch loading when discovery is not active.
func (*SubsystemManager) StartPool ¶ added in v0.8.0
func (m *SubsystemManager) StartPool(ctx context.Context, poolDone chan struct{}, normalizedImagesDir string, removeImagesDirPrefixFn func(string, string) (string, error), processor files.FileProcessor, onFileInserted func(int64))
StartPool launches the worker pool goroutine.
func (*SubsystemManager) WireMetrics ¶ added in v0.8.0
func (m *SubsystemManager) WireMetrics(collector *metrics.Collector)
WireMetrics connects subsystem components to the metrics collector.
Source Files
¶
- app.go
- app_cache.go
- app_cli.go
- app_db.go
- app_lifecycle.go
- app_maintenance.go
- app_startup.go
- auth_service.go
- batched_write.go
- batched_write_flush.go
- batcher_wiring.go
- cache_submit.go
- discovery_dque.go
- handler_manager.go
- infrastructure_batcher.go
- infrastructure_cache.go
- infrastructure_cache_calibration.go
- infrastructure_pool.go
- infrastructure_pragma.go
- infrastructure_service.go
- quiet_once.go
- router.go
- runtime_manager.go
- server.go
- subsystem_manager.go
- testseams.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package auth provides authentication services for the application.
|
Package auth provides authentication services for the application. |
|
Package cachebatch provides batch cache loading with bounded concurrency.
|
Package cachebatch provides batch cache loading with bounded concurrency. |
|
Package cachepreload provides cache preloading when folders are opened.
|
Package cachepreload provides cache preloading when folders are opened. |
|
Package conditional provides pure functions for HTTP conditional request matching.
|
Package conditional provides pure functions for HTTP conditional request matching. |
|
Package config provides configuration loading, validation, persistence, and application for the server.
|
Package config provides configuration loading, validation, persistence, and application for the server. |
|
Package database wires SQLite connection pools and database lifecycle for the server.
|
Package database wires SQLite connection pools and database lifecycle for the server. |
|
Package files provides file discovery, metadata extraction, and thumbnail generation for the photo gallery.
|
Package files provides file discovery, metadata extraction, and thumbnail generation for the photo gallery. |
|
Package handlers provides HTTP request handlers for the web application.
|
Package handlers provides HTTP request handlers for the web application. |
|
Package interfaces holds shared contracts consumed by both the server orchestrator (App) and the handlers package.
|
Package interfaces holds shared contracts consumed by both the server orchestrator (App) and the handlers package. |
|
Package logging configures structured logging for the server application.
|
Package logging configures structured logging for the server application. |
|
Package metrics provides centralized metrics collection for the dashboard.
|
Package metrics provides centralized metrics collection for the dashboard. |
|
Package middleware provides HTTP middleware for the server (auth, COP, logging).
|
Package middleware provides HTTP middleware for the server (auth, COP, logging). |
|
Package modulestate tracks active/inactive state for server subsystems.
|
Package modulestate tracks active/inactive state for server subsystems. |
|
Package pathutil provides path manipulation utilities for the server package.
|
Package pathutil provides path manipulation utilities for the server package. |
|
Package security provides pure functions for security and lockout calculations.
|
Package security provides pure functions for security and lockout calculations. |
|
Package session provides session store, session cookie options, and authentication helpers for the web application.
|
Package session provides session store, session cookie options, and authentication helpers for the web application. |
|
Package template provides pure functions for building template data maps.
|
Package template provides pure functions for building template data maps. |
|
Package ui provides HTML template rendering and cache version management for the application's user interface.
|
Package ui provides HTML template rendering and cache version management for the application's user interface. |
|
Package validation provides configuration and input validation helpers.
|
Package validation provides configuration and input validation helpers. |