Repository navigation
(feat) deliver domain notifications only after a transaction commits - #366
Merged
Merged
Conversation
Member
|
@techmahedy I'll do it soon |
Member
Author
take your time |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Checklist
Problem - Solution of this issue
Reacting to a change from inside a database transaction can announce work that is later rolled back: a receipt for a payment that never happened, an index refresh for a row that no longer exists. The framework had no dispatcher at all (
#[Hook]is model lifecycle only and fires immediately), so applications had to hand-roll this aroundDB::transaction().What this adds
A minimal, synchronous signal bus whose signals can wait for the surrounding transaction to settle, meaning the outermost transaction committed.
Signalfacade,signal()helper,'signal'bindingon,forget,hasListeners,emit,emitNow,emitOnSettle,reportFailuresUsing#[DeliverOnSettle(connection: ...)]php pool make:signal {name} {--settle} {--connection=}src/SignalsThe naming is deliberately Doppar's own (signals, settle, emit) rather than the vocabulary of other frameworks.
How it works
All transaction state already lives in
Database, so the change is there and the bus stays small.Database::$pendingSignals).transaction($callback, $attempts)retries therefore drop the failed attempt's signals.disconnect()andcleanupAllConnections()clear pending signals along with the transaction counters.Listener failures (documented behaviour)
After a commit the data is permanent, so letting an exception escape would make a successful commit look failed and skip other pending signals. Reporting goes to
Signal::reportFailuresUsing(), else thelogservice, else a best-efforterror_log(). A throwing reporter or logger also falls back toerror_log()and can never break the commit. This mirrors the fallback used fordefer()cleanup failures.Listeners and ordering
[class, method],[object, method]or invokable class names (built through the container per delivery). Invalid listeners are rejected at registration.Out of scope
Tests
tests/Signals/(37 tests) covers: priorities, equal priorities, parent and interface listeners, listener forms and validation, immediate propagation, commit delivers once, rollback discards, nested commit and rollback at several depths, chronological order across levels, inner-failure-caught-by-outer, retries, two connections committing and rolling back independently, a signal bound to a connection with no transaction,emitOnSettle/emitNow, failing listener with a reporter, with no reporter and with a throwing reporter, listeners opening their own transaction, disconnect, and two buses.tests/Console/CommandBehaviorCoverageTest.phpgains four tests formake:signal: plain,--settle,--connectionimplying settle, refusing to overwrite, and rejecting unsafe connection names (the value is written into generated source). Each generated file is linted withphp -l.Docs
Documented in the docs repo (4.x): new
signals.mdpage, facade table, helper entry, and a pointer from the transactions section ofentity-builder.md. docs linkChecklist