This commit is contained in:
ponzischeme89
2026-08-16 12:13:51 +12:00
parent bd3732fba5
commit b9374baaf1
47 changed files with 2793 additions and 364 deletions
+45
View File
@@ -35,6 +35,10 @@ type Config struct {
// QueueLimit bounds the queue. Past it, low-priority speculation is discarded rather than
// queued — a backlog of candidates for episodes nobody reached is worse than no backlog.
QueueLimit int
// RetryCooldown keeps an unsuccessful speculative scan from returning on every queue
// refresh. Live playback remains immediate; this applies only to predicted work.
RetryCooldown time.Duration
}
func DefaultConfig() Config {
@@ -45,9 +49,50 @@ func DefaultConfig() Config {
UsefulWindow: 3 * 24 * time.Hour,
WeakWindow: 7 * 24 * time.Hour,
QueueLimit: 20,
RetryCooldown: 24 * time.Hour,
}
}
// NormaliseConfig makes both environment and admin-supplied tuning safe. It is exported
// because the gateway restores persisted settings before constructing the service.
func NormaliseConfig(cfg Config) Config {
defaults := DefaultConfig()
if cfg.PrefetchEpisodes <= 0 {
cfg.PrefetchEpisodes = defaults.PrefetchEpisodes
}
if cfg.PrefetchEpisodes > 10 {
cfg.PrefetchEpisodes = 10
}
if cfg.MaxPrefetchEpisodes < cfg.PrefetchEpisodes {
cfg.MaxPrefetchEpisodes = cfg.PrefetchEpisodes
}
if cfg.MaxPrefetchEpisodes > 20 {
cfg.MaxPrefetchEpisodes = 20
}
if cfg.QueueLimit <= 0 {
cfg.QueueLimit = defaults.QueueLimit
}
if cfg.QueueLimit > 100 {
cfg.QueueLimit = 100
}
if cfg.StrongWindow <= 0 {
cfg.StrongWindow = defaults.StrongWindow
}
if cfg.UsefulWindow <= 0 {
cfg.UsefulWindow = defaults.UsefulWindow
}
if cfg.WeakWindow <= 0 {
cfg.WeakWindow = defaults.WeakWindow
}
if cfg.RetryCooldown < 0 {
cfg.RetryCooldown = 0
}
if cfg.RetryCooldown > 30*24*time.Hour {
cfg.RetryCooldown = 30 * 24 * time.Hour
}
return cfg
}
// Watch is one episode one viewer played, reduced to the four things candidate generation
// needs. It is what a Tracearr session becomes on the way in, and keeping it this narrow is
// what lets every rule below be tested with a literal.