Skip to content
Proud to collaborate with Microsoft for Startups

runner.pool-reconcile-ec2-vm ​

Controller reconcile loop for warm-pool runner groups on EC2. Observes GitHub (via LTIP) + AWS EC2 + the engine DB every tick and converges the pool toward min_warm_idle / max_count. Replaces the event-driven scale-check + manual pool-sweep model. Idempotent; safe to run on a stable workflow_id per group.

Per-group warm-pool reconcile loop for raw EC2 VMs (controller).

Inputs:

  • runner_group_uuid — the group to reconcile.
  • queued_demand_hint — optional inline webhook demand breadcrumb.

Outputs (carried in state_data across the state machine):

  • observation — snapshot of GH runners + EC2 instances + DB rows.
  • transitions — per-instance state changes computed from it.
  • action_taken — at most one of launch / terminate / drain / defer / noop chosen this tick.
  • composition — final pool composition counts.
  • observation_lag_ms — wall clock from observe start to snapshot.
  • degraded — true if an essential observation source failed (GH throttled, EC2 transient error). Reconcile skips destructive transitions in degraded mode and waits for the next tick.

Overview ​

PropertyValue
Workflow typeLinear
LibraryApp-runners-aws
Version1.0

Input Schema ​

FieldTypeRequiredDefaultDescription
runner_group_uuiduuidYes—UUID of the RunnerGroup this reconcile tick operates on, picked from the organization's list of runner groups.
queued_demand_hintjsonNo—Inline webhook demand hint from runner.dispatch-from-job-queued; used as a fallback when queued-job observation misses demand.

Output Schema ​

FieldTypeRequiredDefaultDescription
runner_group_uuiduuidNo—UUID of the RunnerGroup this reconcile tick operated on, echoed from input.
started_atstringNo——
completed_atstringNo——
warm_pool_enabledbooleanNo——
queued_demand_hintjsonNo——
observationjsonNo——
degradedbooleanNo——
observation_errorslistNo——
queued_hint_countintegerNo——
effective_queued_countintegerNo——
transitionslistNo——
stale_github_runners_deletedintegerNo——
stale_github_runners_cleanup_errorslistNo——
action_takenstringNo——
queued_hint_consumed_countintegerNo——
quota_cooldown_untilstringNo——
quota_failure_codestringNo——
quota_failure_execution_uuiduuidNo——
launched_workflow_uuidstringNo—Engine run id of the runner.execution-launch-ec2-vm workflow started by this tick, when a launch was performed. Internal engine correlation id, not a business-entity foreign key — no list/query workflow backs it.
terminated_instance_uuiduuidNo—UUID of the RunnerInstance terminated or drained during this reconcile tick, when one was taken.
desired_aliveintegerNo——
compositionjsonNo——
observation_lag_msintegerNo——
failure_reasonstringNo——
failed_atstringNo——
step_errorslistNo——
errorstringNo——
error_typestringNo——
failed_at_statestringNo——
failed_layerstringNo——
failed_stepstringNo——

States ​

StateInitialTerminalSuccessAuto-advanceDescription
pendingYesNo—observe—
emitting_snapshotNoNo—complete—
enforcing_floor_capNoNo—emit_snapshot—
observingNoNo—diff_and_transition—
transitioningNoNo—enforce_floor_cap—
completedNoYesYes——
failedNoYesNo——

State Diagram ​

Transitions ​

FromActionToDescription
pendingobserveobserving—
observingdiff_and_transitiontransitioning—
transitioningenforce_floor_capenforcing_floor_cap—
enforcing_floor_capemit_snapshotemitting_snapshot—
emitting_snapshotcompletecompleted—
* (any state)failfailed—

API Usage ​

bash
POST /api/workflows/start
Content-Type: application/json

{
  "workflow_type": "runner.pool-reconcile-ec2-vm",
  "initial_data": {
    "runner_group_uuid": "value"
  }
}