lifecycle

package
v0.0.1-alpha.28 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package lifecycle provides a shared, testable scheduler for async state transitions. EC2 instances, ECS tasks, and RDS instances all need delayed state changes (e.g. pending → running, creating → available). This package provides a single abstraction instead of each service hand-rolling time.AfterFunc/goroutine/cancel patterns.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ScopedKey

func ScopedKey(region, id, transition string) string

ScopedKey builds the region-scoped scheduler key AfterScoped and CancelScoped use. Exported for callers that need to inspect or test pending transitions.

Types

type Scheduler

type Scheduler struct {
	// contains filtered or unexported fields
}

Scheduler manages keyed delayed callbacks. Each service creates its own Scheduler instance (no global state, DI-friendly).

func NewScheduler

func NewScheduler(clk clock.Clock) *Scheduler

NewScheduler creates a Scheduler using the given clock. Production: clock.New(). Tests: clock.NewMock() for instant time skips.

func (*Scheduler) After

func (s *Scheduler) After(key string, delay time.Duration, fn func())

After schedules fn to run after delay. Key identifies the transition (e.g. "i-abc123:terminate"). If a transition with the same key is already pending, it is cancelled before the new one is scheduled.

When delay is 0 and the clock is a real clock (not a mock), fn is executed synchronously within this call. This ensures that subsequent API calls immediately see the updated state instead of racing with a goroutine. With a mock clock, 0-delay timers remain pending until clock.Add is called, preserving test-time control.

func (*Scheduler) AfterScoped

func (s *Scheduler) AfterScoped(region, id, transition string, delay time.Duration, fn func(ctx context.Context))

AfterScoped schedules fn to run after delay for a resource that lives in a region-keyed store. It exists because the plain After callbacks run outside any request context: a bare context.Background() resolves to the DEFAULT region, so for a resource created in any other region the callback reads or writes the wrong store key and silently no-ops (statuses stuck at "creating"/"stopping", deferred deletes that never land).

AfterScoped closes both halves of that bug at once:

  • fn receives a background context carrying region, so region-keyed store lookups inside the callback resolve the same record the request wrote;
  • the scheduler key is scoped by region, so same-named resources in different regions cannot cancel or replace each other's pending transitions.

Callers pass the region resolved from the request context at schedule time (e.g. store.region(ctx)).

func (*Scheduler) Cancel

func (s *Scheduler) Cancel(key string) bool

Cancel cancels a pending transition by key. Returns true if a pending transition was found and cancelled.

func (*Scheduler) CancelScoped

func (s *Scheduler) CancelScoped(region, id, transition string) bool

CancelScoped cancels a pending transition scheduled with AfterScoped.

func (*Scheduler) PendingCount

func (s *Scheduler) PendingCount() int

PendingCount returns the number of currently scheduled transitions.

func (*Scheduler) Stop

func (s *Scheduler) Stop(ctx context.Context)

Stop cancels all pending transitions and waits for any in-flight callbacks to complete. Respects ctx for timeout on the wait.

Jump to

Keyboard shortcuts

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