Documentation
¶
Index ¶
- func WrapCluster(inner cluster.Cluster, conf Config, monitor *Monitor) (cluster.Cluster, manager.Runnable, error)
- type Config
- type Monitor
- type Overlay
- func (c *Overlay) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error
- func (c *Overlay) Delete(ctx context.Context, obj client.Object, opts ...client.DeleteOption) error
- func (c *Overlay) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error
- func (c *Overlay) Get(ctx context.Context, key client.ObjectKey, obj client.Object, ...) error
- func (c *Overlay) IndexField(ctx context.Context, obj client.Object, field string, ...) error
- func (c *Overlay) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error
- func (c *Overlay) NeedLeaderElection() bool
- func (c *Overlay) Patch(ctx context.Context, obj client.Object, patch client.Patch, ...) error
- func (c *Overlay) Start(ctx context.Context) error
- func (c *Overlay) Status() client.StatusWriter
- func (c *Overlay) Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error
- type RootConfig
- type Wrapper
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WrapCluster ¶
func WrapCluster(inner cluster.Cluster, conf Config, monitor *Monitor) (cluster.Cluster, manager.Runnable, error)
WrapCluster wraps inner with a transparent in-process overlay cache and returns the wrapped cluster.Cluster together with the overlay's lifecycle Runnable.
The returned cluster.Cluster delegates everything to inner except GetClient and GetFieldIndexer, which return the overlay client so per-cluster reads and writes flow through the cache. GVK strings in conf are formatted as "<group>/<version>/<Kind>" and resolved against inner.GetScheme().
The returned manager.Runnable is the overlay itself: it attaches informer eviction handlers (reading informers from inner.GetCache()) and runs the TTL cleanup loop. The caller MUST add it to the manager. It does NOT re-Start the inner cluster — the manager owns the inner cluster's lifecycle separately.
monitor observes the overlay size per GVK and may be nil (metrics off). It is internal to this package (only Wrapper and tests call WrapCluster), so this signature does not touch the multicluster client.
Types ¶
type Config ¶
type Config struct {
// Enabled turns the overlay cache on. When false (the default), clusters are
// used unwrapped: no overlay, no eviction Runnable, zero overhead.
Enabled bool `json:"enabled"`
// GVKs the cache should overlay, formatted as "<group>/<version>/<Kind>".
// Calls for GVKs not listed here are passed through unchanged.
GVKs []string `json:"gvks"`
// TTL is the maximum lifetime of an overlay entry before it is evicted by
// the background cleanup goroutine, guarding against entries that never
// appear in the informer (e.g. after a crash). Defaults to 2m when zero.
TTL metav1.Duration `json:"ttl,omitzero"`
}
Config configures the transparent in-process overlay cache.
type Monitor ¶
type Monitor struct {
// contains filtered or unexported fields
}
Monitor is a standalone prometheus.Collector that tracks the overlay's per-(gvk, host) entry count. It exposes both the current size and a high-watermark that is reset to the current size on every Collect, so transient spikes are captured even when the overlay is empty at scrape time.
Overlay entries are extremely short-lived (evicted within milliseconds once the informer observes the write), so a plain gauge sampled at scrape time would almost always read zero. A consistently non-zero high-watermark is a strong signal that eviction is broken (informer lag, UID mismatch, TTL fallback firing).
func NewMonitor ¶
NewMonitor returns a Monitor whose metric names are prefixed with prefix (e.g. "cortex_" yields "cortex_cache_overlay_entries").
func (*Monitor) Collect ¶
func (m *Monitor) Collect(ch chan<- prometheus.Metric)
Collect implements prometheus.Collector. It emits the current size and the high-watermark for every observed series, then resets each high-watermark to the current size so the next scrape measures a fresh window.
func (*Monitor) Describe ¶
func (m *Monitor) Describe(ch chan<- *prometheus.Desc)
Describe implements prometheus.Collector.
type Overlay ¶
type Overlay struct {
client.Client // inner client, used for delegation
// contains filtered or unexported fields
}
Overlay wraps an inner client.Client with a transparent in-process overlay. Writes populate the overlay; reads merge the overlay with the inner (informer-backed) result; entries are evicted once the real object appears in an informer (see runnable.go) or after TTL expiry.
It embeds client.Client so all methods not overridden below are delegated to the inner client unchanged.
The local overlay maps each cached GVK to a set of entries keyed by namespace/name. An entry is either live (a pending write not yet visible in the informer) or a tombstone (a Delete that has not yet propagated). Reads merge the inner result with these entries: tombstones suppress objects; live entries override or supplement the inner result.
func (*Overlay) Create ¶
Create delegates to the inner client and, on success for a cached GVK, adds the object to the overlay.
func (*Overlay) Delete ¶
Delete delegates to the inner client and, on success for a cached GVK, stores a tombstone in the overlay. The object is NOT immediately removed from the local map; it stays as a deleted=true entry until the deletion propagates through the informer (which triggers eviction) or the TTL expires. This ensures that reads between the Delete call and the informer event correctly return NotFound rather than serving a stale object from the informer cache.
func (*Overlay) DeleteAllOf ¶
func (c *Overlay) DeleteAllOf(ctx context.Context, obj client.Object, opts ...client.DeleteAllOfOption) error
DeleteAllOf delegates to the inner client and, on success for a cached GVK, tombstones all overlay entries that match the delete options. Objects that live only in the informer cache (not in the overlay) will be evicted naturally once the deletion propagates through the informer.
func (*Overlay) Get ¶
func (c *Overlay) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error
Get delegates to the inner client, then applies the overlay: a tombstone yields NotFound; a live overlay entry overrides the inner result; and an overlay entry can satisfy a Get that the inner client reports as NotFound.
func (*Overlay) IndexField ¶
func (c *Overlay) IndexField(ctx context.Context, obj client.Object, field string, extractValue client.IndexerFunc) error
IndexField delegates to the inner client (if it is a FieldIndexer) and also registers the IndexerFunc with the overlay so overlay entries can be matched against MatchingFields.
func (*Overlay) List ¶
func (c *Overlay) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error
List delegates to the inner client, then merges the overlay into the result.
func (*Overlay) NeedLeaderElection ¶
NeedLeaderElection reports that the Overlay's Start lifecycle must run on every replica, not only the elected leader. The overlay is per-process state, so its eviction handlers and TTL cleanup have to run wherever the client is used, regardless of leader election.
func (*Overlay) Patch ¶
func (c *Overlay) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error
Patch delegates to the inner client and, on success for a cached GVK, refreshes the overlay entry with the patched object.
func (*Overlay) Start ¶
Start implements manager.Runnable. It attaches informer event handlers for eviction and runs the TTL cleanup loop until ctx is done.
func (*Overlay) Status ¶
func (c *Overlay) Status() client.StatusWriter
Status returns a status writer that mirrors status Update/Patch writes for cached GVKs into the overlay.
type RootConfig ¶
type RootConfig struct {
// Cache configures the transparent in-process overlay cache.
Cache Config `json:"cache"`
}
type Wrapper ¶
type Wrapper struct {
// contains filtered or unexported fields
}
Wrapper implements the multicluster.ClusterWrapper interface for the overlay cache. It does not import the multicluster package; interface satisfaction is structural and checked at the call site (e.g. in main.go). It captures the manager at construction time because the ClusterWrapper interface does not pass a manager to WrapCluster.
func NewWrapper ¶
NewWrapper returns a Wrapper that applies the overlay cache to any cluster passed to WrapCluster, registering the overlay's lifecycle Runnable with mgr. The monitor is shared across every wrapped cluster and is supplied by the caller (so this library package hardcodes no project-specific metric prefix); it may be nil to disable overlay size metrics. Register it on the metrics registry from the caller.
func (*Wrapper) WrapCluster ¶
WrapCluster applies the overlay cache to cl, registers the overlay's lifecycle Runnable with the captured manager, and returns the wrapped cluster. Satisfies multicluster.ClusterWrapper structurally.