attachcache

package
v0.18.1 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package attachcache stores attachment bytes on local disk.

Attachment bytes were proxied from Jira on every view, which contradicts the premise of the tool: everything else answers from local disk, and an issue with three screenshots re-downloaded them on every open. Bytes for a given attachment id are immutable in Jira, so they cache indefinitely and the only bound needed is total size.

A cached attachment also survives having no credential at all, which is what lets the bundled demo snapshot show real images offline.

Index

Constants

View Source
const DefaultMaxBytes int64 = 512 << 20

DefaultMaxBytes bounds the cache. Attachments are usually screenshots, so a few hundred megabytes holds a working set of thousands.

Variables

This section is empty.

Functions

func Key added in v0.13.0

func Key(site, profile, issue, id string) string

Key is the on-disk identity for an attachment. Site (and issue) are mixed in so a profile that changes sites cannot serve the previous site's bytes, and a request for the wrong issue cannot read a cached id.

An empty site keeps the legacy id-only form so snapshot imports for `gadak demo` / export-static (no site) stay reachable. Existing id-only files on a real site miss after this change (the safe invalidation).

func TooLarge

func TooLarge(err error) bool

TooLarge reports whether err means the entry was skipped for its size.

Types

type Cache

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

Cache is a content-addressed store under one directory. Safe for concurrent use; a miss for the same id collapses into a single fetch.

func New

func New(dir string, maxBytes int64) (*Cache, error)

New opens (and creates) a cache directory. maxBytes <= 0 means DefaultMaxBytes.

func (*Cache) Dir

func (c *Cache) Dir() string

Dir is the directory the cache owns.

func (*Cache) Fill

func (c *Cache) Fill(id string, fetch func() (io.ReadCloser, Meta, error)) error

Fill is the single-flight write path: fetch runs at most once per id even if ten renders miss at the same moment. It returns after the bytes are on disk.

fetch must return the body, its content type, and its length (0 if unknown).

func (*Cache) Get

func (c *Cache) Get(id string) (io.ReadSeekCloser, Meta, error)

Get returns an open reader for a cached attachment. The caller closes it. A miss returns os.ErrNotExist.

func (*Cache) Has

func (c *Cache) Has(id string) bool

Has reports whether an attachment is cached, without opening it.

func (*Cache) ImportFile

func (c *Cache) ImportFile(key, path, contentType, filename string) error

ImportFile seeds an entry from a local file under the given cache key. Callers that know site/profile/issue must pass Key(...); do not pass a raw id when the site is set — that is the snapshot-import miss that D9 closed.

func (*Cache) ImportManifest added in v0.13.0

func (c *Cache) ImportManifest(dir, site, profile string, issueForID func(id string) (issue string, ok bool)) (ImportStats, error)

ImportManifest seeds the cache from a fixture directory's manifest.json. Each file is stored under Key(site, profile, issue, id). issueForID must return the issue key that owns id; ids it rejects are skipped — they are never written under the raw id (that would reopen the D9 cross-site hole).

func (*Cache) MissReason added in v0.13.0

func (c *Cache) MissReason(key, id string) string

MissReason explains a cache miss so a log can tell a key-scope mismatch (legacy id-only file still on disk) from a true absence. It never serves the legacy entry.

func (*Cache) Stats

func (c *Cache) Stats() (files int, bytes int64)

Stats reports the cache footprint, for the settings panel and `gadak status`.

type ImportStats added in v0.13.0

type ImportStats struct {
	Seeded     int
	SkippedIDs []string
}

ImportStats is what a snapshot import reports: how many files landed, and which manifest ids were skipped (not in the mirror).

type Meta

type Meta struct {
	ContentType string `json:"content_type"`
	Size        int64  `json:"size"`
	Filename    string `json:"filename,omitempty"`
}

Meta is the sidecar recorded next to each cached file. Content-Type has to survive a restart, and guessing it back from bytes is worse than storing it.

Jump to

Keyboard shortcuts

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