INT-2595: Add Time-Based ReleaseStrategy Option
JIRA: https://jira.spring.io/browse/INT-2595 * Add `group-timeout` and `group-timeout-expression` to the Correlation Endpoint * Add logic to the `AbstractCorrelatingMessageHandler` to schedule group for `forceComplete`, when the target `ReleaseStrategy` returns `false` INT-2595: Polishing according PR comments INT-2595: Expose `lock-registry` and further docs INT-2595 Doc and Test Polishing INT-2595: Fix typos INT-2595 More Minor Doc Polish
This commit is contained in:
committed by
Gary Russell
parent
882da62ba0
commit
eb0d1ddc84
@@ -368,7 +368,13 @@ then you should simply provide an implementation of the <classname>ReleaseStrate
|
||||
release-strategy-expression="size() == 5" ]]><co id="aggxml17" /><![CDATA[
|
||||
|
||||
expire-groups-upon-completion="false" ]]><co id="aggxml18" /><![CDATA[
|
||||
empty-group-min-timeout="60000" /> ]]><co id="aggxml19" /><![CDATA[
|
||||
empty-group-min-timeout="60000" ]]><co id="aggxml19" /><![CDATA[
|
||||
|
||||
lock-registry="lockRegistry" ]]><co id="aggxml191" /><![CDATA[
|
||||
|
||||
group-timeout="60000" ]]><co id="aggxml20" /><![CDATA[
|
||||
group-timeout-expression="size() ge 2 ? 100 : -1" ]]><co id="aggxml21" /><![CDATA[
|
||||
scheduler="taskScheduler" /> ]]><co id="aggxml22" /><![CDATA[
|
||||
|
||||
<int:channel id="outputChannel"/>
|
||||
|
||||
@@ -435,8 +441,7 @@ then you should simply provide an implementation of the <classname>ReleaseStrate
|
||||
or by simply invoking that method if you have a reference to the <classname>MessageGroupStore</classname> instance.
|
||||
Otherwise by itself this attribute has no behavior. It only serves as an indicator of what to do (discard or send to the output/reply
|
||||
channel) with Messages that are still in the <classname>MessageGroup</classname> that is about to be expired.
|
||||
<emphasis>Optional</emphasis>.</para>
|
||||
<para><emphasis>Default - 'false'</emphasis>.</para>
|
||||
<emphasis>Optional</emphasis>. <emphasis>Default - 'false'</emphasis>.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aggxml09">
|
||||
@@ -524,6 +529,61 @@ then you should simply provide an implementation of the <classname>ReleaseStrate
|
||||
property and it could be as much as this value plus the timeout.</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aggxml191">
|
||||
<para>
|
||||
A reference to a <interfacename>org.springframework.integration.util.LockRegistry</interfacename> bean;
|
||||
used to obtain a <interfacename>Lock</interfacename> based on the <code>groupId</code> for
|
||||
concurrent operations on the
|
||||
<code>MessageGroup</code>. By default, an internal <classname>DefaultLockRegistry</classname> is used.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="aggxml20">
|
||||
<para>
|
||||
A timeout in milliseconds to force the <code>MessageGroup</code> complete,
|
||||
when the <interfacename>ReleaseStrategy</interfacename> doesn't <emphasis>release</emphasis>
|
||||
the group when the current Message arrives.
|
||||
This attribute provides a built-in <emphasis>Time-base Release Strategy</emphasis> for the aggregator,
|
||||
when there is a need to emit a partial result (or discard the group), if a new Message does not arrive
|
||||
for the <code>MessageGroup</code> within the timeout.
|
||||
When a new Message arrives at the aggregator, any existing <interfacename>ScheduledFuture<?></interfacename>
|
||||
for its <code>MessageGroup</code> is canceled. If the
|
||||
<interfacename>ReleaseStrategy</interfacename>
|
||||
returns <code>false</code> (don't release) and the <code>groupTimeout > 0</code> a new task will be
|
||||
scheduled to expire the group.
|
||||
Setting this attribute to zero is not advised because it will effectively disable the aggregator because every
|
||||
message group will be immediately completed. It is possible, however to conditionally set it to zero using an
|
||||
expression; see <code>group-timeout-expression</code> for information.
|
||||
The action taken during the completion depends on the <interfacename>ReleaseStrategy</interfacename> and the
|
||||
<code>send-partial-group-on-expiry</code> attribute. See <xref linkend="agg-and-group-to"/> for
|
||||
more information.
|
||||
Mutually exclusive with 'group-timeout-expression' attribute.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="aggxml21">
|
||||
<para>
|
||||
The SpEL expression that evaluates to a <code>groupTimeout</code> with the <code>MessageGroup</code>
|
||||
as the <code>#root</code> evaluation context object. Used for scheduling the <code>MessageGroup</code> to
|
||||
be forced complete. If the expression evaluates to null or <code>< 0</code>, the
|
||||
completion is not scheduled. If it evaluates to zero, the group is completed immediately on
|
||||
the current thread. In effect, this provides a dynamic <code>group-timeout</code> property.
|
||||
See <code>group-timeout</code> for more information.
|
||||
Mutually exclusive with 'group-timeout' attribute.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="aggxml22">
|
||||
<para>
|
||||
A <interfacename>TaskScheduler</interfacename> bean reference to schedule
|
||||
the <code>MessageGroup</code> to be forced complete
|
||||
if no new message arrives for the <code>MessageGroup</code>
|
||||
within the <code>groupTimeout</code>.
|
||||
If not provided, the default scheduler <code>taskScheduler</code>,
|
||||
registered in the <interfacename>ApplicationContext</interfacename> (<classname>ThreadPoolTaskScheduler</classname>)
|
||||
will be used. This attribute does not apply if <code>group-timeout</code> or
|
||||
<code>group-timeout-expression</code> is not specified.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
</calloutlist>
|
||||
|
||||
<para>Using a <code>ref</code> attribute is generally recommended if a custom
|
||||
@@ -663,6 +723,45 @@ then you should simply provide an implementation of the <classname>ReleaseStrate
|
||||
<interfacename>MessageGroup</interfacename> itself, and you are simply stating
|
||||
that as soon as there are more than 5 messages in this group, it should be released.
|
||||
</para>
|
||||
|
||||
<section id="agg-and-group-to">
|
||||
<title>Aggregator and Group Timeout</title>
|
||||
|
||||
<para>
|
||||
Starting with <emphasis>version 4.0</emphasis>, two new mutually exclusive attributes have been introduced:
|
||||
<code>group-timeout</code> and <code>group-timeout-expression</code> (see the description above). There are some
|
||||
cases where it is needed to emit the aggregator result (or discard the group) after a timeout
|
||||
if the <interfacename>ReleaseStrategy</interfacename>
|
||||
doesn't <emphasis>release</emphasis> when the current Message arrives.
|
||||
For this purpose the <code>groupTimeout</code> option allows scheduling the <code>MessageGroup</code> to
|
||||
be forced complete:
|
||||
<programlisting language="xml"><![CDATA[<aggregator input-channel="input" output-channel="output"
|
||||
send-partial-result-on-expiry="true"
|
||||
group-timeout-expression="size() ge 2 ? 10000 : -1"
|
||||
release-strategy-expression="[0].headers.sequenceNumber == [0].headers.sequenceSize"/>]]></programlisting>
|
||||
With this example, the normal <emphasis>release</emphasis> will be possible if the aggregator receives the last message
|
||||
in sequence as defined by the <code>release-strategy-expression</code>. If that specific message does not arrive,
|
||||
the <code>groupTimeout</code> will force the group complete after 10 seconds as long as the group contains at least 2 Messages.
|
||||
</para>
|
||||
<para>
|
||||
The results of forcing the group complete depends on the <interfacename>ReleaseStrategy</interfacename> and
|
||||
the <code>send-partial-result-on-expiry</code>.
|
||||
First, the release strategy is again consulted to see if a <emphasis>normal</emphasis> release is to be made - while the
|
||||
group won't have changed, the <interfacename>ReleaseStrategy</interfacename> can decide to release the group at this time. If the
|
||||
release strategy still does not release the group, it will be expired.
|
||||
If <code>send-partial-result-on-expiry</code> is <code>true</code>,
|
||||
existing messages in the (partial) <code>MessageGroup</code> will be released as a normal aggregator reply Message to the
|
||||
<code>output-channel</code>, otherwise it will be discarded.
|
||||
</para>
|
||||
<para>
|
||||
There is a difference between <code>groupTimeout</code> behavior and <classname>MessageGroupStoreReaper</classname>
|
||||
(see <xref linkend="aggregator-config"/>). The reaper initiates forced completion for all <code>MessageGroup</code>s
|
||||
in the <code>MessageGroupStore</code> periodically. The <code>groupTimeout</code> does it for each <code>MessageGroup</code>
|
||||
individually, if a new Message doesn't arrive during the <code>groupTimeout</code>. Also, the reaper can be used to
|
||||
remove empty groups (empty groups are retained in order to discard late messages,
|
||||
if <code>expire-groups-upon-completion</code> is false).
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="aggregator-annotations">
|
||||
|
||||
@@ -52,8 +52,13 @@
|
||||
release-strategy="releaseStrategyBean" ]]><co id="resxml14-co" linkends="resxml14" /><![CDATA[
|
||||
release-strategy-method="release" ]]><co id="resxml15-co" linkends="resxml15" /><![CDATA[
|
||||
release-strategy-expression="size() == 10" ]]><co id="resxml16-co" linkends="resxml16" /><![CDATA[
|
||||
empty-group-min-timeout="60000" />]]><co id="resxml17-co" linkends="resxml17" /></programlisting>
|
||||
empty-group-min-timeout="60000" ]]><co id="resxml17-co" linkends="resxml17" /><![CDATA[
|
||||
|
||||
lock-registry="lockRegistry" ]]><co id="resxml18" /><![CDATA[
|
||||
|
||||
group-timeout="60000" ]]><co id="resxml19" /><![CDATA[
|
||||
group-timeout-expression="size() ge 2 ? 100 : -1" ]]><co id="resxml20" /><![CDATA[
|
||||
scheduler="taskScheduler" /> ]]><co id="resxml21" /></programlisting>
|
||||
<para><calloutlist>
|
||||
<callout arearefs="resxml1-co" id="resxml1">
|
||||
<para>The id of the resequencer is
|
||||
@@ -160,7 +165,27 @@
|
||||
empty group will also be affected by the reaper's <emphasis>timeout</emphasis>
|
||||
property and it could be as much as this value plus the timeout.</para>
|
||||
</callout>
|
||||
<callout arearefs="resxml18">
|
||||
<para>
|
||||
See <xref linkend="aggregator-xml"/>.
|
||||
</para>
|
||||
</callout>
|
||||
|
||||
<callout arearefs="resxml19">
|
||||
<para>
|
||||
See <xref linkend="aggregator-xml"/>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="resxml20">
|
||||
<para>
|
||||
See <xref linkend="aggregator-xml"/>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="resxml21">
|
||||
<para>
|
||||
See <xref linkend="aggregator-xml"/>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist></para>
|
||||
|
||||
<note>
|
||||
|
||||
@@ -209,5 +209,16 @@
|
||||
For more information see <xref linkend="retry-config"/>.
|
||||
</para>
|
||||
</section>
|
||||
<section id="4.0-release-strategy-group-timeout">
|
||||
<title>Correlation Endpoint: Time-based Release Strategy</title>
|
||||
<para>
|
||||
The mutually exclusive <code>group-timeout</code> and <code>group-timeout-expression</code>
|
||||
attributes have been added to the <code><int:aggregator></code> and <code><int:resequencer></code>.
|
||||
These attributes allow forced completion of a partial <code>MessageGroup</code>,
|
||||
if the <interfacename>ReleaseStrategy</interfacename> does not release a group and no
|
||||
further messages arrive within the time specified.
|
||||
For more information see <xref linkend="aggregator-config"/>.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
Reference in New Issue
Block a user