feat(bpm): defer the -transitioned publish to the end of the BPMN execution chain#6234
Merged
Conversation
…cution chain The intent setter delegates (setField/setRelationField) published the -transitioned topic inline, while service tasks that FOLLOW the setter in the same synchronous Flowable chain (a number-generation delegate) ran milliseconds later - an asynchronous consumer that re-loads the source on receive (the postings glue) raced them and could observe the pre-chain state (an auto-posted journal entry catching the create-time UUID placeholder as its documentNumber). New Process.executeAfterCommit(Runnable) (SDK) / BpmFacade .executeAfterCommit - a Flowable COMMITTED transaction listener; runs immediately outside a BPMN command. SetField.java.template publishes -transitioned through it, so by the time any consumer reacts, the whole chain's writes are committed and a re-load observes them. Verified live: issue -> generateNumber -> markIssued chain; the auto-posted entry deterministically carries the real document number. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
The problem
The intent setter delegates (
setField/setRelationField) published the-transitionedtopic inline, at the moment the status was persisted. But service tasks that follow the setter in the same synchronous Flowable chain — e.g. a number-generation delegate after an Issue transition — run milliseconds later in the same command. An asynchronous consumer of-transitionedthat re-loads the source on receive (the postings glue, integrations) raced those steps: an auto-posted journal entry could catch the source's create-time UUID placeholder as itsdocumentNumberinstead of the real stamped number. Timing-dependent, unfixable by the consumer.The fix
Process.executeAfterCommit(Runnable)(SDK) /BpmFacade.executeAfterCommit— registers a FlowableCOMMITTEDtransaction listener via the current command'sTransactionContext, so the action runs after the whole synchronous BPMN execution chain (the current service task and everything up to the next wait state) has completed and committed. Outside a BPMN command it runs the action immediately.SetField.java.templatepublishes-transitionedthrough it. By the time any consumer reacts, every write the chain performed is committed — a consumer's re-load by id observes the completed document by construction, with no authoring-order requirement.(Modeling-side, the intent guide now also documents the complementary convention — order the steps a posting must read before the status set, so "the transition is final" also means "the document is complete".)
Verification
issue → generateNumber → markIssuedchain; the auto-posted journal entry deterministically carries the real document number (previously the UUID placeholder, timing-dependent).IntentEngineITsetter assertion updated: the generated delegate wraps the publish inProcess.executeAfterCommit(...).CLAUDE.md(-transitionedsemantics) +intent-assistant-guide.md(postings section).🤖 Generated with Claude Code