INT-2430 - Improve Polling Consumer Documentation
INT-2425 - Poller: Document the Ability to Change Polling Rate at Runtime For reference see: * https://jira.springsource.org/browse/INT-2430 * https://jira.springsource.org/browse/INT-2425 INT-2430 - Code Review - Minor spelling error fix in src/reference/docbook/endpoint.xml INT-2430 - Code Review - Doc updates * Add more documentation around the dynamic poller sample * Standardize Endpoint chapter so that for emphasis of properties the <emphasis/> docbook element is used rather than quotes. Polishing
This commit is contained in:
committed by
Gary Russell
parent
b45bc645e7
commit
dc1d1868d9
@@ -25,8 +25,8 @@
|
||||
Message Channel, some component has to schedule and manage the polling thread(s). Spring Integration provides
|
||||
two different endpoint implementations to accommodate these two types of consumers. Therefore, the consumers
|
||||
themselves can simply implement the callback interface. When polling is required, the endpoint acts as a
|
||||
"container" for the consumer instance. The benefit is similar to that of using a container for hosting
|
||||
Message Driven Beans, but since these consumers are simply Spring-managed Objects running within an
|
||||
<emphasis>container</emphasis> for the consumer instance. The benefit is similar to that of using a container for hosting
|
||||
Message Driven Beans, but since these consumers are simply Spring-managed Objects running within an
|
||||
ApplicationContext, it more closely resembles Spring's own MessageListener containers.
|
||||
</para>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
following chapters (Routers, Transformers, Splitters, Aggregators, Service Activators, etc). Those components
|
||||
each perform very different functionality with the Messages they handle, but the requirements for actually
|
||||
receiving a Message are the same, and the choice between polling and event-driven behavior is also the same.
|
||||
Spring Integration provides two endpoint implementations that "host" these callback-based handlers and allow
|
||||
Spring Integration provides two endpoint implementations that <emphasis>host</emphasis> these callback-based handlers and allow
|
||||
them to be connected to Message Channels.
|
||||
</para>
|
||||
</section>
|
||||
@@ -80,6 +80,12 @@ EventDrivenConsumer consumer = new EventDrivenConsumer(channel, exampleHandler);
|
||||
|
||||
PollingConsumer consumer = new PollingConsumer(channel, exampleHandler);</programlisting>
|
||||
</para>
|
||||
|
||||
<note>
|
||||
For more information regarding Polling Consumers, please also read
|
||||
<xref linkend="polling-consumer"/> as well as <xref linkend="channel-adapter"/>.
|
||||
</note>
|
||||
|
||||
<para>
|
||||
There are many other configuration options for the Polling Consumer. For example, the trigger is a required property:
|
||||
<programlisting language="java">
|
||||
@@ -89,7 +95,7 @@ consumer.setTrigger(new IntervalTrigger(30, TimeUnit.SECONDS));</programlisting>
|
||||
Spring Integration currently provides two implementations of the <interfacename>Trigger</interfacename>
|
||||
interface: <classname>IntervalTrigger</classname> and <classname>CronTrigger</classname>. The
|
||||
<classname>IntervalTrigger</classname> is typically defined with a simple interval (in milliseconds), but
|
||||
also supports an 'initialDelay' property and a boolean 'fixedRate' property (the default is false, i.e.
|
||||
also supports an <emphasis>initialDelay</emphasis> property and a boolean <emphasis>fixedRate</emphasis> property (the default is false, i.e.
|
||||
fixed delay):
|
||||
<programlisting language="java">IntervalTrigger trigger = new IntervalTrigger(1000);
|
||||
trigger.setInitialDelay(5000);
|
||||
@@ -107,15 +113,15 @@ consumer.setMaxMessagesPerPoll(10);
|
||||
consumer.setReceiveTimeout(5000);</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
The 'maxMessagesPerPoll' property specifies the maximum number of messages to receive within a given poll
|
||||
The <emphasis>maxMessagesPerPoll</emphasis> property specifies the maximum number of messages to receive within a given poll
|
||||
operation. This means that the poller will continue calling receive() <emphasis>without waiting</emphasis>
|
||||
until either <code>null</code> is returned or that max is reached. For example, if a poller has a 10 second
|
||||
interval trigger and a 'maxMessagesPerPoll' setting of 25, and it is polling a channel that has 100 messages
|
||||
interval trigger and a <emphasis>maxMessagesPerPoll</emphasis> setting of 25, and it is polling a channel that has 100 messages
|
||||
in its queue, all 100 messages can be retrieved within 40 seconds. It grabs 25, waits 10 seconds, grabs the
|
||||
next 25, and so on.
|
||||
</para>
|
||||
<para>
|
||||
The 'receiveTimeout' property specifies the amount of time the poller should wait if no messages are
|
||||
The <emphasis>receiveTimeout</emphasis> property specifies the amount of time the poller should wait if no messages are
|
||||
available when it invokes the receive operation. For example, consider two options that seem similar on
|
||||
the surface but are actually quite different: the first has an interval trigger of 5 seconds and a receive
|
||||
timeout of 50 milliseconds while the second has an interval trigger of 50 milliseconds and a receive timeout
|
||||
@@ -123,7 +129,7 @@ consumer.setReceiveTimeout(5000);</programlisting>
|
||||
(if that message arrived immediately after one of its poll calls returned). On the other hand, the second
|
||||
configuration will never miss a message by more than 50 milliseconds. The difference is that the second
|
||||
option requires a thread to wait, but as a result it is able to respond much more quickly to arriving messages.
|
||||
This technique, known as "long polling", can be used to emulate event-driven behavior on a polled source.
|
||||
This technique, known as <emphasis>long polling</emphasis>, can be used to emulate event-driven behavior on a polled source.
|
||||
</para>
|
||||
<para>
|
||||
A Polling Consumer may also delegate to a Spring <interfacename>TaskExecutor</interfacename>, and it can
|
||||
@@ -159,22 +165,209 @@ consumer.setTransactionManager(txManager);</programlisting>
|
||||
<title>Namespace Support</title>
|
||||
<para>
|
||||
Throughout the reference manual, you will see specific configuration examples for endpoint elements, such as
|
||||
router, transformer, service-activator, and so on. Most of these will support an "input-channel" attribute and
|
||||
many will support an "output-channel" attribute. After being parsed, these endpoint elements produce an instance
|
||||
router, transformer, service-activator, and so on. Most of these will support an <emphasis>input-channel</emphasis> attribute and
|
||||
many will support an <emphasis>output-channel</emphasis> attribute. After being parsed, these endpoint elements produce an instance
|
||||
of either the <classname>PollingConsumer</classname> or the
|
||||
<classname>EventDrivenConsumer</classname> depending on the type of the "input-channel" that is
|
||||
<classname>EventDrivenConsumer</classname> depending on the type of the <emphasis>input-channel</emphasis> that is
|
||||
referenced: <interfacename>PollableChannel</interfacename> or <interfacename>SubscribableChannel</interfacename>
|
||||
respectively. When the channel is pollable, then the polling behavior is determined based on the endpoint
|
||||
element's "poller" sub-element and its attributes. For example, a simple interval-based poller with a 1-second interval would be
|
||||
element's <emphasis>poller</emphasis> sub-element and its attributes.
|
||||
</para>
|
||||
|
||||
<emphasis>Configuration</emphasis>
|
||||
|
||||
<para>Below you find a <emphasis>poller</emphasis> with all available configuration options:</para>
|
||||
|
||||
<programlisting language="xml"><![CDATA[<int:poller cron="" ]]><co id="poller-xml01-co" linkends="sp-gateway-xml01" /><![CDATA[
|
||||
default="false" ]]><co id="poller-xml02-co" linkends="poller-xml02" /><![CDATA[
|
||||
error-channel="" ]]><co id="poller-xml03-co" linkends="poller-xml03" /><![CDATA[
|
||||
fixed-delay="" ]]><co id="poller-xml04-co" linkends="poller-xml04" /><![CDATA[
|
||||
fixed-rate="" ]]><co id="poller-xml05-co" linkends="poller-xml05" /><![CDATA[
|
||||
id="" ]]><co id="poller-xml06-co" linkends="poller-xml06" /><![CDATA[
|
||||
max-messages-per-poll="" ]]><co id="poller-xml07-co" linkends="poller-xml07" /><![CDATA[
|
||||
receive-timeout="" ]]><co id="poller-xml08-co" linkends="poller-xml08" /><![CDATA[
|
||||
ref="" ]]><co id="poller-xml09-co" linkends="poller-xml09" /><![CDATA[
|
||||
task-executor="" ]]><co id="poller-xml10-co" linkends="poller-xml10" /><![CDATA[
|
||||
time-unit="MILLISECONDS" ]]><co id="poller-xml11-co" linkends="poller-xml11" /><![CDATA[
|
||||
trigger=""> ]]><co id="poller-xml12-co" linkends="poller-xml12" /><![CDATA[
|
||||
<int:advice-chain /> ]]><co id="poller-xml13-co" linkends="poller-xml13" /><![CDATA[
|
||||
<int:transactional /> ]]><co id="poller-xml14-co" linkends="poller-xml14" /><![CDATA[
|
||||
</int:poller>]]></programlisting>
|
||||
|
||||
<para>
|
||||
<calloutlist>
|
||||
<callout arearefs="poller-xml01-co" id="poller-xml01">
|
||||
<para>
|
||||
Provides the ability to configure Pollers using Cron expressions.
|
||||
The underlying implementation uses a
|
||||
<classname>org.springframework.scheduling.support.CronTrigger</classname>.
|
||||
|
||||
If this attribute is set, none of the following attributes
|
||||
must be specified: <code>fixed-delay</code>, <code>trigger</code>,
|
||||
<code>fixed-rate</code>, <code>ref</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml02-co" id="poller-xml02">
|
||||
<para>
|
||||
By setting this attribute to <emphasis>true</emphasis>,
|
||||
it is possible to define exactly one (1) global default
|
||||
poller. An exception is raised if more than one default
|
||||
poller is defined in the application context.
|
||||
|
||||
Any endpoints connected to a PollableChannel (PollingConsumer)
|
||||
or any SourcePollingChannelAdapter that does not have any
|
||||
explicitly configured poller will then use the global default
|
||||
Poller.
|
||||
<emphasis>Optional</emphasis>. Defaults to <code>false</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml03-co" id="poller-xml03">
|
||||
<para>
|
||||
Identifies the channel which error messages will be sent to if
|
||||
a failure occurs in this poller's invocation. To completely
|
||||
suppress Exceptions, provide a reference to the
|
||||
<code>nullChannel</code>. <emphasis>Optional</emphasis>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml04-co" id="poller-xml04">
|
||||
<para>
|
||||
The fixed delay trigger uses a <classname>PeriodicTrigger</classname>
|
||||
under the covers. If the <code>time-unit</code> attribute is
|
||||
not used, the specified value is represented in milliseconds.
|
||||
|
||||
If this attribute is set, none of the following attributes
|
||||
must be specified: <code>fixed-rate</code>, <code>trigger</code>,
|
||||
<code>cron</code>, <code>ref</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml05-co" id="poller-xml05">
|
||||
<para>
|
||||
The fixed rate trigger uses a <classname>PeriodicTrigger</classname>
|
||||
under the covers. If the <code>time-unit</code> attribute is
|
||||
not used the specified value is represented in milliseconds.
|
||||
|
||||
If this attribute is set, none of the following attributes
|
||||
must be specified: <code>fixed-delay</code>, <code>trigger</code>,
|
||||
<code>cron</code>, <code>ref</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml06-co" id="poller-xml06">
|
||||
<para>
|
||||
The Id referring to the Poller's underlying bean-definition,
|
||||
which is of type
|
||||
<classname>org.springframework.integration.scheduling.PollerMetadata</classname>.
|
||||
The <emphasis>id</emphasis> attribute is required for
|
||||
a top-level poller element unless it is the default
|
||||
poller (<code>default="true"</code>).
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml07-co" id="poller-xml07">
|
||||
<para>
|
||||
Please see <xref linkend="channel-adapter-namespace-inbound"/>
|
||||
for more information. <emphasis>Optional</emphasis>. If
|
||||
not specified the default values used depends on the context.
|
||||
|
||||
If a <classname>PollingConsumer</classname> is used, this atribute
|
||||
will default to <emphasis>-1</emphasis>. However, if a
|
||||
<classname>SourcePollingChannelAdapter</classname> is used,
|
||||
then the <code>max-messages-per-poll</code> attribute defaults to
|
||||
<emphasis>1</emphasis>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml08-co" id="poller-xml08">
|
||||
<para>
|
||||
Value is set on the underlying class <classname>PollerMetadata</classname>
|
||||
<emphasis>Optional</emphasis>. If not specified it defaults
|
||||
to 1000 (milliseconds).
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml09-co" id="poller-xml09">
|
||||
<para>
|
||||
Bean reference to another top-level poller. The <code>ref</code>
|
||||
attribute must not be present on the top-level <code>poller</code>
|
||||
element.
|
||||
|
||||
However, if this attribute is set, none of the following attributes
|
||||
must be specified: <code>fixed-rate</code>, <code>trigger</code>,
|
||||
<code>cron</code>, <code>fixed-deleay</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml10-co" id="poller-xml10">
|
||||
<para>
|
||||
Provides the ability to reference a custom <emphasis>task executor</emphasis>.
|
||||
Please see the section below titled <emphasis>TaskExecutor Support</emphasis>
|
||||
for further information. <emphasis>Optional</emphasis>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml11-co" id="poller-xml11">
|
||||
<para>
|
||||
This attribute specifies the <classname>java.util.concurrent.TimeUnit</classname>
|
||||
enum value on the underlying
|
||||
<classname>org.springframework.scheduling.support.PeriodicTrigger</classname>.
|
||||
Therefore, this attribute can <emphasis>ONLY</emphasis>
|
||||
be used in combination with the <code>fixed-delay</code>
|
||||
or <code>fixed-rate</code> attributes. If combined with
|
||||
either <code>cron</code> or a <code>trigger</code> reference
|
||||
attribute, it will cause a failure.
|
||||
</para>
|
||||
<para>
|
||||
The minimal supported granularity for a
|
||||
<classname>PeriodicTrigger</classname> is MILLISECONDS.
|
||||
Therefore, the only available options are MILLISECONDS and
|
||||
SECONDS. If this value is not provided, then any
|
||||
<code>fixed-delay</code> or <code>fixed-rate</code> value
|
||||
will be interpreted as MILLISECONDS by default.
|
||||
</para>
|
||||
<para>
|
||||
Basically this enum provides a convenience for SECONDS-based
|
||||
interval trigger values. For hourly, daily, and monthly
|
||||
settings, consider using a <code>cron</code> trigger instead.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml12-co" id="poller-xml12">
|
||||
<para>
|
||||
Reference to any spring configured bean which implements
|
||||
the <interfacename>org.springframework.scheduling.Trigger</interfacename>
|
||||
interface.
|
||||
<emphasis>Optional</emphasis>. However, if this attribute
|
||||
is set, none of the following attributes must be specified:
|
||||
<code>fixed-delay</code>, <code>fixed-rate</code>,
|
||||
<code>cron</code>, <code>ref</code>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml13-co" id="poller-xml13">
|
||||
<para>
|
||||
Allows to specify extra AOP Advices to handle additional
|
||||
cross cutting concerns. Please see the section
|
||||
below titled <emphasis>Transaction Support</emphasis>
|
||||
for further information. <emphasis>Optional</emphasis>.
|
||||
</para>
|
||||
</callout>
|
||||
<callout arearefs="poller-xml14-co" id="poller-xml14">
|
||||
<para>
|
||||
Pollers can be made transactional. Please see the section
|
||||
below titled <emphasis>AOP Advice chains</emphasis>
|
||||
for further information. <emphasis>Optional</emphasis>.
|
||||
</para>
|
||||
</callout>
|
||||
</calloutlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis>Examples</emphasis>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example, a simple interval-based poller with a 1-second interval would be
|
||||
configured like this: <programlisting language="xml"><![CDATA[ <int:transformer input-channel="pollable"
|
||||
ref="transformer"
|
||||
output-channel="output">
|
||||
<int:poller fixed-rate="1000"/>
|
||||
</int:transformer>]]></programlisting>
|
||||
As an alternative to 'fixed-rate' you can also use the 'fixed-delay' attribute.
|
||||
As an alternative to <emphasis>fixed-rate</emphasis> you can also use the <emphasis>fixed-delay</emphasis> attribute.
|
||||
</para>
|
||||
<para>
|
||||
For a poller based on a Cron expression, use the "cron" attribute instead:
|
||||
For a poller based on a Cron expression, use the <emphasis>cron</emphasis> attribute instead:
|
||||
<programlisting language="xml"><![CDATA[ <int:transformer input-channel="pollable"
|
||||
ref="transformer"
|
||||
output-channel="output">
|
||||
@@ -183,56 +376,78 @@ consumer.setTransactionManager(txManager);</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
If the input channel is a <interfacename>PollableChannel</interfacename>, then the poller configuration is
|
||||
required. Specifically, as mentioned above, the 'trigger' is a required property of the PollingConsumer class.
|
||||
Therefore, if you omit the "poller" sub-element for a Polling Consumer endpoint's configuration, an Exception
|
||||
may be thrown. The exception will also be thrown if you attempt to configure a poller on the element that is
|
||||
required. Specifically, as mentioned above, the <emphasis>trigger</emphasis> is a required property of the PollingConsumer class.
|
||||
Therefore, if you omit the <emphasis>poller</emphasis> sub-element for a Polling Consumer endpoint's configuration, an Exception
|
||||
may be thrown. The exception will also be thrown if you attempt to configure a poller on the element that is
|
||||
connected to a non-pollable channel.
|
||||
</para>
|
||||
<para>
|
||||
It is also possible to create top-level pollers in which case only a "ref" is required:
|
||||
<programlisting language="xml"><![CDATA[ <int:poller id="weekdayPoller" cron="*/10 * * * * MON-FRI"/>
|
||||
|
||||
<para>
|
||||
It is also possible to create top-level pollers in which case only a <emphasis>ref</emphasis> is required:
|
||||
</para>
|
||||
|
||||
<programlisting language="xml"><![CDATA[ <int:poller id="weekdayPoller" cron="*/10 * * * * MON-FRI"/>
|
||||
|
||||
<int:transformer input-channel="pollable"
|
||||
ref="transformer"
|
||||
output-channel="output">
|
||||
<int:poller ref="weekdayPoller"/>
|
||||
</int:transformer>]]></programlisting>
|
||||
|
||||
<note>
|
||||
The "ref" attribute is only allowed on the inner-poller definitions. Defining this attribute on a top-level
|
||||
poller will result in a configuration exception thrown during initialization of the Application Context.
|
||||
<para>
|
||||
The <emphasis>ref</emphasis> attribute is only allowed on the inner-poller definitions. Defining this attribute on a top-level
|
||||
poller will result in a configuration exception thrown during initialization of the Application Context.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
<emphasis>Global Default Pollers</emphasis>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In fact, to simplify the configuration even further, you can define a global default poller. A single top-level poller within
|
||||
an ApplicationContext may have the <code>default</code> attribute with a value of "true". In that case, any
|
||||
an ApplicationContext may have the <code>default</code> attribute with a value of <emphasis>true</emphasis>. In that case, any
|
||||
endpoint with a PollableChannel for its input-channel that is defined within the same ApplicationContext and has
|
||||
no explicitly configured 'poller' sub-element will use that default.
|
||||
no explicitly configured <emphasis>poller</emphasis> sub-element will use that default.
|
||||
</para>
|
||||
<programlisting language="xml"><![CDATA[ <int:poller id="defaultPoller" default="true" max-messages-per-poll="5" fixed-rate="3000"/>
|
||||
|
||||
|
||||
<!-- No <poller/> sub-element is necessary since there is a default -->
|
||||
<int:transformer input-channel="pollable"
|
||||
ref="transformer"
|
||||
output-channel="output"/>]]></programlisting>
|
||||
|
||||
<para>
|
||||
<emphasis>Transaction Support</emphasis>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Spring Integration also provides transaction support for the pollers so that each receive-and-forward
|
||||
operation can be performed as an atomic unit-of-work. To configure transactions for a poller, simply add the
|
||||
<transactional/> sub-element. The attributes for this element should be familiar to anyone who has
|
||||
<emphasis><transactional/></emphasis> sub-element. The attributes for this element should be familiar to anyone who has
|
||||
experience with Spring's Transaction management:
|
||||
<programlisting language="xml"><![CDATA[<int:poller fixed-delay="1000">
|
||||
</para>
|
||||
|
||||
<programlisting language="xml"><![CDATA[<int:poller fixed-delay="1000">
|
||||
<int:transactional transaction-manager="txManager"
|
||||
propagation="REQUIRED"
|
||||
isolation="REPEATABLE_READ"
|
||||
timeout="10000"
|
||||
read-only="false"/>
|
||||
</int:poller>]]></programlisting>
|
||||
</int:poller>]]></programlisting>
|
||||
|
||||
<para>
|
||||
For more information please refer to <xref linkend="transaction-poller"/>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis>AOP Advice chains</emphasis>
|
||||
<emphasis>AOP Advice chains</emphasis>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Since Spring transaction support depends on the Proxy mechanism with <classname>TransactionInterceptor</classname> (AOP Advice) handling transactional
|
||||
behavior of the message flow initiated by the poler, some times there is a need to provide extra Advice(s) to handle other
|
||||
cross cutting behavior associated with the poller. For that poller defines an 'advice-chain' element allowing you to add
|
||||
Since Spring transaction support depends on the Proxy mechanism with <classname>TransactionInterceptor</classname> (AOP Advice) handling transactional
|
||||
behavior of the message flow initiated by the poller, some times there is a need to provide extra Advice(s) to handle other
|
||||
cross cutting behavior associated with the poller. For that poller defines an <emphasis>advice-chain</emphasis> element allowing you to add
|
||||
more advices - class that implements <classname>MethodInterceptor</classname> interface..
|
||||
<programlisting language="xml"><![CDATA[<int:service-activator id="advicedSa" input-channel="goodInputWithAdvice" ref="testBean"
|
||||
method="good" output-channel="output">
|
||||
@@ -243,32 +458,37 @@ consumer.setTransactionManager(txManager);</programlisting>
|
||||
<beans:bean class="org.bar.SampleAdvice"/>
|
||||
</int:advice-chain>
|
||||
</int:poller>
|
||||
</int:service-activator>]]></programlisting>
|
||||
For more information on how to implement MethodInterceptor please refer to AOP sections of Spring
|
||||
reference manual (section 7 and 8). Advice chain can also be applied on the poller that does not have
|
||||
</int:service-activator>]]></programlisting>
|
||||
For more information on how to implement MethodInterceptor please refer to AOP sections of Spring
|
||||
reference manual (section 8 and 9). Advice chain can also be applied on the poller that does not have
|
||||
any transaction configuration essentially allowing you to enhance the behavior of the message flow initiated by the poller.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<emphasis>TaskExecutor Support</emphasis>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The polling threads may be executed by any instance of Spring's <interfacename>TaskExecutor</interfacename>
|
||||
abstraction. This enables concurrency for an endpoint or group of endpoints. As of Spring 3.0, there is a "task"
|
||||
abstraction. This enables concurrency for an endpoint or group of endpoints. As of Spring 3.0, there is a <emphasis>task</emphasis>
|
||||
namespace in the core Spring Framework, and its <executor/> element supports the creation of a simple thread
|
||||
pool executor. That element accepts attributes for common concurrency settings such as pool-size and queue-capacity.
|
||||
Configuring a thread-pooling executor can make a substantial difference in how the endpoint performs under load. These
|
||||
settings are available per-endpoint since the performance of an endpoint is one of the major factors to consider
|
||||
(the other major factor being the expected volume on the channel to which the endpoint subscribes). To enable
|
||||
concurrency for a polling endpoint that is configured with the XML namespace support, provide the 'task-executor'
|
||||
concurrency for a polling endpoint that is configured with the XML namespace support, provide the <emphasis>task-executor</emphasis>
|
||||
reference on its <poller/> element and then provide one or more of the properties shown below:
|
||||
<programlisting language="xml"><![CDATA[ <int:poller task-executor="pool" fixed-rate="1000"/>
|
||||
|
||||
|
||||
<task:executor id="pool"
|
||||
pool-size="5-25"
|
||||
queue-capacity="20"
|
||||
keep-alive="120"/>]]></programlisting>
|
||||
If no 'task-executor' is provided, the consumer's handler will be invoked in the caller's thread. Note that the
|
||||
"caller" is usually the default <interfacename>TaskScheduler</interfacename>
|
||||
(see <xref linkend="namespace-taskscheduler"/>). Also, keep in mind that the 'task-executor' attribute can
|
||||
If no <emphasis>task-executor</emphasis> is provided, the consumer's handler will be invoked in the caller's thread. Note that the
|
||||
<emphasis>caller</emphasis> is usually the default <interfacename>TaskScheduler</interfacename>
|
||||
(see <xref linkend="namespace-taskscheduler"/>). Also, keep in mind that the <emphasis>task-executor</emphasis> attribute can
|
||||
provide a reference to any implementation of Spring's <interfacename>TaskExecutor</interfacename> interface by
|
||||
specifying the bean name. The "executor" element above is simply provided for convenience.
|
||||
specifying the bean name. The <emphasis>executor</emphasis> element above is simply provided for convenience.
|
||||
</para>
|
||||
<para>
|
||||
As mentioned in the background section for Polling Consumers above, you can also configure a Polling Consumer
|
||||
@@ -281,33 +501,88 @@ any transaction configuration essentially allowing you to enhance the behavior o
|
||||
participate. The following example demonstrates how a Polling Consumer will receive Messages nearly
|
||||
instantaneously.
|
||||
<programlisting language="xml"><![CDATA[ <int:service-activator input-channel="someQueueChannel"
|
||||
output-channel="output">
|
||||
output-channel="output">
|
||||
<int:poller receive-timeout="30000" fixed-rate="10"/>
|
||||
|
||||
|
||||
</int:service-activator>]]></programlisting>
|
||||
Using this approach does not carry much overhead since internally it is nothing more then a timed-wait thread
|
||||
which does not require nearly as much CPU resource usage as a thrashing, infinite while loop for example.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="polling-consumer-change-polling-rate">
|
||||
<title>Change Polling Rate at Runtime</title>
|
||||
<para>
|
||||
When configuring Pollers with a <code>fixed-delay</code> or
|
||||
<code>fixed-rate</code> attribute, the default implementation will use
|
||||
a <classname>PeriodicTrigger</classname> instance. The
|
||||
<classname>PeriodicTrigger</classname> is part of the Core Spring Framework
|
||||
and it accepts the <emphasis>interval</emphasis> as a constructor
|
||||
argument, only. Therefore it cannot be changed at runtime.
|
||||
</para>
|
||||
<para>
|
||||
However, you can define your own implementation of the
|
||||
<interfacename>org.springframework.scheduling.Trigger</interfacename>
|
||||
interface. You could even use the PeriodicTrigger as a starting point.
|
||||
Then, you can add a setter for the interval (period), or you could even
|
||||
embed your own throttling logic within the trigger itself if desired.
|
||||
The <emphasis>period</emphasis> property will be used with each call to
|
||||
<emphasis>nextExecutionTime</emphasis> to schedule the next poll.
|
||||
|
||||
To use this custom trigger within pollers, declare the bean defintion of
|
||||
the custom Trigger in your application context and inject the dependency
|
||||
into your Poller configuration using the <code>trigger</code> attribute,
|
||||
which references the custom Trigger bean instance.
|
||||
|
||||
You can now obtain a reference to the Trigger bean and the polling
|
||||
interval can be changed between polls.
|
||||
</para>
|
||||
<para>
|
||||
For an example, please see the Spring Integration Samples
|
||||
project. It contains a sample called <emphasis>dynamic-poller</emphasis>,
|
||||
which uses a custom Trigger and demonstrates the ability to change the polling
|
||||
interval at runtime.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><ulink url="https://github.com/SpringSource/spring-integration-samples/tree/master/intermediate">
|
||||
https://github.com/SpringSource/spring-integration-samples/tree/master/intermediate
|
||||
</ulink></listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
The sample provides a custom Trigger which implements the
|
||||
<emphasis><ulink url="http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/scheduling/Trigger.html">org.springframework.scheduling.Trigger</ulink></emphasis>
|
||||
interface. The sample's Trigger is based on Spring's <ulink url="http://static.springsource.org/spring/docs/current/javadoc-api/org/springframework/scheduling/support/PeriodicTrigger.html">PeriodicTrigger</ulink>
|
||||
implementation. However, the fields of the custom trigger are not final
|
||||
and the properties have explicit getters and setters, allowing to dynamically
|
||||
change the polling period at runtime.
|
||||
</para>
|
||||
<note><para>
|
||||
It is important to note, though, that because the Trigger method is
|
||||
<emphasis>nextExecutionTime()</emphasis>, any changes to a dynamic trigger
|
||||
will not take effect until the next poll, based on the existing configuration.
|
||||
It is not possible to force a trigger to fire before it's currently
|
||||
configured next execution time.
|
||||
</para></note>
|
||||
</section>
|
||||
|
||||
<section id="payload-type-conversion">
|
||||
<title>Payload Type Conversion</title>
|
||||
<para>
|
||||
Throughout the reference manual, you will also see specific configuration and implementation examples of various endpoints
|
||||
which can accept a Message or any arbitrary Object as an input parameter. In the case of an Object, such a parameter will
|
||||
be mapped to a Message payload or part of the payload or header (when using the Spring Expression Language). However there
|
||||
are times when the type of input parameter of the endpoint method does not match the type of the payload or its part.
|
||||
In this scenario we need to perform type conversion. Spring Integration provides a convenient way for registering type
|
||||
Throughout the reference manual, you will also see specific configuration and implementation examples of various endpoints
|
||||
which can accept a Message or any arbitrary Object as an input parameter. In the case of an Object, such a parameter will
|
||||
be mapped to a Message payload or part of the payload or header (when using the Spring Expression Language). However there
|
||||
are times when the type of input parameter of the endpoint method does not match the type of the payload or its part.
|
||||
In this scenario we need to perform type conversion. Spring Integration provides a convenient way for registering type
|
||||
converters (using the Spring 3.x ConversionService) within its own instance of a conversion service bean named <emphasis>integrationConversionService</emphasis>.
|
||||
That bean is automatically created as soon as the first converter is defined using the Spring Integration namespace support.
|
||||
|
||||
To register a Converter all you need is to implement
|
||||
<interfacename>org.springframework.core.convert.converter.Converter</interfacename> and define it via
|
||||
<interfacename>org.springframework.core.convert.converter.Converter</interfacename> and define it via
|
||||
convenient namespace support:
|
||||
<programlisting language="xml"><![CDATA[ <int:converter ref="sampleConverter"/>
|
||||
|
||||
<bean id="sampleConverter" class="foo.bar.TestConverter"/>]]></programlisting>
|
||||
|
||||
|
||||
or as an inner bean:
|
||||
<programlisting language="xml"><![CDATA[ <int:converter>
|
||||
<bean class="org.springframework.integration.config.xml.ConverterParserTests$TestConverter3"/>
|
||||
@@ -318,9 +593,9 @@ any transaction configuration essentially allowing you to enhance the behavior o
|
||||
<section id="async-polling">
|
||||
<title>Asynchronous polling</title>
|
||||
<para>
|
||||
If you want the polling to be asynchronous, a Poller can optionally specify a 'task-executor' attribute
|
||||
pointing to an existing instance of any <classname>TaskExecutor</classname> bean
|
||||
(Spring 3.0 provides a convenient namespace configuration via the <code>task</code> namespace). However, there are certain things
|
||||
If you want the polling to be asynchronous, a Poller can optionally specify a <emphasis>task-executor</emphasis> attribute
|
||||
pointing to an existing instance of any <classname>TaskExecutor</classname> bean
|
||||
(Spring 3.0 provides a convenient namespace configuration via the <code>task</code> namespace). However, there are certain things
|
||||
you must understand when configuring a Poller with a TaskExecutor.
|
||||
</para>
|
||||
<para>
|
||||
@@ -328,21 +603,21 @@ any transaction configuration essentially allowing you to enhance the behavior o
|
||||
and they both have to be in tune with each other otherwise you might end up creating an artificial memory leak.
|
||||
</para>
|
||||
<para>
|
||||
Let's look at the following configuration provided by one of the users on the Spring Integration
|
||||
Let's look at the following configuration provided by one of the users on the Spring Integration
|
||||
forum (http://forum.springsource.org/showthread.php?t=94519):
|
||||
|
||||
<programlisting language="xml"><![CDATA[<int:service-activator input-channel="publishChannel" ref="myService">
|
||||
<int:poller receive-timeout="5000" task-executor="taskExecutor" fixed-rate="50"/>
|
||||
</int:service-activator>
|
||||
|
||||
|
||||
<task:executor id="taskExecutor" pool-size="20" queue-capacity="20"/>]]></programlisting>
|
||||
|
||||
|
||||
The above configuration demonstrates one of those out of tune configurations.
|
||||
</para>
|
||||
<para>
|
||||
The poller keeps scheduling new tasks even though all the threads are blocked waiting for either a new message to arrive,
|
||||
or the timeout to expire. Given that there are 20 threads executing tasks with a 5 second timeout, they will be executed
|
||||
at a rate of 4 per second (5000/20 = 250ms). But, new tasks are being scheduled at a rate of 20 per second, so the internal
|
||||
The poller keeps scheduling new tasks even though all the threads are blocked waiting for either a new message to arrive,
|
||||
or the timeout to expire. Given that there are 20 threads executing tasks with a 5 second timeout, they will be executed
|
||||
at a rate of 4 per second (5000/20 = 250ms). But, new tasks are being scheduled at a rate of 20 per second, so the internal
|
||||
queue in the task executor will grow at a rate of 16 per second (while the process is idle), so we essentially have a memory leak.
|
||||
</para>
|
||||
<para>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<title>Messaging Channels</title>
|
||||
|
||||
<xi:include href="./channel.xml"/>
|
||||
<xi:include href="./polling-consumer.xml"/>
|
||||
<xi:include href="./channel-adapter.xml"/>
|
||||
<xi:include href="./bridge.xml"/>
|
||||
|
||||
|
||||
71
src/reference/docbook/polling-consumer.xml
Normal file
71
src/reference/docbook/polling-consumer.xml
Normal file
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="polling-consumer"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Poller (Polling Consumer)</title>
|
||||
<para>
|
||||
When Message Endpoints (Channel Adapters) are connected to channels and
|
||||
instantiated, they produce one of the following 2 instances:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><ulink url="http://static.springsource.org/spring-integration/api/org/springframework/integration/endpoint/PollingConsumer.html">PollingConsumer</ulink></listitem>
|
||||
<listitem><ulink url="http://static.springsource.org/spring-integration/api/org/springframework/integration/endpoint/EventDrivenConsumer.html">EventDrivenConsumer</ulink></listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
The actual implementation depends on which type of channel these Endpoints
|
||||
are connected to. A channel adapter connected to a channel that implements
|
||||
the <interfacename><ulink url="http://static.springsource.org/spring-integration/api/org/springframework/integration/core/SubscribableChannel.html">org.springframework.integration.core.SubscribableChannel</ulink></interfacename>
|
||||
interface will produce an instance of <classname>EventDrivenConsumer</classname>.
|
||||
On the other hand, a channel adapter connected to a channel that implements the
|
||||
<interfacename><ulink url="http://static.springsource.org/spring-integration/api/org/springframework/integration/core/PollableChannel.html">org.springframework.integration.core.PollableChannel</ulink></interfacename>
|
||||
interface (e.g. a QueueChannel) will produce an instance of <classname>PollingConsumer</classname>.
|
||||
</para>
|
||||
<para>
|
||||
Polling Consumers allow Spring Integration components to actively poll for
|
||||
Messages, rather than to process Messages in an event-driven manner.
|
||||
</para>
|
||||
<para>
|
||||
They represent a critical cross cutting concern in many
|
||||
messaging scenarios. In Spring Integration, Polling Consumers are based
|
||||
on the pattern with the same name, which is described in the book
|
||||
"Enterprise Integration Patterns" by Gregor Hohpe and Bobby Woolf. You
|
||||
can find a description of the pattern on the book's website at:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><ulink url="http://www.enterpriseintegrationpatterns.com/PollingConsumer.html">
|
||||
http://www.enterpriseintegrationpatterns.com/PollingConsumer.html
|
||||
</ulink></listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
Furthermore, in Spring Integration a second variation of the Polling Consumer
|
||||
pattern exists. When Inbound Channel Adapters are being used, these adapters
|
||||
are often wrapped by a <classname>SourcePollingChannelAdapter</classname>.
|
||||
For example, when retrieving messages from a remote FTP Server location,
|
||||
the adapter described in <xref linkend="ftp-inbound" />
|
||||
is configured with a <emphasis>poller</emphasis> to retrieve messages periodically.
|
||||
So, when components are configured with Pollers, the resulting instances are
|
||||
of one of the following types:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><ulink url="http://static.springsource.org/spring-integration/api/org/springframework/integration/endpoint/PollingConsumer.html">PollingConsumer</ulink></listitem>
|
||||
<listitem><ulink url="http://static.springsource.org/spring-integration/api/org/springframework/integration/endpoint/SourcePollingChannelAdapter.html">SourcePollingChannelAdapter</ulink></listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
This means, Pollers are used in both inbound and outbound messaging scenarios.
|
||||
Here are some use-cases that illustrate the scenarios in which Pollers are
|
||||
used:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>Polling certain external systems such as FTP Servers, Databases, Web Services</listitem>
|
||||
<listitem>Polling internal (pollable) Message Channels</listitem>
|
||||
<listitem>Polling internal services (E.g. repeatedly execute methods on a Java class)</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
This chapter is meant to only give a high-level overview regarding Polling Consumers
|
||||
and how they fit into the concept of message channels - <xref linkend="channel"/> and
|
||||
channel adapters -
|
||||
<xref linkend="channel-adapter"/>. For more in-depth information regarding
|
||||
Messaging Endpoints in general and Polling Consumers in particular, please see
|
||||
<xref linkend="endpoint"/>.
|
||||
</para>
|
||||
|
||||
</section>
|
||||
Reference in New Issue
Block a user