Stream is AutoCloseable, Stream.onClose

Joe Bowbeer joe.bowbeer at gmail.com
Thu Jun 20 11:50:21 PDT 2013


Anything reasonably close without an "on" prefix would be better. Given the
prevalent onNaming style in many, many currently used frameworks, onClose
just looks wrong, both in its use and in Stream's list of methods.
On Jun 20, 2013 11:18 AM, "Brian Goetz" <brian.goetz at oracle.com> wrote:

> FWIW, the closest analogue to "onClose" in the current API is "parallel",
> which modifies execution characteristics of the current stream (whether it
> does this mutatively or functionally is a detail).
>
> Perhaps a good analogy would be: what would you call a "register a close
> hook" method on a builder object?  Because Stream is kind of like a
> builder.  I am not sure the onClose(closeAction) is all that confusing in
> the context of a builder; its not a method declaration, and almost no user
> will ever implement Stream directly, so I'm not sure the confusion is all
> that bad?
>
> On 6/20/2013 2:10 PM, Joe Bowbeer wrote:
>
>> 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
>> <mailto: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/8978f5e0/attachment.html 


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