Documentation
¶
Overview ¶
Package cache provides a minimal caching interface for the pipeline.
The cache abstraction allows different storage backends:
- File-based (CLI)
- In-memory (testing)
- Redis (cloud platform - implemented in stacktower-cloud)
The cache is used to store:
- HTTP responses from package registries
- Parsed dependency graphs
- Computed layouts
- Rendered artifacts
Cache keys are opaque strings generated by implementations. The pipeline doesn't need to know about key structure, scoping, or TTLs.
Index ¶
- Constants
- Variables
- func Hash(data []byte) string
- func IsRetryable(err error) bool
- func RetryWithBackoff(ctx context.Context, fn func() error) error
- func RetryWithBackoffRegistry(ctx context.Context, registry string, fn func() error) error
- func Retryable(err error) error
- type ArtifactKeyOpts
- type Cache
- type DefaultKeyer
- func (k *DefaultKeyer) ArtifactKey(layoutHash string, opts ArtifactKeyOpts) string
- func (k *DefaultKeyer) GraphKey(language, pkg string, opts GraphKeyOpts) string
- func (k *DefaultKeyer) HTTPKey(namespace, key string) string
- func (k *DefaultKeyer) LayoutKey(graphHash string, opts LayoutKeyOpts) string
- type FileCache
- type GraphKeyOpts
- type InstrumentedCache
- func (c *InstrumentedCache) Close() error
- func (c *InstrumentedCache) Delete(ctx context.Context, key string) error
- func (c *InstrumentedCache) Dir() string
- func (c *InstrumentedCache) Get(ctx context.Context, key string) ([]byte, bool, error)
- func (c *InstrumentedCache) Set(ctx context.Context, key string, data []byte, ttl time.Duration) error
- type Keyer
- type LayoutKeyOpts
- type NullCache
- type RetryableError
- type ScopedKeyer
Constants ¶
const ( TTLGraph = 7 * 24 * time.Hour // 1 week - dependency graphs change with new versions TTLLayout = 30 * 24 * time.Hour // 30 days - layouts are stable once computed TTLArtifact = 90 * 24 * time.Hour // 90 days - rendered artifacts rarely need regeneration TTLHTTPResponse = 24 * time.Hour // 1 day - registry API responses (used by integrations) )
Cache TTL constants for different artifact types. These define how long cached items remain valid before expiring.
Variables ¶
var ( // ErrNotFound is returned when a requested item does not exist. ErrNotFound = errors.New("not found") // ErrNetwork is returned for HTTP failures (timeouts, connection errors, 5xx responses). ErrNetwork = errors.New("network error") // This typically means the API token is invalid, expired, or revoked. ErrUnauthorized = errors.New("unauthorized") // ErrCacheMiss is returned when an item is not found in cache. ErrCacheMiss = errors.New("cache miss") )
Sentinel errors for caching operations.
Functions ¶
func Hash ¶
Hash computes a SHA-256 hash of the input data. Returns the full 64-character hex string.
func IsRetryable ¶
IsRetryable checks if an error is wrapped with RetryableError.
func RetryWithBackoff ¶
RetryWithBackoff retries fn up to 3 times with exponential backoff. Only errors wrapped with Retryable will trigger retries.
func RetryWithBackoffRegistry ¶
RetryWithBackoffRegistry retries fn up to 3 times with exponential backoff, emitting observability hooks with the registry name for each retry.
Types ¶
type ArtifactKeyOpts ¶
type ArtifactKeyOpts struct {
Format string `json:"format"`
Style string `json:"style,omitempty"`
ShowEdges bool `json:"show_edges,omitempty"`
Popups bool `json:"popups,omitempty"`
Nebraska bool `json:"nebraska,omitempty"`
Merge bool `json:"merge,omitempty"`
Normalize bool `json:"normalize,omitempty"`
ShowVulns bool `json:"show_vulns,omitempty"`
ShowLicenses bool `json:"show_licenses,omitempty"`
FlagsOnTop bool `json:"flags_on_top,omitempty"`
}
ArtifactKeyOpts defines parameters that affect artifact rendering. Different options produce different artifacts, so they're part of the cache key.
IMPORTANT: This must include ALL options that affect rendering output:
- Format: Output format (svg/png/pdf)
- Style: Visual style (simple/handdrawn) - affects SVG structure
- ShowEdges: Show dependency edges - adds <line> elements
- Popups: Hover popups - adds metadata to SVG
- Nebraska: Maintainer ranking - adds panel to visualization
- Merge: Edge filtering for subdividers - affects which edges render
- Normalize: Whether graph was normalized - changes node/edge count
- ShowVulns: Whether vulnerability colours are rendered
When adding new render-time options to pipeline.Options, update this struct!
type Cache ¶
type Cache interface {
// Get retrieves a value by key.
// Returns (data, true, nil) on hit.
// Returns (nil, false, nil) on miss or expiration.
// Returns (nil, false, err) on error.
Get(ctx context.Context, key string) ([]byte, bool, error)
// Set stores a value with the given TTL.
// A TTL of 0 means no expiration.
Set(ctx context.Context, key string, data []byte, ttl time.Duration) error
// Delete removes a value from the cache.
// Not finding the key is not an error.
Delete(ctx context.Context, key string) error
// Close releases any resources held by the cache.
Close() error
}
Cache provides generic key-value caching with TTL support. All methods must be safe for concurrent use.
func NewFileCache ¶
NewFileCache creates a file-based cache in the given directory. The directory will be created if it doesn't exist.
func NewInstrumentedCache ¶
NewInstrumentedCache wraps a cache to emit CacheHooks on every operation.
type DefaultKeyer ¶
type DefaultKeyer struct{}
DefaultKeyer provides a simple hash-based key generation strategy.
func (*DefaultKeyer) ArtifactKey ¶
func (k *DefaultKeyer) ArtifactKey(layoutHash string, opts ArtifactKeyOpts) string
ArtifactKey generates a key for artifact caching.
func (*DefaultKeyer) GraphKey ¶
func (k *DefaultKeyer) GraphKey(language, pkg string, opts GraphKeyOpts) string
GraphKey generates a key for dependency graph caching.
func (*DefaultKeyer) HTTPKey ¶
func (k *DefaultKeyer) HTTPKey(namespace, key string) string
HTTPKey generates a key for HTTP response caching.
func (*DefaultKeyer) LayoutKey ¶
func (k *DefaultKeyer) LayoutKey(graphHash string, opts LayoutKeyOpts) string
LayoutKey generates a key for layout caching.
type FileCache ¶
type FileCache struct {
// contains filtered or unexported fields
}
FileCache implements a file-based cache for CLI usage. Cache entries are stored as files in a directory with metadata (expiration).
type GraphKeyOpts ¶
type GraphKeyOpts struct {
MaxDepth int `json:"max_depth"`
MaxNodes int `json:"max_nodes"`
Enriched bool `json:"enriched,omitempty"` // Whether GitHub metadata enrichment was performed
SecurityScan bool `json:"security_scan,omitempty"` // Whether vulnerability scan data is included
IncludePrerelease bool `json:"include_prerelease,omitempty"` // Whether prerelease versions were included
DependencyScope string `json:"dependency_scope,omitempty"` // Whether graph includes prod-only or all dependency groups
RuntimeVersion string `json:"runtime_version,omitempty"` // Target runtime version for marker evaluation (e.g., "3.11" for Python)
}
GraphKeyOpts defines parameters that affect graph resolution during parsing. Different options produce different graphs, so they're part of the cache key. Note: Normalization is applied during layout, not parsing, so it's not here.
type InstrumentedCache ¶
type InstrumentedCache struct {
// contains filtered or unexported fields
}
InstrumentedCache wraps a Cache and emits observability hooks on Get/Set operations.
func (*InstrumentedCache) Close ¶
func (c *InstrumentedCache) Close() error
func (*InstrumentedCache) Delete ¶
func (c *InstrumentedCache) Delete(ctx context.Context, key string) error
func (*InstrumentedCache) Dir ¶
func (c *InstrumentedCache) Dir() string
Dir returns the underlying directory for FileCache, empty string otherwise.
type Keyer ¶
type Keyer interface {
// HTTPKey generates a key for HTTP response caching.
// namespace isolates different registries (e.g., "npm:", "pypi:").
HTTPKey(namespace, key string) string
// GraphKey generates a key for dependency graph caching.
GraphKey(language, pkg string, opts GraphKeyOpts) string
// LayoutKey generates a key for layout caching.
LayoutKey(graphHash string, opts LayoutKeyOpts) string
// ArtifactKey generates a key for artifact caching.
ArtifactKey(layoutHash string, opts ArtifactKeyOpts) string
}
Keyer generates cache keys for pipeline artifacts. Implementations should produce stable, collision-resistant keys.
func NewScopedKeyer ¶
NewScopedKeyer creates a keyer with a prefix. The prefix is prepended to all generated keys.
type LayoutKeyOpts ¶
type LayoutKeyOpts struct {
VizType string `json:"viz_type"`
Width float64 `json:"width"`
Height float64 `json:"height"`
Normalize bool `json:"normalize,omitempty"` // Whether normalization was applied
Ordering string `json:"ordering,omitempty"`
Merge bool `json:"merge,omitempty"`
Randomize bool `json:"randomize,omitempty"`
Seed uint64 `json:"seed,omitempty"`
}
LayoutKeyOpts defines parameters that affect layout computation. Different options produce different layouts, so they're part of the cache key.
type NullCache ¶
type NullCache struct{}
NullCache is a no-op cache that never stores anything. Useful for testing or when caching should be disabled.
type RetryableError ¶
type RetryableError struct{ Err error }
RetryableError wraps an error to indicate it should trigger a retry.
func (*RetryableError) Error ¶
func (e *RetryableError) Error() string
Error returns the error message of the wrapped error.
func (*RetryableError) Unwrap ¶
func (e *RetryableError) Unwrap() error
Unwrap returns the wrapped error.
type ScopedKeyer ¶
type ScopedKeyer struct {
// contains filtered or unexported fields
}
ScopedKeyer wraps a Keyer with a prefix for multi-tenant isolation. This is useful in the cloud platform where different users or contexts need separate cache namespaces.
Example usage:
// User-specific keys for private repos userKeyer := NewScopedKeyer(NewDefaultKeyer(), "user:abc123:") // Global keys for public packages globalKeyer := NewDefaultKeyer()
func (*ScopedKeyer) ArtifactKey ¶
func (k *ScopedKeyer) ArtifactKey(layoutHash string, opts ArtifactKeyOpts) string
ArtifactKey generates a prefixed key for artifact caching.
func (*ScopedKeyer) GraphKey ¶
func (k *ScopedKeyer) GraphKey(language, pkg string, opts GraphKeyOpts) string
GraphKey generates a prefixed key for dependency graph caching.
func (*ScopedKeyer) HTTPKey ¶
func (k *ScopedKeyer) HTTPKey(namespace, key string) string
HTTPKey generates a prefixed key for HTTP response caching.
func (*ScopedKeyer) LayoutKey ¶
func (k *ScopedKeyer) LayoutKey(graphHash string, opts LayoutKeyOpts) string
LayoutKey generates a prefixed key for layout caching.