Documentation
¶
Overview ¶
Package-level error helpers for runner. These classify ECS RunTask errors into "transient capacity" (worth backing off and retrying) vs everything else (config, IAM, quota -- surface unchanged).
Package runner provides ECS task management for GitHub Actions runners. It defines a TaskRunner interface for testability and an ECS implementation that creates, stops, and lists runner tasks.
Index ¶
- Variables
- type ECSClient
- type ECSRunner
- type Reaper
- type RunTaskInput
- type ScaleSetClient
- type State
- func (s *State) AddIdle(name, taskARN string)
- func (s *State) Count() int
- func (s *State) IdleCount() int
- func (s *State) IsDeregistered(name string) bool
- func (s *State) MarkBusy(name string)
- func (s *State) MarkDeregistered(name string)
- func (s *State) MarkDone(name string) string
- func (s *State) Snapshot() map[string]string
Constants ¶
This section is empty.
Variables ¶
var ErrTransientCapacity = errors.New("ecs: transient capacity unavailable")
ErrTransientCapacity wraps RunTask failures attributed to ECS capacity exhaustion or upstream throttling. Callers detect it with errors.Is and engage a backoff before the next attempt.
Functions ¶
This section is empty.
Types ¶
type ECSClient ¶
type ECSClient interface {
RunTask(ctx context.Context, input *ecs.RunTaskInput, opts ...func(*ecs.Options)) (*ecs.RunTaskOutput, error)
StopTask(ctx context.Context, input *ecs.StopTaskInput, opts ...func(*ecs.Options)) (*ecs.StopTaskOutput, error)
ListTasks(ctx context.Context, input *ecs.ListTasksInput, opts ...func(*ecs.Options)) (*ecs.ListTasksOutput, error)
DescribeTasks(ctx context.Context, input *ecs.DescribeTasksInput, opts ...func(*ecs.Options)) (*ecs.DescribeTasksOutput, error)
}
ECSClient is the subset of the ECS API that the runner package needs.
type ECSRunner ¶
type ECSRunner struct {
// contains filtered or unexported fields
}
ECSRunner manages ECS tasks for GitHub Actions runners.
func NewECSRunner ¶
NewECSRunner creates a new ECSRunner.
type Reaper ¶
type Reaper struct {
// contains filtered or unexported fields
}
Reaper periodically checks for stale runner tasks and stops them. It handles two cases:
- Tasks stuck in PENDING state beyond the pending timeout
- Tasks running longer than the configured max runtime
func NewReaper ¶
func NewReaper( client ECSClient, ssClient ScaleSetClient, cluster, scaleSetName string, maxRuntime, pendingTimeout time.Duration, state *State, logger *slog.Logger, ) *Reaper
NewReaper creates a new Reaper.
func (*Reaper) Run ¶
Run starts the reaper loop, sweeping on the given interval until the context is cancelled.
func (*Reaper) Sweep ¶
Sweep checks all tasks for this scale set and stops stale ones. Returns the number of tasks stopped.
Sweep also reconciles in-memory runner state against ECS: any tracked runner whose ECS task no longer appears in the cluster is dropped from state. The state snapshot is captured before ListTasks to avoid racing with scaler.startRunner; runners added concurrently are simply deferred to the next sweep.
type RunTaskInput ¶
type RunTaskInput struct {
TaskDefinition string
JITConfigEncoded string
RunnerName string
ScaleSetName string
Subnets []string
SecurityGroups []string
CapacityProvider string
LaunchType ecsTypes.LaunchType
}
RunTaskInput holds the parameters for creating a new runner ECS task.
type ScaleSetClient ¶ added in v1.0.7
type ScaleSetClient interface {
GetRunnerByName(ctx context.Context, name string) (*scaleset.RunnerReference, error)
RemoveRunner(ctx context.Context, runnerID int64) error
}
ScaleSetClient is the subset of the scaleset API the Reaper uses to deregister GitHub runner registrations when the ECS task they back has stopped. It is a local copy of the interface shape used by internal/scaler, duplicated to avoid an import cycle.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State tracks runner tasks and their lifecycle (idle -> busy -> done). It is safe for concurrent use.
func (*State) IsDeregistered ¶ added in v1.0.7
IsDeregistered reports whether name was recently marked deregistered. It prunes expired entries as a side effect.
func (*State) MarkDeregistered ¶ added in v1.0.7
MarkDeregistered records that name has been successfully deregistered on the GitHub side. Subsequent IsDeregistered calls return true until the entry expires after deregisteredTTL.