Help us shape the future of Go! Take the 2026 Go Developer Survey

segcache

package
v0.2.5 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2026 License: GPL-3.0 Imports: 23 Imported by: 0

Documentation

Overview

Package segcache is Ether's on-disk cache of decoded Usenet segments. It is a disk budget with segment-granular LRU eviction, pinning and a protection callback, not a library: the stream engine stores segments here so rewatches, seeks and the next episode are instant.

Concurrency model: a single mutex guards the in-memory index (O(1) map lookups plus an intrusive LRU list); segment file IO happens outside it. Per-key striped RW locks order the file-level operations on one key: Get reads under the read lock, while the rename of a Put and the unlink of an eviction/Remove run under the write lock and re-check the index, so an eviction never deletes a newer file put concurrently and a reader never observes a file being replaced underneath it.

A segment larger than the whole budget is rejected by Put with ErrTooLarge. If everything that could be evicted is pinned or protected the cache is allowed to exceed its budget (logged at most once a minute).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrTooLarge is returned by Put for a segment bigger than the whole budget.
	ErrTooLarge = errors.New("segcache: segment larger than cache budget")
	// ErrClosed is returned by mutating calls after Close.
	ErrClosed = errors.New("segcache: cache closed")
)

Functions

func ValidateSharedMount added in v0.2.4

func ValidateSharedMount(dir string, db *sql.DB) error

ValidateSharedMount checks a proposed mount without creating a pool or moving bytes. A missing marker on an existing pool is a different/unmounted share.

Types

type Cache

type Cache struct {
	// contains filtered or unexported fields
}

Cache implements core.SegmentCache.

func Open

func Open(dir string, budget int64, logger *slog.Logger) (*Cache, error)

Open opens (creating) a cache rooted at dir with a byte budget (<=0 means unlimited), rebuilding the in-memory index from disk (and cleaning stale temp files from interrupted writes). logger may be nil (slog.Default()).

func OpenShared added in v0.2.4

func OpenShared(dir string, budget int64, db *sql.DB, node string, logger *slog.Logger) (*Cache, error)

OpenShared opens a NAS pool. The directory must already exist and be mounted. The server database owns the index, pins and accounting: local SQLite for a standalone server, shared PostgreSQL for a cluster. Media files have immutable, random names. No SQLite database is placed on the NAS. Each mount must expose the same marker created by the first pool member.

func (*Cache) Close

func (c *Cache) Close() error

Close marks the cache closed. Everything is already durable (pins are written eagerly), so Close only stops further use. It is idempotent.

func (*Cache) Describe added in v0.2.4

func (c *Cache) Describe(id, title string, size int64)

Describe records a source's display metadata without counting a play.

func (*Cache) Directory added in v0.2.4

func (c *Cache) Directory() string

func (*Cache) Get

func (c *Cache) Get(releaseID string, segment int) ([]byte, bool)

Get returns the cached payload (a fresh buffer owned by the caller) and marks it as recently used. A missing, vanished or corrupt file is a miss.

func (*Cache) Has

func (c *Cache) Has(releaseID string, segment int) bool

Has reports whether the segment is indexed. No disk IO, no recency update.

func (*Cache) Metrics added in v0.2.4

func (c *Cache) Metrics() Metrics

func (*Cache) Pin

func (c *Cache) Pin(releaseID string, reason string) error

Pin protects every segment of a release from eviction while it has at least one pin reason. Pins are persisted to pins.json. If persisting fails the pin still applies in memory and the error is returned.

func (*Cache) Pins

func (c *Cache) Pins() map[string][]string

Pins returns a copy: releaseID -> sorted pin reasons.

func (*Cache) Protect

func (c *Cache) Protect(fn func() map[string]bool)

Protect registers a callback returning release IDs that must not be evicted right now. It is only called when an eviction is needed and its result is cached for a few seconds. A nil fn clears it. fn must not call Protect.

