Stream is AutoCloseable, Stream.onClose
Brian Goetz
brian.goetz at oracle.com
Thu Jun 20 11:18:02 PDT 2013
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 {
> }
>
>
More information about the lambda-libs-spec-experts
mailing list