Problem
A failed background task can retain the worker semaphore permit indefinitely while recording its failure. On a single-shard topology Anvil currently forces background concurrency to one, so this stalls the entire queue and leaves later typed indexes enabled but unmaterialized.
Worka E2E34 evidence (2026-07-30)
Candidate source: a6b8f719f36190800dcdcceb0c06957270db84bf.
- Task 110 (
AuthzMaterialization) failed at 05:48:25 on an authz-head ValueHash predicate.
- No failure-recording result, task completion, or later index-build completion was logged.
- At 05:55:41 recovery found task 110 still running without a valid execution lease and requeued it.
- All bootstrap index builds had completed by 05:48:29, but none of 11 indexes created for a template workspace around 06:07 materialized.
workspace.integration_events_by_time was present, enabled, and version 1, but had no typed segment.
- Worka queried it with
lag_timeout_ms=5000; TypedJsonIndexNotMaterialised stopped the watcher every 15 seconds despite caller reconciliation.
The worker error branch awaits execution_lease_precondition and then fail_task_with_execution_guard inside the spawned task while holding its semaphore permit. Neither await has an outer deadline. Recovery can requeue the task record but cannot release a permit retained by the stuck spawned future.
Single-node serialization compounds the defect: effective_worker_concurrency returns 1 whenever fewer than two shard targets exist, even though durability topology should not serialize unrelated background task execution.
Acceptance criteria
- Failure and completion persistence have bounded deadlines and cannot retain a worker permit indefinitely.
- Cancellation leaves a recoverable queue/lease state; recovery can safely reclaim the exact attempt.
- A deliberately hung failure-finalization operation does not prevent an unrelated queued index build from starting.
- A failed authz materialization does not starve later index builds.
- Background concurrency is not reduced to one solely because local durability has one shard target; configured concurrency remains bounded and MVCC/task leases remain authoritative.
- Focused tests cover timeout, permit release, recovery, and single-node concurrency.
- Worka's newly created workspace indexes materialize before/within their query lag timeout under the E2E workload.
Problem
A failed background task can retain the worker semaphore permit indefinitely while recording its failure. On a single-shard topology Anvil currently forces background concurrency to one, so this stalls the entire queue and leaves later typed indexes enabled but unmaterialized.
Worka E2E34 evidence (2026-07-30)
Candidate source:
a6b8f719f36190800dcdcceb0c06957270db84bf.AuthzMaterialization) failed at 05:48:25 on anauthz-headValueHashpredicate.workspace.integration_events_by_timewas present, enabled, and version 1, but had no typed segment.lag_timeout_ms=5000;TypedJsonIndexNotMaterialisedstopped the watcher every 15 seconds despite caller reconciliation.The worker error branch awaits
execution_lease_preconditionand thenfail_task_with_execution_guardinside the spawned task while holding its semaphore permit. Neither await has an outer deadline. Recovery can requeue the task record but cannot release a permit retained by the stuck spawned future.Single-node serialization compounds the defect:
effective_worker_concurrencyreturns 1 whenever fewer than two shard targets exist, even though durability topology should not serialize unrelated background task execution.Acceptance criteria