Help us shape the future of Go! Take the 2026 Go Developer Survey

gcpscale

package
v1.9.1 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package gcpscale holds the request-driven instance pool and injectable clock that Cloud Run style emulators share.

Index

Constants

View Source
const (
	// DefaultIdleTimeout is how long an idle instance above the minimum is kept; Cloud Run documents "up to 15 minutes".
	DefaultIdleTimeout = 15 * time.Minute
	// DefaultMaxInstances is Cloud Run's default instance cap.
	DefaultMaxInstances = 100
)

Variables

View Source
var ErrClosed = errors.New("instance pool is closed")

ErrClosed means the pool was shut down.

View Source
var ErrRetired = errors.New("instance was retired while starting")

ErrRetired means the instance was drained or removed before it finished starting.

View Source
var ErrSaturated = errors.New("no instance became available: the request timed out in the pending queue")

ErrSaturated means every instance slot stayed busy until the pending-queue timeout (HTTP 429 on Cloud Run).

Functions

This section is empty.

Types

type Clock

type Clock interface {
	Now() time.Time
	NewTimer(d time.Duration) Timer
	AfterFunc(d time.Duration, f func()) Timer
}

Clock abstracts time so idle scale-down and request queueing can be driven by tests.

type Config

type Config[T any] struct {
	Start       func(ctx context.Context) (T, error)
	Stop        func(T)
	Limits      func() Limits
	Idle        func() time.Duration
	Clock       Clock
	Base        context.Context //nolint:containedctx // lifetime of the instances, set by the worker
	IdleTimeout time.Duration
}

Config wires a Pool to the thing it scales. Start gets a context cancelled once its instance is retired (after Stop for a started one). Limits and Idle run under the pool lock and must not call back into the pool.

type Limits

type Limits struct {
	Min         int
	Max         int
	Concurrency int
}

Limits are the scaling settings read afresh on every decision. Zero Max means DefaultMaxInstances, zero Concurrency means 1.

type Pool

type Pool[T any] struct {
	// contains filtered or unexported fields
}

Pool keeps instances of one revision: requests take a concurrency slot, new instances start while below the maximum, and idle ones above the minimum are removed.

func New

func New[T any](name string, cfg Config[T]) *Pool[T]

New creates an empty pool.

func (*Pool[T]) Acquire

func (p *Pool[T]) Acquire(ctx context.Context) (T, func(), error)

Acquire reserves a request slot, starting an instance when all slots are taken and the pool is below its maximum, and queueing for max(10s, 3.5 x observed start time) otherwise (then ErrSaturated).

func (*Pool[T]) Close

func (p *Pool[T]) Close()

Close stops every instance and rejects further requests. Starts in flight are cancelled and stopped as they finish.

func (*Pool[T]) Drain

func (p *Pool[T]) Drain()

Drain retires every instance but keeps the pool open: later requests start fresh ones.

func (*Pool[T]) Ensure

func (p *Pool[T]) Ensure(ctx context.Context, n int) error

Ensure brings the pool to at least n instances (capped at the maximum) and waits until they are ready.

func (*Pool[T]) Live

func (p *Pool[T]) Live() int

Live returns the number of instances started or starting.

func (*Pool[T]) Remove

func (p *Pool[T]) Remove(match func(T) bool) bool

Remove retires and stops the started instances match selects (a failed liveness probe, say); the pool starts a replacement on demand. It reports whether any instance was removed.

type RealClock

type RealClock struct{}

RealClock is the wall clock.

func (RealClock) AfterFunc

func (RealClock) AfterFunc(d time.Duration, f func()) Timer

AfterFunc runs f after d on the wall clock.

func (RealClock) NewTimer

func (RealClock) NewTimer(d time.Duration) Timer

NewTimer starts a wall-clock timer.

func (RealClock) Now

func (RealClock) Now() time.Time

Now returns the wall time.

type Timer

type Timer interface {
	C() <-chan time.Time
	Stop() bool
}

Timer is the slice of *time.Timer that scaling uses.

Jump to

Keyboard shortcuts

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