server

package
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 56 Imported by: 0

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

View Source
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

func New(opt getopt.Opt, version string) *App

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

func (app *App) CheckAccountLockout(ctx context.Context, username string) (bool, error)

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

func (app *App) ClearLoginAttempts(ctx context.Context, username string) error

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) GetConfig added in v0.9.0

func (app *App) GetConfig() *config.Config

GetConfig returns the current application configuration.

func (*App) GetETagVersion

func (app *App) GetETagVersion() string

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

func (app *App) GetUser(ctx context.Context, username string) (*session.User, error)

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) ImagesDir added in v0.8.0

func (app *App) ImagesDir() string

ImagesDir returns the current images directory path.

func (*App) IncrementETag

func (app *App) IncrementETag() (string, error)

IncrementETag loads current ETag, increments it, saves to database, and returns new value.

func (*App) InitForBatchLoad added in v0.3.0

func (app *App) InitForBatchLoad(opt getopt.Opt) error

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

func (app *App) InitForIncrementETag(opt getopt.Opt) error

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

func (app *App) InitForUnlock() error

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

func (app *App) IsAuthenticated(w http.ResponseWriter, r *http.Request) bool

IsAuthenticated reports whether the request has a valid authenticated session.

func (*App) IsRestartRequested added in v0.9.0

func (app *App) IsRestartRequested() bool

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

func (app *App) ManualDiscoveryError() string

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

func (app *App) RecordFailedLoginAttempt(ctx context.Context, username string) error

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

func (app *App) RestartRequired() bool

RestartRequired reports whether a restart is required for pending configuration changes to take effect.

func (*App) Run

func (app *App) Run(minPoolWorkers, maxPoolWorkers int) error

func (*App) RunCacheBatchLoad added in v0.3.0

func (app *App) RunCacheBatchLoad() int

RunCacheBatchLoad runs the batch load and returns the exit code: 0 success, 1 error, 2 blocked.

func (*App) Serve

func (app *App) Serve() error

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

func (app *App) ServerError(w http.ResponseWriter, r *http.Request, err error)

ServerError logs an error and sends a generic 500 Internal Server Error response to the client.

func (*App) SetConfig added in v0.9.0

func (app *App) SetConfig(cfg *config.Config)

SetConfig replaces the current application configuration.

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

func (app *App) SetManualDiscoveryError(msg string)

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

func (app *App) SetPreloadEnabled(enabled bool)

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

func (app *App) SetRestartRequired(b bool)

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

func (app *App) TriggerDiscovery(ctx context.Context) error

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

func (app *App) UnlockAccount(username string) error

UnlockAccount unlocks a locked account by clearing failed attempts and removing the lockout.

func (*App) UpdateConfigWithPrecedence added in v0.7.0

func (app *App) UpdateConfigWithPrecedence(c *config.Config, changedFields []string)

UpdateConfigWithPrecedence stores configuration and reapplies CLI/env precedence rules.

func (*App) UpdatePassword added in v0.8.0

func (app *App) UpdatePassword(ctx context.Context, passwordHash string) error

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

func (app *App) UpdateUsername(ctx context.Context, username string) error

UpdateUsername updates the admin username in the config table. Uses gallerydb-generated queries (no inline SQL).

func (*App) WireMetrics added in v0.9.0

func (app *App) WireMetrics(collector *metrics.Collector)

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

type HandlerManagerTestSeams struct {
	BuildHandlers func(fs fs.FS) error
}

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

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

DBRoPool returns the read-only database connection pool.

func (*InfrastructureService) DBRwPool added in v0.8.0

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

GetHandlerQueries returns handler database queries for the given connection.

func (*InfrastructureService) GetMetadataQueries added in v0.8.0

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

func (s *InfrastructureService) ReconfigurePools(ctx context.Context, config *config.Config) error

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

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

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.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL