Stream is AutoCloseable, Stream.onClose

Joe Bowbeer joe.bowbeer at gmail.com
Thu Jun 20 11:10:15 PDT 2013


I like the benefits, though I think the onClose name is confusing.

In many frameworks, the onError/onExit/onEvent naming style is reserved for
method names in callback interfaces.  It is the prevalent convention
currently.  So I'd expect onClose() to be the method that is called-back
upon closing.

The method name that is needed for this wrapping purpose should be
something more imperative, possibly mentioning its function as a "close"
guard.

Some ideas below:

.autoclose(ac)
.autoclosing(ac)

.closeableStream(ac)

--Joe


On Thu, Jun 20, 2013 at 8:22 AM, Brian Goetz <brian.goetz at oracle.com> wrote:

> Paul, this looks great.  I love that we can get rid of CloseableStream and
> DelegatingStream (two of the last remaining top-level API warts), and
> efficiently incorporate resource release in a predictable manner.
>
>
>
>
>
> On 6/20/2013 11:17 AM, Paul Sandoz wrote:
>
>> Hi,
>>
>> Having another go at this...
>>
>> The current solution of resource management for Stream is poor (as
>> previously mentioned):
>>
>> 1) CloseableStream/**DelegatingStream add a lot of API surface area.
>>
>> 2) Operations on CloseableStream do not return a CloseableStream.
>>
>> 3) try-with-resources always needs to be used with the CloseableStream
>> since the Stream itself has no closeable semantics.
>>
>> 4) Stream.concat fails to propagate the closing
>>
>>
>> If Stream extends from AutoCloseable we can address the first 3 issues.
>> In fact it can be addressed with just a close method but it is awkward to
>> transform that into an AutoCloseable for use with try-with-resources: try
>> (AutoCloseable ac = () -> s.close()) { … }
>>
>> A negative point is it is no longer clear whether a stream should be
>> closed or not, which is anyway the case for issues 2/3/4. However, i don't
>> think that should stop us trying to improve the general situation, it's not
>> gonna be perfect but i think we can do better than what we currently have
>> [*].
>>
>>
>> Issue 4 can be addressed by adding a Stream.onClose(AutoCloseable ac)
>> method.
>>
>> Stream s = ...
>> s = s.onClose(a).filter(...).**onClose(b).
>> s.close(); // b is called, then a is called
>> s.toArray(); // throws ISE
>>
>> Stream s = ...
>> s = s.onClose(a).onClose(b).
>> s.close(); // b is called, then a is called
>> s.toArray(); // throws ISE
>>
>> The Stream.concat implementation becomes:
>>
>>          Stream<T> cs = (a.isParallel() || b.isParallel())
>>                 ? StreamSupport.parallelStream(**split)
>>                 : StreamSupport.stream(split);
>>
>>          return cs.onClose(() -> { a.close(); b.close(); } ) // ignoring
>> exception handling to be brief
>>
>>
>> The Stream.close/onClose methods enable us to specify more precisely the
>> behaviour of Stream.close, the order in which calls to close on
>> AutoClosable instances passed to onClose occur, and what happens if
>> AutoCloseable.close throws an exception.
>>
>>
>> Of course it is possible to do silly things like this:
>>
>>    s = s.conClose(a).filter(...).**onClose(s).
>>
>> but we could detect if s is stage in the pipeline and throw an IAE.
>>
>>
>> FWIW Stream.close/onClose is easy to implement efficiently.
>>
>> Paul.
>>
>> [*] The JDK world is murky, see ByteArrayInputStream.close:
>>
>>      /**
>>       * Closing a <tt>ByteArrayInputStream</tt> has no effect. The
>> methods in
>>       * this class can be called after the stream has been closed without
>>       * generating an <tt>IOException</tt>.
>>       * <p>
>>       */
>>      public void close() throws IOException {
>>      }
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/attachments/20130620/d427ad96/attachment.html 


More information about the lambda-libs-spec-experts mailing list