GH-7925: Make message history header as mutable

Fixes: #7925

The `MessageHistory.write()` creates not only a new instance of the `MessageHistory`,
but also a new copy of the whole message.
This significantly impacts the performance when we have too many components to track

* Make `MessageHistory` as append-only container and create a new instance (plus message)
only on the first track when no prior history is present
* Change `WireTap`, `BroadcastingDispatcher`, `AbstractMessageRouter` and `AbstractMessageSplitter`
to use a new `AbstractIntegrationMessageBuilder.cloneMessageHistoryIfAny()` API for every branch a message
is produced.
Essentially, create a new message with copy of the message history to let that downstream sub-flow
have its own trace
* Modify failed unit tests for a new logic where message history header is not immutable anymore
* This also fixes an `AbstractMessageSplitter` for propagating its track into messages it emits

* * Do not clone message history header if only one consume in multi-publish
* Fix typos in docs
This commit is contained in:
Artem Bilan
2024-03-05 15:05:34 -05:00
committed by GitHub
parent 3fbe917e6c
commit 2731e9411e
12 changed files with 214 additions and 134 deletions

View File

@@ -129,7 +129,9 @@ The MBean's object name is `<domain>:name=messageHistoryConfigurer,type=MessageH
IMPORTANT: Only one `@EnableMessageHistory` (or `<message-history/>`) must be declared in the application context as single source for components tracking configuration.
Do not use a generic bean definition for the `MessageHistoryConfigurer`.
NOTE: By definition, the message history header is immutable (you cannot re-write history).
Therefore, when writing message history values, the components either create new messages (when the component is an origin) or they copy the history from a request message, modifying it and setting the new list on a reply message.
In either case, the values can be appended even if the message itself is crossing thread boundaries.
That means that the history values can greatly simplify debugging in an asynchronous message flow.
NOTE: Prior to version 6.3, the message history header was immutable (you cannot re-write history): every single track created not only new instance of the `MessageHistory`, but a fully new message copy.
Now it works in append-only mode: the first track creates a new message with a new `MessageHistory` container.
All the rest `MessageHistory.write()` calls add new entries to existing header - and no new message created.
This significantly improves the application performance.
All the components in the framework, where same message can be sent to several consumers (`PublishSubscribeChannel`, `AbstractMessageRouter`, `WireTap` etc.), or splitter produces several outputs based on the input message, are now cloning an existing `MessageHistory` header into those new messages.
For any other multi-producing use-cases, outside the framework scope, the `AbstractIntegrationMessageBuilder.cloneMessageHistoryIfAny()` API is recommended to ensure that parallel downstream sub-flows contribute their own message history traces.

View File

@@ -19,6 +19,10 @@ In general the project has been moved to the latest dependency versions.
[[x6.3-general]]
=== General Changes
The `MessageHistory` header is now mutable, append-only container.
And all the subsequent tracks don't create new message - only their entry is added to existing message history header.
See xref:message-history.adoc[Message History Chapter] for more information.
[[x6.3-security-changes]]
=== Security Support Changes