INT-3736: Process Barrier Component

JIRA: https://jira.spring.io/browse/INT-3736

INT-3736: Polishing

INT-3736: Use o-c-a For Release

Avoids unusual parser logic, allows release channel to be of any type.

INT-3736: Schema Polishing

INT-3736: Polishing

- Add TriggerMessageHandler interface
- Use SyncQueue - suspend the trigger thread if the main thread hasn't arrived yet
 - allows clean up of state regardless of whether just a trigger or suspend is processed
- reply-required

INT-3736: Polishing and Docs

Polishing code style and fixing typos in docs
This commit is contained in:
Gary Russell
2015-06-10 13:11:55 -04:00
committed by Artem Bilan
parent 4266bb53b4
commit c695129bd5
13 changed files with 970 additions and 55 deletions

View File

@@ -0,0 +1,87 @@
[[barrier]]
=== Thread Barrier
Sometimes, we need to suspend a message flow thread until some other asynchronous event occurs.
For example, consider an HTTP request that publishes a message to RabbitMQ.
We might wish to not reply to the user until the RabbitMQ broker has issued an acknowledgment that the message was
received.
Since _version 4.2_ Spring Integration introduced the `<barrier/>` component for this purpose.
The underlying `MessageHandler` is the `BarrierMessageHandler`; this class also implements
`MessageTriggerAction` where a message passed to the `trigger()` method releases a corresponding thread in the
`handleRequestMessage()` method (if present).
The suspended thread and trigger thread are correlated by invoking a `CorrelationStrategy` on the messages.
When a message is sent to the `input-channel`, the thread is suspended for up to `timeout` milliseconds, waiting for
a corresponding trigger message.
The default correlation strategy uses the `IntegrationMessageHeaderAccessor.CORRELATION_ID` header.
When a trigger message arrives with the same correlation, the thread is released.
The message sent to the `output-channel` after release is constructed using a `MessageGroupProcessor`.
By default, the message is a `Collection<?>` of the two payloads and the headers are merged, using a
`DefaultAggregatingMessageGroupProcessor`.
CAUTION: If the `trigger()` method is invoked first (or after the main thread times out), it will be suspended
for up to `timeout` waiting for the suspending message to arrive.
If you do not want to suspend the trigger thread, consider handing off to a `TaskExecutor` instead so its thread
will be suspended instead.
The `requires-reply` property determines the action if the suspended thread times out before the trigger message
arrives.
By default, it is `false` which means the endpoint simply returns `null`, the flow ends and the thread returns to the
caller.
When `true`, a `ReplyRequiredException` is thrown.
You can call the `trigger()` method programmatically (obtain the bean reference using the name `barrier.handler`
- where _barrier_ is the bean name of the barrier endpoint) or you can configure
an `<outbound-channel-adapter/>` to trigger the release.
IMPORTANT: Only one thread can be suspended with the same correlation; the same correlation can be used multiple times
but only once concurrently.
[source, xml]
----
<int:barrier id="barrier1" input-channel="in" output-channel="out"
correlation-strategy-expression="headers['myHeader']"
output-processor="myOutputProcessor"
timeout="10000">
</int:barrier>
<int:outbound-channel-adapter channel="release" ref="barrier1.handler" method="trigger" />
----
In this example, a custom header is used for correlation.
Either the thread sending a message to `in` or the one sending a message to `release` will wait for
up to 10 seconds until the other arrives.
When the message is released, the `out` channel will be sent a message combining the result of invoking the
custom `MessageGroupProcessor` bean `myOutputProcessor`.
Java configuration is shown below.
[source, java]
----
@Configuration
@EnableIntegration
public class Config {
@ServiceActivator(inputChannel="in")
@Bean
public BarrierMessageHandler barrier() {
BarrierMessageHandler barrier = new BarrierMessageHandler(10000);
barrier.setOutputChannel(out());
return barrier;
}
@ServiceActivator (inputChannel="release")
@Bean
public MessageHandler releaser() {
return new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
barrier().trigger(message);
}
};
}
}
----

View File

@@ -15,4 +15,6 @@ include::./resequencer.adoc[]
include::./chain.adoc[]
include::./scatter-gather.adoc[]
include::./barrier.adoc[]
// BE SURE TO PRECEDE ALL include:: with a blank line - see https://github.com/asciidoctor/asciidoctor/issues/1297

View File

@@ -54,6 +54,14 @@ Zookeeper support has been added to the framework to assist when running on a cl
See <<zookeeper>> for more information.
[[x4.2-barrier]]
==== Thread Barrier
A new thread `<int:barrier/>` component is available allowing a thread to be suspended until some asynchronous event
occurs.
See <<barrier>> for more information.
[[x4.2-general]]
=== General Changes