INT-4118: Detect EOF on stdin

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

Add an option to the `CharacterStreamReadingMessageSource` to detect EOF
on the stream and close the context.

Publish event instead of closing context.

Polishing - PR Comments

Polishing

Docs about stopping the poller.

* Fix typos in the docs
This commit is contained in:
Gary Russell
2016-09-22 11:54:00 -04:00
committed by Artem Bilan
parent a7171c4db9
commit f9ddefec2c
9 changed files with 306 additions and 21 deletions

View File

@@ -16,7 +16,8 @@ Both `ByteStreamReadingMessageSource` and `CharacterStreamReadingMessageSource`
By configuring one of these within a channel-adapter element, the polling period can be configured, and the Message Bus can automatically detect and schedule them.
The byte stream version requires an `InputStream`, and the character stream version requires a `Reader` as the single constructor argument.
The `ByteStreamReadingMessageSource` also accepts the 'bytesPerMessage' property to determine how many bytes it will attempt to read into each `Message`.
The default value is 1024
The default value is 1024.
[source,xml]
----
<bean class="org.springframework.integration.stream.ByteStreamReadingMessageSource">
@@ -27,7 +28,50 @@ The default value is 1024
<bean class="org.springframework.integration.stream.CharacterStreamReadingMessageSource">
<constructor-arg ref="someReader"/>
</bean>
----
The `CharacterStreamReadingMessageSource` wraps the reader in a `BufferedReader` (if it's not one already).
You can set the buffer size used by the buffered reader in the second constructor argument.
Starting with _version 5.0_, a third constructor argument (`blockToDetectEOF`) controls the behavior of the `CharacterStreamReadingMessageSource`.
When `false` (default), the `receive()` method checks if the reader is `ready()` and returns null if not.
EOF is not detected in this case.
When `true`, the `receive()` method blocks until data is available, or EOF is detected on the underlying stream.
When EOF is detected, a `StreamClosedEvent` (application event) is published; you can consume this event with a bean implementing `ApplicationListener<StreamClosedEvent>`.
NOTE: To facilitate EOF detection, the poller thread will block in the `receive()` method until either data arrives or EOF is detected.
IMPORTANT: The poller will continue to publish an event on each poll once EOF has been detected; the application listener can stop the adapter to prevent this.
The event is published on the poller thread and stopping the adapter will cause the thread to be interrupted.
If you intend to perform some interruptible task after stopping the adapter, you must either perform the `stop()` on a different thread, or use a different thread for those downstream activities.
Note that sending to a `QueueChannel` is interruptible so if you wish to send a message from the listener, do it before stopping the adapter.
This facilitates "piping" or redirecting data to `stdin`, such as...
[source]
----
cat foo.txt | java -jar my.jar
----
or
[source]
----
java -jar my.jar < foo.txt
----
allowing the application to terminate when the pipe is closed.
Four convenient factory methods are available:
[source, java]
----
public static final CharacterStreamReadingMessageSource stdin() { ... }
public static final CharacterStreamReadingMessageSource stdin(String charsetName) { ... }
public static final CharacterStreamReadingMessageSource stdinPipe() { ... }
public static final CharacterStreamReadingMessageSource stdinPipe(String charsetName) { ... }
----
[[stream-writing]]
@@ -77,6 +121,8 @@ To configure the inbound channel adapter the following code snippet shows the di
<int-stream:stdin-channel-adapter id="adapterWithProvidedCharset" charset="UTF-8"/>
----
Starting with _version 5.0_ you can set the `detect-eof` attribute which sets the `blockToDetectEOF` property - see <<stream-reading>> for more information.
To configure the outbound channel adapter you can use the namespace support as well.
The following code snippet shows the different configuration for an outbound channel adapters.

View File

@@ -45,3 +45,8 @@ The inbound channel adapters now have a property `max-fetch-size` which is used
Since _version 4.3.2_ a new `spring.integration.readOnly.headers` global property has been added to customize the list of headers which should not be copied to a newly created `Message` by the `MessageBuilder`.
See <<global-properties>> for more information.
==== Stream Changes
There is a new option on the `CharacterStreamReadingMessageSource` to allow it to be used to "pipe" stdin and publish an application event when the pipe is closed.
See <<stream-reading>> for more information.