Documentation
¶
Overview ¶
Package cache is the on-disk persistence layer for processed-episode deduplication, per-user language profiles, shared-user tokens, and the scheduler's last-run marker.
The persisted JSON schema (field names, types, tags) is an inviolate contract — the on-disk /config/cache.json file is read-forward / write-back across deploys, so any schema change is a migration, not a refactor.
Index ¶
- Constants
- type Cache
- func (c *Cache) LastSchedulerRun() time.Time
- func (c *Cache) LearnLanguageProfile(userID, audioLang, subtitleLang string)
- func (c *Cache) LoadFrom(path string) error
- func (c *Cache) MarkProcessed(key string)
- func (c *Cache) SaveTo(path string) error
- func (c *Cache) SetLastSchedulerRun(t time.Time)
- func (c *Cache) SetUserTokens(tokens map[string]string)
- func (c *Cache) SubtitleLangForAudio(userID, audioLang string) (string, bool)
- func (c *Cache) UserTokens() map[string]string
- func (c *Cache) WasRecentlyProcessed(key string) bool
- type Data
Constants ¶
const ( KeyPrefixSession = "session:" KeyPrefixTimeline = "timeline:" KeyPrefixScheduler = "scheduler:" KeyPrefixStreams = "streams:" )
Cache-key prefix constants. The exact literal values are part of the on-disk cache.json schema (inviolate contract item 7) — do NOT change them without a migration.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache is the concurrent-safe persistent cache. The zero value is usable; prefer New for explicit initialization of the backing maps.
func New ¶
func New() *Cache
New returns a Cache with its maps pre-initialized. The zero value also works (maps are lazily created by the mutation methods) — New is the preferred construction point for application code because it documents intent.
func (*Cache) LastSchedulerRun ¶
LastSchedulerRun returns the timestamp of the last deep-analysis run. A zero time.Time indicates the scheduler has never run (fresh install or cache reset).
func (*Cache) LearnLanguageProfile ¶
LearnLanguageProfile records a user's audio→subtitle language preference. Empty audioLang is treated as "unknown" and ignored — this prevents the profile map from accumulating an empty-key entry for streams whose language is not reported by Plex.
func (*Cache) LoadFrom ¶
LoadFrom reads the cache from the given path. A missing file returns nil (fresh start). Capped at maxCacheSize bytes via atomicfile.LoadJSON. Warns if the file has permissive mode bits set, as tokens are stored here.
func (*Cache) MarkProcessed ¶
MarkProcessed records the current time against the key. Inline-prunes old entries when the map grows past 10000 entries to keep memory bounded.
func (*Cache) SaveTo ¶
SaveTo atomically writes the cache to the given path (temp file + rename) and ensures the final file is 0o600 (user tokens live here). The temp file is removed on any failure path so partial writes don't clutter the dir.
func (*Cache) SetLastSchedulerRun ¶
SetLastSchedulerRun records the supplied timestamp as the most recent scheduler run. Stored as a unix int64 on disk (contract item 7 — persisted schema is frozen).
func (*Cache) SetUserTokens ¶
SetUserTokens replaces the stored user-token map wholesale. The supplied map is defensive-copied so callers retain exclusive ownership of the original. Passing nil clears the map to an empty non-nil value.
func (*Cache) SubtitleLangForAudio ¶
SubtitleLangForAudio returns the learned subtitle language for a given audio language and user. Returns ("", false) if no profile exists.
func (*Cache) UserTokens ¶
UserTokens returns a defensive copy of the userID → accessToken map. Mutating the returned map does not affect cache state — callers must use SetUserTokens to persist changes.
func (*Cache) WasRecentlyProcessed ¶
WasRecentlyProcessed reports whether the given key was marked processed within the last 5 minutes. Used as a short-term dedup window for rapid successive webhook / websocket events on the same episode.
type Data ¶
type Data struct {
// ProcessedEpisodes tracks recently processed episode keys to avoid
// re-processing the same episode on rapid successive events.
// Keys include userID: "play:{userID}:{ratingKey}".
ProcessedEpisodes map[string]int64 `json:"processed_episodes"`
// LanguageProfiles maps userID → audioLang → subtitleLang.
// Empty subtitle string means "no subtitles" for that audio language.
LanguageProfiles map[string]map[string]string `json:"language_profiles"`
// UserTokens maps userID → accessToken for shared users.
UserTokens map[string]string `json:"user_tokens"`
// LastSchedulerRun is the unix timestamp of the last scheduler run.
LastSchedulerRun int64 `json:"last_scheduler_run"`
}
Data is the JSON schema persisted to /config/cache.json. Field names and JSON tags are frozen — the on-disk file is read-forward across deploys.