Skip to main content

Module scheduler

Module scheduler 

Source
Expand description

Admission-pipeline for the Postgres backend (RFC-v0.7 Wave 5b).

Mirrors ff-scheduler::claim::Scheduler::claim_for_worker on Valkey: find an eligible execution, match capabilities, admit under budget, admit under quota, and issue a signed ClaimGrant. Returns Ok(None) when no candidate is admissible.

§Pipeline

All six pipeline stages run in one READ COMMITTED transaction (Q11):

  1. Eligible pick. SELECT ... FROM ff_exec_core WHERE lane_id = $1 AND lifecycle_phase = 'runnable' AND eligibility_state = 'eligible_now' ORDER BY priority DESC, created_at_ms ASC FOR UPDATE SKIP LOCKED LIMIT N. Over-fetches so capability-subset filtering has candidates after per-row rejects.
  2. Capability subset-match. Each over-fetched row is filtered via ff_core::caps::matches. First matching row wins.
  3. Budget admission. If the exec row carries budget_ids, each referenced [ff_budget_policy] row is FOR SHARE-locked, its policy_json parsed for hard_limit + dimension, and the current ff_budget_usage value compared. Breach → Ok(None), row left eligible for another worker/tick.
  4. Quota admission. There is no quota schema in 0001/0002. This stage is a no-op and reported as “skipped — quota schema not yet migrated” in the return channel. Grep of the migrations directory confirms: only budget + core + suspension + stream tables exist.
  5. Issue ClaimGrant. Uses the Wave-4d global [ff_waitpoint_hmac] keystore via hmac_sign — the same primitive signing waitpoint tokens. The signed blob rides inside ClaimGrant::grant_key as pg:<hash-tag>:<uuid>:<expires_ms>:<kid>:<hex>. The grant itself is stashed into ff_exec_core.raw_fields.claim_grant (no schema addition — Wave-4b already uses raw_fields as the untyped-column overflow; see progress).
  6. Commit + return grant.

§Isolation (Q11)

READ COMMITTED + FOR UPDATE SKIP LOCKED on the eligible pick + FOR SHARE on budget policy rows. No SERIALIZABLE retries.

§Scheduler integration

ff-scheduler today is Valkey-specific (ferriskey::Client embedded in Scheduler). Rather than add ff-backend-postgres (and its sqlx transitive graph) as a dep of ff-scheduler — which would pollute every consumer (ff-server, ff-observability, ff-test, ff-readiness-tests, ff-script, ff-backend-valkey) — the Postgres variant lives here as a free-standing PostgresScheduler struct. ff-server dispatches against the concrete backend type it constructed (Valkey → ff_scheduler::Scheduler, Postgres → ff_backend_postgres::scheduler::PostgresScheduler); no trait- object indirection needed because the engine already decides backend at boot.

Structs§

PostgresScheduler
Postgres admission pipeline. See the module rustdoc for pipeline + isolation notes.

Enums§

GrantVerifyError
Errors from verify_grant.

Functions§

verify_grant
Verify a grant produced by PostgresScheduler::claim_for_worker.