You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9d8e156
Browse filesBrowse the repository at this point in the historyBrowse files
Track SQL commitment before retry and failure handling so Rails callback
errors cannot relabel a completed turn or mask its original exception.
Carry the committed phase through coordination handlers and restore the
original error at synchronous caller and worker boundaries.
Cover real transaction callbacks, rollback, domain rejection, busy and
deadline failures, waiting callers, and subsequent execution with strict
red/green and implementation-reversal evidence. Document the error
boundary and bump the version and generated lockfile to 0.14.6.
Copy file name to clipboardExpand all lines: docs/architecture.md
+29-2Lines changed: 29 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -314,9 +314,30 @@ Any lease or message predicate failure raises `LostActivation` and rolls back ev
314
314
315
315
The state version can advance because of state migration even when the message itself makes no state change.
316
316
317
+
Active Record may raise from an application `after_commit` callback while the
318
+
transaction call unwinds, after SQL has committed. The adapter retains the
319
+
actual transaction object and checks its fully committed state before any
320
+
deadline conversion or SQLite retry. Reaching the end of the block, releasing
321
+
a savepoint, or observing an in-memory message update is not proof of SQL
322
+
commitment. A failing `before_commit` callback follows the rollback path.
323
+
324
+
An internal `CommittedTransactionError` carries the original error through
325
+
executor, SQLite retry, and coordination rescue handlers. The synchronous
326
+
invocation and worker boundaries re-raise the original exception with its
327
+
original backtrace and cause. The wrapper prevents a callback's `Rejected`,
328
+
`LostActivation`, or database error from being mistaken for a pre-commit
329
+
outcome. It is not a durable message error or a new delivery mechanism.
330
+
331
+
After commitment, actor state, application writes, message completion/result,
332
+
and outboxes remain durable. The executor preserves the committed activation
333
+
state and does not retry, reject, or dead-letter that turn. Caller assistance
334
+
still deactivates and releases its lease during cleanup; cached worker state
335
+
can process later messages. A worker running its continuous loop exposes the
336
+
error and runs its existing shutdown cleanup.
337
+
317
338
## Failure path
318
339
319
-
Actor exceptions roll back all in-memory changes by restoring the pre-turn state. A separate short transaction conditionally owned by the current generation:
340
+
Before commitment, actor and commit-action exceptions roll back all in-memory changes by restoring the pre-turn state. A separate short transaction conditionally owned by the current generation:
320
341
321
342
- Stores a sanitized error
322
343
- Deletes claimed membership
@@ -403,9 +424,15 @@ outer commit, and callers timing out on work they indirectly block.
403
424
waiting and immediately returns a `MessageReference`. Runtime workers process
404
425
it normally.
405
426
427
+
An executing caller receives an inline after-commit callback error even though
428
+
the turn committed. An independently waiting caller observes the durable
429
+
result and may return before that callback raises in the worker. Completed
430
+
history is not changed retroactively; callback failures must be observed in
431
+
the executing process. Later Rails callbacks may not run after one raises.
432
+
406
433
## Domain rejection
407
434
408
-
Actor code can call `reject` for a validation or business-rule outcome that
435
+
Before commitment, actor code can call `reject` for a validation or business-rule outcome that
409
436
must not retry. The executor restores pre-turn state, discards staged intents,
410
437
stores the structured rejection, completes the claimed membership, and
411
438
continues with the next sequence in one fenced transaction. Synchronous callers
0 commit comments