Why doesn't Channels.newChannel(OutputStream) flush?
Alan Bateman
Alan.Bateman at oracle.com
Wed Apr 7 11:16:26 UTC 2021
On 06/04/2021 20:30, Charles Oliver Nutter wrote:
> While debugging some subprocess logic in JRuby today I came to the
> realization that the WritableByteChannel returned by
> Channels.newChannel(OutputStream) is "broken".
>
> https://github.com/jruby/jruby/pull/6649/commits/5a6912caf3adb70fb4c210c73ae02fbf16f404d9
>
> The issue arises when the provided stream is itself buffered, as is
> the case for Process.getOutputStream. Because neither Channel nor
> WritableByteChannel provide a way to flush (as Channels are expected
> to be "raw" unbuffered IO), data written to the wrapper will not
> propagate to the the other end of the stream until the intermediate
> buffer has been filled. A flush can only be performed if you have
> direct access to the underlying stream, which is generally impossible
> if using this wrapper to interact with a Channel-related API.
>
> I would propose that the default OutputStream Channel wrapper should
> flush() after every non-zero write (or potentially after every write,
> if the underlying stream is not altogether honest about how many bytes
> were written).
Channels.newChannel(OutputStream) dates from Java 1.4 and JSR-51 so I
don't think we can rush into changing it. If a writable channel is
created on an buffered stream then it will usually be up to the
underlying stream as to how much to buffer and when to flush when it
wraps another stream. So I think it will take a bit of exploration and
maybe there is a case for an overload that configures when if/when it
flushes. A PrintStream like autoFlush may or may not be enough.
-Alan.
More information about the core-libs-dev
mailing list