filecheck

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package filecheck compares the database's file references with the file store, records the differences, and deletes files nothing has referenced for 30 days.

Index

Constants

View Source
const MaxRetention = 30 * 24 * time.Hour

MaxRetention is the longest a file may go unreferenced before it is deleted, and the default (FILE_RETENTION can make it shorter, e.g. on dev).

Variables

This section is empty.

Functions

func ParseRetention

func ParseRetention(raw string) (time.Duration, error)

ParseRetention reads a retention period: whole days ("1d", "7d") or a Go duration ("12h", "90m"). "" means MaxRetention. It must be above zero and at most MaxRetention.

Types

type Checker

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

Checker runs file checks.

func NewChecker

func NewChecker(store *Store, objects Objects) *Checker

NewChecker deletes files after MaxRetention unless WithRetention says otherwise.

func (*Checker) Run

func (c *Checker) Run(ctx context.Context, deleteDue bool) (Report, error)

Run compares the database with the file store and records the differences. With deleteDue it also deletes files that have been unreferenced for the retention period.

func (*Checker) WithRetention

func (c *Checker) WithRetention(d time.Duration) *Checker

WithRetention sets how long a file may go unreferenced before it is deleted (see ParseRetention); it is capped at MaxRetention.

type Discrepancy

type Discrepancy struct {
	Key  string `db:"key"`
	Kind Kind   `db:"kind"`
	// Detail names the rows that point at a missing file, e.g. "players 12".
	Detail    string    `db:"detail"`
	FirstSeen time.Time `db:"first_seen"`
	LastSeen  time.Time `db:"last_seen"`
}

Discrepancy is one recorded difference.

type Job

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

Job runs the file check, with deletion, once a day (see NewJob). Every server instance runs a Job; the Postgres lock means only one of them checks at a time.

func NewJob

func NewJob(checker *Checker, store *Store) *Job

NewJob checks once a day, or as often as the retention period when that is shorter, so files are deleted close to when they fall due.

func (*Job) RunOnce

func (j *Job) RunOnce(ctx context.Context)

RunOnce runs one check with deletion, unless another instance is.

func (*Job) Start

func (j *Job) Start()

Start begins the daily checks until Stop.

func (*Job) Stop

func (j *Job) Stop()

Stop ends the job. It is safe to call more than once.

type Kind

type Kind string

Kind is a type of difference between the database and the file store.

const (
	// Unreferenced is a file in the bucket that no row points to.
	Unreferenced Kind = "unreferenced"
	// Missing is a row pointing at a file that isn't in the bucket.
	Missing Kind = "missing"
)

type Objects

type Objects interface {
	List(ctx context.Context) ([]string, error)
	Delete(ctx context.Context, key string) error
}

Objects is the file store (satisfied by *storage.Store).

type Report

type Report struct {
	Objects    int
	References int
	// Retention is how long a file may go unreferenced before it is deleted.
	Retention time.Duration
	// Differences are all recorded differences after the check, oldest first.
	Differences []Discrepancy
	// Deleted are files removed for being unreferenced for 30 days.
	Deleted []string
	// DeletionSkipped explains why nothing was deleted, when deletion was asked
	// for but held back.
	DeletionSkipped string
}

Report is what one check found and did.

type Store

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

Store reads file references from the database and keeps the file_discrepancies table (migration 005).

func NewStore

func NewStore(db *sqlx.DB) *Store

func (*Store) Forget

func (s *Store) Forget(ctx context.Context, key string, kind Kind) error

Forget removes one recorded difference (after its file is deleted).

func (*Store) List

func (s *Store) List(ctx context.Context) ([]Discrepancy, error)

List returns every recorded difference, oldest first.

func (*Store) Record

func (s *Store) Record(ctx context.Context, now time.Time, found []Discrepancy) error

Record saves what a check found at now: new differences are added, ones seen before keep their first_seen, and ones no longer found are removed.

func (*Store) References

func (s *Store) References(ctx context.Context) (map[string][]string, error)

References maps each storage key a row points at to the rows pointing at it ("players 12"). It reads every table in the schema with a file_name column, found from the database itself, so a table the code doesn't know about (or one added later) can't have its files deleted by mistake.

func (*Store) Texts

func (s *Store) Texts(ctx context.Context) ([]string, error)

Texts returns every text value stored in the schema (article and event bodies, the info page, team descriptions...), in which a file may be linked directly. Columns are found from the database itself.

func (*Store) WithLock

func (s *Store) WithLock(ctx context.Context, f func(context.Context) error) (bool, error)

WithLock runs f only if no other instance holds the file check lock, and reports whether it ran.

Jump to

Keyboard shortcuts

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