Add Job Queue reliability and scheduling guidance (#148)
Some checks are pending
Validate knowledge index / validate-index (push) Waiting to run
Validate AL review fixtures / validate-review-fixtures (push) Waiting to run
Validate frontmatter and structure / validate (push) Waiting to run

* knowledge(performance): add job queue reliability guidance

* Address Job Queue review feedback

* Address Job Queue routing review feedback

* Encode job queue conflict in fixtures
This commit is contained in:
Stefano Demiliani 2026-09-14 12:44:30 +02:00 • committed by GitHub
parent 45ac371e7a
commit 8c26ba4e76
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 574 additions and 25 deletions

View file

@ -17,7 +17,7 @@ The first database write opens an AL write transaction that the runtime holds un
## Best Practice
Defer the HTTP call to a separate session. When the external operation must correspond to a committed database change, insert an outbox work item in the same transaction as that change and process committed outbox rows with a recurring job queue entry. The change and work item then commit or roll back together, and the worker performs HTTP before deleting the item so it holds no write lock during the call. Make the external operation idempotent because a failure after a successful HTTP response can cause the work item to be retried.
Defer the HTTP call to a separate session. When the external operation must correspond to a committed database change, insert an outbox work item in the same transaction as that change and process committed outbox rows with a recurring job queue entry. The change and work item then commit or roll back together, and the worker performs HTTP before deleting the item so it holds no write lock during the call. The separate retry-safety requirement is covered by `job-queue-external-effects-must-be-idempotent.md`.
A directly created scheduled task is suitable only when its work is independent of the caller's commit. An immediately ready task can run concurrently with the caller, so it must not assume that the caller's writes are already committed. Do **not** use `Commit()` as a general remedy: it irrevocably commits all prior writes in the current transaction, so any subsequent failure cannot roll them back. `Commit()` is appropriate only at top-level entry points where partial persistence is intentional and understood.