Documentation
¶
Overview ¶
Package dockerpool is the in-memory warm-container pool for Docker sandboxes.
Index ¶
- Variables
- func NewSlotID() (string, error)
- func ParkReservationID(slotID string) string
- func RunRefill(ctx context.Context, pool *Pool, cfg RefillConfig, spawner Spawner, ...)
- type Key
- type Metrics
- type ParkShape
- type ParkedSlot
- type Pool
- func (p *Pool) Acquire(ctx context.Context, key Key, currentImageID string) (*ParkedSlot, error)
- func (p *Pool) ClearSpawnFailures(ks string)
- func (p *Pool) Close() int
- func (p *Pool) HasReady(key Key) bool
- func (p *Pool) ListTargets() []Key
- func (p *Pool) MarkSpawning(ks string)
- func (p *Pool) Metrics() *Metrics
- func (p *Pool) NoteMiss(key Key)
- func (p *Pool) NoteSpawnFailure(ks string) bool
- func (p *Pool) NoteTarget(key Key)
- func (p *Pool) PinTarget(key Key)
- func (p *Pool) ReapIdle(now time.Time) int
- func (p *Pool) RecordLoaded(slot *ParkedSlot)
- func (p *Pool) ReleasePark(slotID string)
- func (p *Pool) ReturnSlot(slot *ParkedSlot)
- func (p *Pool) Run(ctx context.Context, cfg RefillConfig, spawner Spawner, gate RefillGate)
- func (p *Pool) SetDefaultDepth(n int)
- func (p *Pool) SetIdleTTL(d time.Duration)
- func (p *Pool) SetMaxImages(n int)
- func (p *Pool) SetParkReleaser(fn func(slotID string))
- func (p *Pool) SetSpawner(s Spawner)
- func (p *Pool) SpawnBudget(ks string) int
- func (p *Pool) UnmarkSpawning(ks string)
- type RefillConfig
- type RefillGate
- type Snapshot
- type Spawner
- type SpawnerHandle
Constants ¶
This section is empty.
Variables ¶
var ErrNoSlot = errors.New("docker pool: no slot")
ErrNoSlot is returned when no warm slot is available for the key.
var ErrStaleImage = errors.New("docker pool: stale image")
ErrStaleImage is returned when a parked slot's image ID no longer matches.
Functions ¶
func ParkReservationID ¶
ParkReservationID is the capacity admitter key for a parked slot.
func RunRefill ¶
func RunRefill(ctx context.Context, pool *Pool, cfg RefillConfig, spawner Spawner, gate RefillGate, logger *slog.Logger)
RunRefill is a convenience wrapper matching daemon wiring style.
Types ¶
type Key ¶
type Key struct {
Image string
ImageDigest string
ImageRegistryRef string
ImageDistributionMode string
Runtime string
}
Key identifies a warm-pool target by resolved image identity + runtime.
func KeyFromRequest ¶
func KeyFromRequest(req models.CreateSandboxRequest, runtime string) Key
KeyFromRequest builds a pool key from a create request and resolved runtime.
func (Key) KeyString ¶
KeyString returns a stable map key for the pool. It canonicalizes through the same defaulting rule the service's image-distribution normalization applies (empty mode → external_registry, empty ref → image), because keys reach the pool from two sides that MUST collide: boot-time pins are built bare (Key{Image, Runtime}), while create-path keys are computed after NormalizeCreateImageDistribution filled the metadata. Without this, pinned slots sit under a keystring no create ever computes — permanently unreachable and, being pinned, never idle-reaped.
type Metrics ¶
type Metrics struct {
// contains filtered or unexported fields
}
Metrics exposes pool counters for tests and expvar export.
func (*Metrics) RecordAdoptMS ¶
RecordAdoptMS publishes the latest successful adopt handshake duration. Exported because the adopt happens in pkg/docker, not in this package.
func (*Metrics) RecordSpawnFail ¶
func (m *Metrics) RecordSpawnFail()
type ParkShape ¶
type ParkShape struct {
CPU float64
MemoryMB int
DiskGB int
GPUs int
GPUVendor string
Runtime string
}
ParkShape is the resource reservation shape for one parked slot.
type ParkedSlot ¶
type ParkedSlot struct {
ID string
ContainerID string
ContainerIP string
ImageID string
Key Key
BootstrapToken string
Handle SpawnerHandle
}
ParkedSlot is the in-memory handle for one warm container.
type Pool ¶
type Pool struct {
// contains filtered or unexported fields
}
Pool keeps pre-started Docker containers keyed by image identity + runtime.
func (*Pool) Acquire ¶
Acquire removes one warm slot for key. imageID is re-validated at hand-out. Dead and stale-image slots found along the way are pruned and destroyed — container, netrules, AND park reservation — otherwise their DROP rules and admitter reservations outlive the container object. All queue surgery happens under one continuous lock hold; releasing p.mu mid-scan let a concurrent RecordLoaded slot be clobbered by a stale slice write-back.
func (*Pool) ClearSpawnFailures ¶
ClearSpawnFailures resets the consecutive-failure count after a successful park, so the eviction threshold only ever measures an unbroken run.
func (*Pool) HasReady ¶
HasReady reports whether any slot is queued for key. It exists so the create path can skip the image-inspect engine call on a guaranteed miss — keeping the miss path free of added boot-path work.
func (*Pool) ListTargets ¶
ListTargets returns keys eligible for refill.
func (*Pool) MarkSpawning ¶
MarkSpawning increments in-flight spawn counter for key string.
func (*Pool) NoteMiss ¶
NoteMiss registers a miss without scanning the queue: the target is noted for self-warming, the miss is counted, and refill is kicked — the same side effects an empty-queue Acquire would have had.
func (*Pool) NoteSpawnFailure ¶
NoteSpawnFailure counts a failed park for key and evicts the target once the consecutive-failure threshold is crossed. Returns true when the target was evicted. Slot destruction happens outside the lock (same rationale as Acquire/NoteTarget).
func (*Pool) NoteTarget ¶
NoteTarget registers a miss-driven refill target with LRU bounds.
func (*Pool) ReapIdle ¶
ReapIdle drops non-pinned targets with no recent use past idleTTL. Map surgery happens under one lock hold; slot destruction after unlock (same rationale as Acquire/NoteTarget).
func (*Pool) RecordLoaded ¶
func (p *Pool) RecordLoaded(slot *ParkedSlot)
RecordLoaded pushes a freshly parked slot into the ready queue.
func (*Pool) ReleasePark ¶
ReleasePark frees the capacity reservation of a slot that already left the pool via Acquire but was discarded by the caller (e.g. adopt failure). Every parked slot holds a park:<slot-id> admitter reservation; any path that destroys the container without releasing it leaks capacity until the node stops admitting creates.
func (*Pool) ReturnSlot ¶
func (p *Pool) ReturnSlot(slot *ParkedSlot)
ReturnSlot puts an acquired-but-untouched slot back into the ready queue (duplicate-create rename conflict: the parked container was never adopted). Unlike RecordLoaded it does not decrement the in-flight spawn counter — no spawn completed here, and skewing that counter makes SpawnBudget park past depth, each excess slot pinning a park reservation.
func (*Pool) Run ¶
func (p *Pool) Run(ctx context.Context, cfg RefillConfig, spawner Spawner, gate RefillGate)
Run starts the refill loop until ctx is cancelled.
func (*Pool) SetDefaultDepth ¶
func (*Pool) SetIdleTTL ¶
func (*Pool) SetMaxImages ¶
func (*Pool) SetParkReleaser ¶
func (*Pool) SetSpawner ¶
func (*Pool) SpawnBudget ¶
SpawnBudget returns how many slots refill should create for key on this tick.
func (*Pool) UnmarkSpawning ¶
UnmarkSpawning decrements in-flight spawn counter after failed warm.
type RefillConfig ¶
type RefillConfig struct {
RefillInterval time.Duration
SpawnTimeout time.Duration
IdleTTL time.Duration
ParkShape ParkShape
}
RefillConfig holds timing knobs for the background refill loop.
type RefillGate ¶
type RefillGate interface {
CanPark(shape ParkShape) bool
ParkReservation(slotID string, shape ParkShape) error
ReleasePark(slotID string)
}
RefillGate decides whether a new park is allowed and tracks reservations.
type Snapshot ¶
type Snapshot struct {
Hits int64
Misses int64
Refilled int64
Orphans int64
StaleImages int64
SpawnFail int64
TargetEvicts int64
}
Snapshot is a point-in-time view of pool counters.