Do not block by default (#8580)
Currently, many timeouts in the project are like `-1` or other negative value with a meaning to wait indefinitely. According to distributed systems design and bad demo developing experience it is not OK to block forever. * Rework most of the timeouts in the framework to be `30` seconds. Only one remained as `1` seconds is a `PollingConsumer` where it is better to not block even for those 30 seconds when no messages in the queue, but let the polling task be rescheduled. * Remove the `MessagingGatewaySupport.replyTimeout` propagation down to the `PollingConsumer` correlator where it was a `-1` before and blocked the polling thread on the `Queue.poll()`. This fixed the problem with a single thread in a pool for auto-configured `TaskScheduler`. Now with 1 seconds wait time we are able to switch to other scheduled tasks even with only 1 thread in the pool
This commit is contained in:
@@ -431,7 +431,7 @@ It serves only as an indicator of whether to discard or send to the output or re
|
||||
Optional (the default is `false`).
|
||||
NOTE: This attribute might more properly be called `send-partial-result-on-timeout`, because the group may not actually expire if `expire-groups-upon-timeout` is set to `false`.
|
||||
<9> The timeout interval to wait when sending a reply `Message` to the `output-channel` or `discard-channel`.
|
||||
Defaults to `-1`, which results in blocking indefinitely.
|
||||
Defaults to `30` seconds.
|
||||
It is applied only if the output channel has some 'sending' limitations, such as a `QueueChannel` with a fixed 'capacity'.
|
||||
In this case, a `MessageDeliveryException` is thrown.
|
||||
For `AbstractSubscribableChannel` implementations, the `send-timeout` is ignored .
|
||||
|
||||
@@ -80,7 +80,7 @@ Optional.
|
||||
This attribute is not available inside a `Chain` element.
|
||||
Optional.
|
||||
<7> Specifies the maximum amount of time (in milliseconds) to wait when sending a reply message to the output channel.
|
||||
Defaults to `-1` -- blocking indefinitely.
|
||||
Defaults to `30` seconds.
|
||||
This attribute is not available inside a `Chain` element.
|
||||
Optional.
|
||||
<8> Defines a poller.
|
||||
@@ -150,7 +150,7 @@ This setting is useful when Message can be "`claimed`" only once.
|
||||
It defaults to `false`.
|
||||
Optional.
|
||||
<8> Specifies the maximum amount of time (in milliseconds) to wait when sending a reply message to the output channel.
|
||||
It defaults to `-1` -- blocking indefinitely.
|
||||
It defaults to `30` seconds.
|
||||
This attribute is not available inside a `Chain` element.
|
||||
Optional.
|
||||
<9> Defines a poller.
|
||||
|
||||
@@ -328,7 +328,7 @@ Optional.
|
||||
<9> Maximum amount of time in milliseconds to wait when sending a message to the channel, if the channel might block.
|
||||
For example, a queue channel can block until space is available, if its maximum capacity has been reached.
|
||||
Internally, the `send()` timeout is set on the `MessagingTemplate` and ultimately applied when invoking the send operation on the `MessageChannel`.
|
||||
By default, the `send() timeout is set to '-1', which can cause the send operation on the `MessageChannel`, depending on the implementation, to block indefinitely.
|
||||
By default, the `send()` timeout is set to '30'.
|
||||
Optional.
|
||||
<10> Boolean value indicating whether any payload that implements `Cloneable` should be cloned prior to sending the message to the request channel for acquiring the enriching data.
|
||||
The cloned version would be used as the target payload for the ultimate reply.
|
||||
|
||||
@@ -48,7 +48,7 @@ With this configuration defined, the `cafeService` can now be injected into othe
|
||||
See the <<./samples.adoc#samples,"`Samples`">> Appendix for an example that uses the `gateway` element (in the Cafe demo).
|
||||
|
||||
The defaults in the preceding configuration are applied to all methods on the gateway interface.
|
||||
If a reply timeout is not specified, the calling thread waits indefinitely for a reply.
|
||||
If a reply timeout is not specified, the calling thread waits for a reply for 30 seconds.
|
||||
See <<gateway-no-response>>.
|
||||
|
||||
The defaults can be overridden for individual methods.
|
||||
@@ -480,14 +480,16 @@ This means that there might be a chance that a message that was initiated by a g
|
||||
Some service activator method might result in an exception, thus providing no reply (as we do not generate null messages).
|
||||
In other words, multiple scenarios can cause a reply message to never come.
|
||||
That is perfectly natural in messaging systems.
|
||||
However, think about the implication on the gateway method. The gateway's method input arguments were incorporated into a message and sent downstream.
|
||||
However, think about the implication on the gateway method.
|
||||
The gateway's method input arguments were incorporated into a message and sent downstream.
|
||||
The reply message would be converted to a return value of the gateway's method.
|
||||
So you might want to ensure that, for each gateway call, there is always a reply message.
|
||||
Otherwise, your gateway method might never return and hang indefinitely.
|
||||
Otherwise, your gateway method might never return and hang indefinitely if `reply-timeout` is set to negative value.
|
||||
One way to handle this situation is by using an asynchronous gateway (explained later in this section).
|
||||
Another way of handling it is to explicitly set the `reply-timeout` attribute.
|
||||
Another way of handling it is to rely on a default `reply-timeout` as a `30` seconds.
|
||||
That way, the gateway does not hang any longer than the time specified by the `reply-timeout` and returns 'null' if that timeout does elapse.
|
||||
Finally, you might want to consider setting downstream flags, such as 'requires-reply', on a service-activator or 'throw-exceptions-on-rejection' on a filter. These options are discussed in more detail in the final section of this chapter.
|
||||
Finally, you might want to consider setting downstream flags, such as 'requires-reply', on a service-activator or 'throw-exceptions-on-rejection' on a filter.
|
||||
These options are discussed in more detail in the final section of this chapter.
|
||||
|
||||
NOTE: If the downstream flow returns an `ErrorMessage`, its `payload` (a `Throwable`) is treated as a regular downstream error.
|
||||
If there is an `error-channel` configured, it is sent to the error flow.
|
||||
@@ -841,7 +843,7 @@ You should understand that the reply message (if produced) is sent to a reply ch
|
||||
===== Downstream Component Returns 'null'
|
||||
|
||||
Sync Gateway -- single-threaded::
|
||||
If a component downstream returns 'null' and no `reply-timeout` has been configured, the gateway method call hangs indefinitely, unless a `reply-timeout` has been configured or the `requires-reply` attribute has been set on the downstream component (for example, a service activator) that might return 'null'.
|
||||
If a component downstream returns 'null' and the `reply-timeout` has been configured to negative value, the gateway method call hangs indefinitely, unless the `requires-reply` attribute has been set on the downstream component (for example, a service activator) that might return 'null'.
|
||||
In this case, an exception would be thrown and propagated to the gateway.
|
||||
Sync Gateway -- multi-threaded::
|
||||
The behavior is the same as the previous case.
|
||||
@@ -849,7 +851,7 @@ The behavior is the same as the previous case.
|
||||
===== Downstream Component Return Signature is 'void' While Gateway Method Signature Is Non-void
|
||||
|
||||
Sync Gateway -- single-threaded::
|
||||
If a component downstream returns 'void' and no `reply-timeout` has been configured, the gateway method call hangs indefinitely unless a `reply-timeout` has been configured.
|
||||
If a component downstream returns 'void' and the `reply-timeout` has been configured to negative value, the gateway method call hangs indefinitely.
|
||||
Sync Gateway -- multi-threaded::
|
||||
The behavior is the same as the previous case.
|
||||
|
||||
@@ -861,8 +863,9 @@ Sync Gateway -- multi-threaded::
|
||||
The behavior is the same as the previous case.
|
||||
|
||||
IMPORTANT: You should understand that, by default, `reply-timeout` is unbounded.
|
||||
Consequently, if you do not explicitly set the `reply-timeout`, your gateway method invocation might hang indefinitely.
|
||||
Consequently, if you set the `reply-timeout` to negative value, your gateway method invocation might hang indefinitely.
|
||||
So, to make sure you analyze your flow and if there is even a remote possibility of one of these scenarios to occur, you should set the `reply-timeout` attribute to a "'safe'" value.
|
||||
It is `30` seconds by default.
|
||||
Even better, you can set the `requires-reply` attribute of the downstream component to 'true' to ensure a timely response, as produced by the throwing of an exception as soon as that downstream component returns null internally.
|
||||
However, you should also realize that there are some scenarios (see <<long-running-process-downstream,the first one>>) where `reply-timeout` does not help.
|
||||
That means it is also important to analyze your message flow and decide when to use a synchronous gateway rather than an asynchronous gateway.
|
||||
@@ -873,11 +876,6 @@ Likewise, when dealing with a Filter, you can set the `throw-exception-on-reject
|
||||
In both of these cases, the resulting flow behaves like it contain a service activator with the 'requires-reply' attribute.
|
||||
In other words, it helps to ensure a timely response from the gateway method invocation.
|
||||
|
||||
NOTE: `reply-timeout` is unbounded for `<gateway/>` elements (created by the `GatewayProxyFactoryBean`).
|
||||
Inbound gateways for external integration (WS, HTTP, and so on) share many characteristics and attributes with these gateways.
|
||||
However, for those inbound gateways, the default `reply-timeout` is 1000 milliseconds (one second).
|
||||
If a downstream asynchronous hand-off is made to another thread, you may need to increase this attribute to allow enough time for the flow to complete before the gateway times out.
|
||||
|
||||
IMPORTANT: You should understand that the timer starts when the thread returns to the gateway -- that is, when the flow completes or a message is handed off to another thread.
|
||||
At that time, the calling thread starts waiting for the reply.
|
||||
If the flow was completely synchronous, the reply is immediately available.
|
||||
|
||||
@@ -899,7 +899,7 @@ For the _HTTP Outbound Gateway_, the XML Schema defines only the _reply-timeout_
|
||||
The _reply-timeout_ maps to the _sendTimeout_ property of the _org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler_ class.
|
||||
More precisely, the property is set on the extended `AbstractReplyProducingMessageHandler` class, which ultimately sets the property on the `MessagingTemplate`.
|
||||
|
||||
The value of the _sendTimeout_ property defaults to "-1" and will be applied to the connected `MessageChannel`.
|
||||
The value of the _sendTimeout_ property defaults to `30` seconds and will be applied to the connected `MessageChannel`.
|
||||
This means, that depending on the implementation, the Message Channel's _send_ method may block indefinitely.
|
||||
Furthermore, the _sendTimeout_ property is only used, when the actual MessageChannel implementation has a blocking send (such as 'full' bounded QueueChannel).
|
||||
|
||||
|
||||
@@ -985,7 +985,6 @@ Optional.
|
||||
<3> Lets you specify how long this gateway waits for the reply message to be sent successfully before throwing an exception.
|
||||
Keep in mind that, when sending to a `DirectChannel`, the invocation occurs in the sender's thread.
|
||||
Consequently, the failing of the send operation may be caused by other components further downstream.
|
||||
By default, the gateway waits indefinitely.
|
||||
The value is specified in milliseconds.
|
||||
Optional.
|
||||
<4> Indicates whether this procedure's return value should be included.
|
||||
|
||||
@@ -926,7 +926,6 @@ If this attribute is not defined, the request message must have a `replyChannel`
|
||||
Optional.
|
||||
<3> Specifies the time the gateway waits to send the result to the reply channel.
|
||||
Only applies when the reply channel itself might block the send operation (for example, a bounded `QueueChannel` that is currently full).
|
||||
By default, the gateway waits indefinitely.
|
||||
The value is specified in milliseconds.
|
||||
Optional.
|
||||
====
|
||||
|
||||
@@ -69,16 +69,15 @@ Optional.
|
||||
<6> A reference to a `MessageGroupStore` that can be used to store groups of messages under their correlation key until they are complete.
|
||||
Optional.
|
||||
(The default is a volatile in-memory store.)
|
||||
<7> Whether, upon the expiration of the group, the ordered group should be sent out (even if some of the messages are missing).
|
||||
<7> Whether, upon the expiration of the group, the ordered group should be sent out (even if some messages are missing).
|
||||
Optional.
|
||||
(The default is false.)
|
||||
See <<./aggregator.adoc#reaper,Managing State in an Aggregator: `MessageGroupStore`>>.
|
||||
<8> The timeout interval to wait when sending a reply `Message` to the `output-channel` or `discard-channel`.
|
||||
Defaults to `-1`, which blocks indefinitely.
|
||||
It is applied only if the output channel has some 'sending' limitations, such as a `QueueChannel` with a fixed 'capacity'.
|
||||
In this case, a `MessageDeliveryException` is thrown.
|
||||
The `send-timeout` is ignored for `AbstractSubscribableChannel` implementations.
|
||||
For `group-timeout(-expression)`, the `MessageDeliveryException` from the scheduled expire task leads this task to be rescheduled.
|
||||
For `group-timeout(-expression)`, the `MessageDeliveryException` from the scheduled expired task leads this task to be rescheduled.
|
||||
Optional.
|
||||
<9> A reference to a bean that implements the message correlation (grouping) algorithm.
|
||||
The bean can be an implementation of the `CorrelationStrategy` interface or a POJO.
|
||||
|
||||
@@ -380,7 +380,6 @@ This attribute defaults to `false`.
|
||||
|
||||
`timeout`::
|
||||
The `timeout` attribute specifies the maximum amount of time in milliseconds to wait when sending messages to the target Message Channels.
|
||||
By default, the send operation blocks indefinitely.
|
||||
|
||||
[[router-common-parameters-top]]
|
||||
===== Top-Level (Outside a Chain)
|
||||
|
||||
@@ -139,13 +139,12 @@ By default, the `send()` blocks for one second.
|
||||
It applies only if the output channel has some 'sending' limitations -- for example, a `QueueChannel` with a fixed 'capacity' that is full.
|
||||
In this case, a `MessageDeliveryException` is thrown.
|
||||
The `send-timeout` is ignored for `AbstractSubscribableChannel` implementations.
|
||||
For `group-timeout(-expression)`, the `MessageDeliveryException` from the scheduled expire task leads this task to be rescheduled.
|
||||
For `group-timeout(-expression)`, the `MessageDeliveryException` from the scheduled expired task leads this task to be rescheduled.
|
||||
Optional.
|
||||
<10> Lets you specify how long the scatter-gather waits for the reply message before returning.
|
||||
By default, it waits indefinitely.
|
||||
By default, it waits for `30` seconds.
|
||||
'null' is returned if the reply times out.
|
||||
Optional.
|
||||
It defaults to `-1`, meaning to wait indefinitely.
|
||||
<11> Specifies whether the scatter-gather must return a non-null value.
|
||||
This value is `true` by default.
|
||||
Consequently, a `ReplyRequiredException` is thrown when the underlying aggregator returns a null value after `gather-timeout`.
|
||||
@@ -214,4 +213,3 @@ This way errors from the `AggregatingMessageHandler` are going to be propagated
|
||||
For successful operation, a `gatherResultChannel`, `originalReplyChannel` and `originalErrorChannel` headers must be transferred back to replies from scatter recipient subflows.
|
||||
In this case a reasonable, finite `gatherTimeout` must be configured for the `ScatterGatherHandler`.
|
||||
Otherwise, it is going to be blocked waiting for a reply from the gatherer forever, by default.
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@ See <<./zip.adoc#zip,Zip Support>> for more information.
|
||||
- The `MessageFilter` now emits a warning into logs when message is silently discarded and dropped.
|
||||
See <<./filter.adoc#filter, Filter>> for more information.
|
||||
|
||||
- The default timeout for send and receive operations in gateways and replying channel adapters has been changed from infinity to `30` seconds.
|
||||
Only one left as a `1` second is a `receiveTimeout` for `PollingConsumer` to not block a scheduler thread too long and let other queued tasks to be performed with the `TaskScheduler`.
|
||||
|
||||
[[x6.1-web-sockets]]
|
||||
=== Web Sockets Changes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user