Documentation
¶
Overview ¶
Package backend provides storage backend abstractions for the content cache.
Index ¶
- Constants
- Variables
- func IsFramed(r io.ReadSeeker) (bool, error)
- func WriteFramed(w io.Writer, header *BlobHeader, body io.Reader) error
- type Backend
- type BlobHeader
- type Filesystem
- func (fs *Filesystem) Delete(ctx context.Context, key string) error
- func (fs *Filesystem) Exists(ctx context.Context, key string) (bool, error)
- func (fs *Filesystem) List(ctx context.Context, prefix string) ([]string, error)
- func (fs *Filesystem) Read(ctx context.Context, key string) (io.ReadCloser, error)
- func (fs *Filesystem) ReadFramed(ctx context.Context, key string) (*BlobHeader, io.ReadCloser, error)
- func (fs *Filesystem) Root() string
- func (fs *Filesystem) Size(ctx context.Context, key string) (int64, error)
- func (fs *Filesystem) Write(ctx context.Context, key string, r io.Reader) error
- func (fs *Filesystem) WriteFramed(ctx context.Context, key string, header *BlobHeader, body io.Reader) error
- func (fs *Filesystem) Writer(ctx context.Context, key string) (io.WriteCloser, error)
- type FramedBackend
- type SizeAwareBackend
- type WriterBackend
Constants ¶
const MaxHeaderSize = 64 * 1024
MaxHeaderSize is the maximum allowed size for the JSON header (64 KiB).
Variables ¶
var ( // MagicBytes is the 4-byte prefix for framed blob files. MagicBytes = []byte("CCB1") // ErrInvalidMagic is returned when a file doesn't start with the expected magic bytes. ErrInvalidMagic = errors.New("invalid magic bytes: expected CCB1") // ErrHeaderTooLarge is returned when the header exceeds MaxHeaderSize. ErrHeaderTooLarge = errors.New("header exceeds maximum size") )
var ErrNotFound = errors.New("not found")
ErrNotFound is returned when a key does not exist in the backend.
Functions ¶
func IsFramed ¶ added in v1.2.0
func IsFramed(r io.ReadSeeker) (bool, error)
IsFramed checks if the reader contains a framed blob by looking for magic bytes. The reader is seeked back to the start after checking.
func WriteFramed ¶ added in v1.2.0
WriteFramed writes a framed blob to the writer. Format: MAGIC (4 bytes) | HDRLEN (uint32 big-endian) | HDRBYTES (JSON) | BODYBYTES
Types ¶
type Backend ¶
type Backend interface {
// Write stores data at the given key.
// If the key already exists, it should be overwritten.
Write(ctx context.Context, key string, r io.Reader) error
// Read retrieves data at the given key.
// Returns ErrNotFound if the key does not exist.
// The caller must close the returned ReadCloser.
Read(ctx context.Context, key string) (io.ReadCloser, error)
// Delete removes data at the given key.
// Returns nil if the key does not exist (idempotent).
Delete(ctx context.Context, key string) error
// Exists checks if a key exists.
Exists(ctx context.Context, key string) (bool, error)
// List returns all keys with the given prefix.
// The prefix should use "/" as the path separator.
List(ctx context.Context, prefix string) ([]string, error)
}
Backend defines the interface for storage backends. Implementations must be safe for concurrent use.
type BlobHeader ¶ added in v1.2.0
type BlobHeader struct {
ContentType string `json:"content_type"`
ContentLength int64 `json:"content_length"`
CachedAt string `json:"cached_at"`
UpstreamETag string `json:"upstream_etag,omitempty"`
ContentHash string `json:"content_hash"`
}
BlobHeader contains metadata for a cached blob.
func ReadFramed ¶ added in v1.2.0
ReadFramed reads a framed blob from the reader. Returns the parsed header and a reader for the body.
type Filesystem ¶
type Filesystem struct {
// contains filtered or unexported fields
}
Filesystem implements Backend using the local filesystem. Writes are atomic using a temp file and rename pattern.
func NewFilesystem ¶
func NewFilesystem(root string) (*Filesystem, error)
NewFilesystem creates a new filesystem backend rooted at the given path. The directory will be created if it does not exist.
func (*Filesystem) Delete ¶
func (fs *Filesystem) Delete(ctx context.Context, key string) error
Delete removes data at the given key.
func (*Filesystem) Read ¶
func (fs *Filesystem) Read(ctx context.Context, key string) (io.ReadCloser, error)
Read retrieves data at the given key.
func (*Filesystem) ReadFramed ¶ added in v1.2.0
func (fs *Filesystem) ReadFramed(ctx context.Context, key string) (*BlobHeader, io.ReadCloser, error)
ReadFramed retrieves framed content at the given key.
func (*Filesystem) WriteFramed ¶ added in v1.2.0
func (fs *Filesystem) WriteFramed(ctx context.Context, key string, header *BlobHeader, body io.Reader) error
WriteFramed stores framed content (header + body) at the given key.
func (*Filesystem) Writer ¶
func (fs *Filesystem) Writer(ctx context.Context, key string) (io.WriteCloser, error)
Writer returns a WriteCloser for writing to the given key. The write is atomic - data is written to a temp file and renamed on Close.
type FramedBackend ¶ added in v1.2.0
type FramedBackend interface {
Backend
// WriteFramed stores framed content (header + body) at the given key.
WriteFramed(ctx context.Context, key string, header *BlobHeader, body io.Reader) error
// ReadFramed retrieves framed content at the given key.
// Returns the parsed header and a reader for the body.
// The caller must close the returned ReadCloser.
ReadFramed(ctx context.Context, key string) (*BlobHeader, io.ReadCloser, error)
}
FramedBackend extends Backend with framed blob support.
type SizeAwareBackend ¶
type SizeAwareBackend interface {
Backend
// Size returns the size in bytes of the data at the given key.
// Returns ErrNotFound if the key does not exist.
Size(ctx context.Context, key string) (int64, error)
}
SizeAwareBackend extends Backend with size information.
type WriterBackend ¶
type WriterBackend interface {
Backend
// Writer returns a WriteCloser for writing to the given key.
// The write is only committed when Close returns nil.
// If Close returns an error, the write should be considered failed.
Writer(ctx context.Context, key string) (io.WriteCloser, error)
}
WriterBackend extends Backend with direct writer access. This is optional and allows backends to provide more efficient writes for callers that can write directly rather than provide a reader.