func (*Cache) Put

func (c *Cache) Put(releaseID string, segment int, data []byte) error

Put stores (or replaces) a segment crash-safely (temp file + rename) and then evicts down to the budget. A payload larger than the whole budget is rejected with ErrTooLarge and nothing is stored. Note that a stored segment may be evicted again immediately if everything else is pinned/protected.

func (*Cache) RecordPlay added in v0.2.4

func (c *Cache) RecordPlay(id, title string, size int64)

RecordPlay counts actual playback admissions, never speculative reads. The metadata is local, contains no viewer identity, and survives restarts.

func (*Cache) ReleaseBytes

func (c *Cache) ReleaseBytes(releaseID string) int64

ReleaseBytes reports how many bytes of a release are currently cached.

func (*Cache) ReleaseSizes added in v0.2.4

func (c *Cache) ReleaseSizes() map[string]int64

ReleaseSizes is a single metadata query regardless of shelf or segment count.

func (*Cache) Releases

func (c *Cache) Releases() []ReleaseUsage

Releases lists every release that has cached segments or pins, most recently used first.

func (*Cache) Remove

func (c *Cache) Remove(releaseID string) error

Remove drops all segments of a release from the index and disk. Pins are kept.

func (*Cache) Run added in v0.2.4

func (c *Cache) Run(ctx context.Context)

Run expires idle bytes even when no new streams arrive.

func (*Cache) SetBudget

func (c *Cache) SetBudget(budget int64)

SetBudget changes the budget (<=0 = unlimited) and evicts immediately if the cache is now over it.

func (*Cache) SetPolicy added in v0.2.4

func (c *Cache) SetPolicy(p Policy)

func (*Cache) Shared added in v0.2.4

func (c *Cache) Shared() bool

Shared reports whether this cache uses the cluster's NAS pool.

func (*Cache) SharedPinTx added in v0.2.4

func (c *Cache) SharedPinTx(ctx context.Context, tx *sql.Tx, id, reason string, add bool) error

SharedPinTx joins a fenced preloader transaction. This package owns the pin SQL; the caller owns its lease check. Both locks live until the same commit.

func (*Cache) StorageError added in v0.2.4

func (c *Cache) StorageError() string

StorageError is intentionally suitable for the owner UI and contains no credentials.

func (*Cache) Sweep added in v0.2.4

func (c *Cache) Sweep()

Sweep expires idle releases, retaining live streams and owner/resume pins. Dropping entries and choosing victims happen under the index lock; unlinking uses the same striped locks as budget eviction, so concurrent Puts survive.

func (*Cache) Unpin

func (c *Cache) Unpin(releaseID string, reason string) error

Unpin removes one pin reason. When the last reason goes the release becomes evictable again and the cache is evicted down to budget immediately.

func (*Cache) Usage

func (c *Cache) Usage() (used, budget int64)

Usage returns the payload bytes stored and the budget (0 = unlimited).

type Metrics added in v0.2.4

type Metrics struct {
	Hits         int64 `json:"hits"`
	Misses       int64 `json:"misses"`
	ServedBytes  int64 `json:"servedBytes"`
	EvictedBytes int64 `json:"evictedBytes"`
}

Metrics count disk-cache reads since this process started (not RAM hits).

type Policy added in v0.2.4

type Policy struct {
	Mode        string
	Retention   time.Duration
	ReplayBoost time.Duration
}

Policy controls retention of bytes already fetched. It never downloads media. A budget is a soft limit while live playback or explicit pins protect bytes.

type ReleaseUsage

type ReleaseUsage struct {
	ReleaseID  string
	Bytes      int64
	Segments   int
	LastUsed   time.Time
	Pins       []string
	Title      string
	Size       int64
	Plays      int
	LastPlayed time.Time
}

ReleaseUsage describes one release in the cache, for the admin UI.

Jump to

Keyboard shortcuts

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