3.8 KiB
3.8 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| mem-engine-scheduler-outbox | Mem engine — scheduler (`schedule`/`unschedule`/`run_schedules`) and outbox helper | pending |
|
moderate | medium | component | implementation |
|
Description
The collapsed scheduler and the outbox helper (ADR-009, ADR-014):
- Scheduler surface:
schedule(name, spec, queue, payload, opts)(upsert by name; both name-bearing arguments validated — schedule name and queue argument identically,InvalidName/ReservedName),unschedule(name) -> bool, and the opt-inrun_schedules(stop: StopToken)runner over a mem-owned tick task. - Tick machinery — engine-uniform (ADR-009
§4's rule; single-instance leadership is trivially owned but the
machinery still runs): each boundary fire enqueues ordinary work
stamped with the schedule's
ScheduleOptsresolved over the target queue's derived engine defaults; fire+advance is atomic under the guarded state (the no-double-fire floor); bounded catch-up with the fixed 64-boundary cap and skip-forward past the cap (mem-owned tick implementation — third owner per ADR-012 §2); leadership rides the reserved__alkstore_schedulerlock through the lock mechanism (so two runners on one instance contend through the same machinery the other engines use; loss →Err(LeadershipLost), clean stop →Ok(())). - Spec grammar v1:
@every <n><unit>(s|m|h|d) only — mem owns its parser (third copy, the grammar is small and pinned); cron strings rejected (InvalidSpec). Boundary waits ride tokio time. - Outbox helper:
Outbox { enqueue, run_once }per ADR-019 §5 —run_once(worker_id, delivery) -> boolis pull: claim one, ack onOk,retry(err, None)onErr; no engine-issued heartbeat inside delivery (inherited posture);outbox_enqueue_txstaged in the overlay bymem-engine-seam-tx(the 60/5/5 stamp set); the derived backing queue__alkstore_outbox:{outbox}unreachable byenqueue_tx(validation already pins the reserved prefix), name format pinned identical to the other engines (the suite's derived-queue-naming row composes it).
Unit tests pin: boundary fires (deterministic, tokio-time driven),
bounded catch-up + skip-forward, leadership lock contention/loss
through two run_schedules calls, outbox run_once ack/retry shapes,
derived-name format.
Acceptance Criteria
- Scheduler surface + tick: boundary fire, catch-up (≤64), skip-forward — unit-pinned with tokio-time determinism
- Leadership contention through the
__alkstore_schedulerlock;LeadershipLoston loss,Ok(())on clean stop — pinned - Schedule name + queue argument validation;
@every-only parser (cron →InvalidSpec) — pinned - Outbox:
enqueue/run_oncesemantics (no engine heartbeat); derived backing-queue name format identical to both engines — pinned cargo check --target wasm32-unknown-unknown -p alkstore-memclean; workspace gates green
References
- docs/architecture/queues.md; core-contract.md §scheduler, §outbox
- docs/architecture/decisions/009-scheduler-collapse.md §1/§3/§4/§6; 014-outbox-tx-enqueue.md; 019 §4/§5; 020 §3
- docs/architecture/engine-mem.md §Mapping the contract (scheduler/outbox row)
- tasks/pg-engine-scheduler-outbox.md (the structural twin's task of record — tick/catch-up/leadership shapes)
Notes
To be filled by implementation agent
Summary
To be filled on completion