INT-3886: TCP Fix Socket Timeout: Raw Deserializer

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

An SO user reported a short message delivery when an NIO connection was timed out.

See JIRA for link.

We could not produce the problem with his deserializer but it did identify a problem
with the standard `ByteArrayRawSerializer`.

With NIO, socket timeouts were reported to the deserializer as a normal EOF (-1). This
caused the raw serializer to emit a short message - it's signal for end of message is the
socket closure.

We can't treat a timeout as a normal EOF.

If the socket is forcibly timed out due to no recent data, throw a `SocketTimeoutException` to
the deserializer.

Just in case the old behavior is being relied upon, a boolean has been added to restore that
behavior. This is not recommended, as using timeout to delimit messages is not reliable.

* Fix typos
* Increase `MongoDbInboundChannelAdapterIntegrationTests` timeouts
* Some code polishing
This commit is contained in:
Gary Russell
2015-11-12 19:37:59 -05:00
committed by Artem Bilan
parent f0d0772397
commit e5269bb265
5 changed files with 283 additions and 57 deletions

View File

@@ -223,6 +223,12 @@ When using this serializer, message reception will hang until the client closes
When this serializer is being used, and the client is a Spring Integration application, the client must use a connection factory that is configured with single-use=true - this causes the adapter to close the socket after sending the message; the serializer will not, itself, close the connection.
This serializer should only be used with connection factories used by channel adapters (not gateways), and the connection factories should be used by either an inbound or outbound adapter, and not both.
NOTE: Before version 4.2.2, when using NIO, this serializer treated a timeout (during read) as an end of file and the
data read so far was emitted as a message.
This is unreliable and should not be used to delimit messages; it now treats such conditions as an exception.
In the unlikely event you are using it this way, the previous behavior can be restored by setting the
`treatTimeoutAsEndOfMessage` constructor argument to `true`.
Each of these is a subclass of `AbstractByteArraySerializer` which implements both `org.springframework.core.serializer.Serializer` and `org.springframework.core.serializer.Deserializer`.
For backwards compatibility, connections using any subclass of `AbstractByteArraySerializer` for serialization will also accept a String which will be converted to a byte array first.
Each of these (de)serializers converts an input stream containing the corresponding format to a byte array payload.