Utilities of auto close

Sam Pullara spullara at gmail.com
Mon Jun 24 09:44:23 PDT 2013


The one thing that bothers me about this discussion is that TWR would have never existed if lambdas had been in the language — it would just be a static method in java.io somewhere. It isn't clear to me that we should be mixing them at all. It seems like we should be using something more like Jed's Managed suggestion or even less. 

For example, we could just add a .release() on the Stream (to make it clear that it is targeted at resource management) and have it called when either the stream is exhausted or an exception is thrown from the pipeline. For those that convert their streams to external iteration via .iterator() may the buyer beware.

Sam

On Jun 24, 2013, at 7:54 AM, Zhong Yu <zhong.j.yu at gmail.com> wrote:

> I agree with you and Jeb that returning a wrapped Stream is better
> than returning a Stream that inherits Closeable. The wrapper is more
> generic, useful for all types of resources. But I think the task of
> triggering clean up should not be on individual resources, but rather
> on a enclosing lexical scope. I feel the latter pattern result in more
> pleasant code. For example
> 
>    try(Scope scope = Scope.newInstance())
>    {
>        InputStream input = new FileInputStream(src);
>        scope.onClose(input::close);
> 
>        OutputStream output = new FileOutputStream(dest);
>        scope.onClose(output::close);
> 
>        ...
>    }
> 
> It's subjective, of course.
> 
> Zhong Yu
> 
> 
> On Mon, Jun 24, 2013 at 6:35 AM, Samir Talwar <samir at noodlesandwich.com> wrote:
>> I don't like the idea of mutable scopes. This seems like it could introduce
>> a whole unnecessary class of bugs. I'd prefer to just replace the
>> inheritance with composition using your scope metaphor.
>> 
>>    try (IterableScope<Path> scope = Files.list(dir)) {
>>        Stream<Path> entries = scope.stream();
>>        // do stuff with entries
>>    }
>> 
>>    interface IterableScope<T> extends Iterable<T>, AutoCloseable { }
>> 
>> The name is not so important, but the idea would be to separate the concepts
>> of iteration and scoping so that the user has to deal with them both,
>> instead of accidentally storing the CloseableStream as a Stream and
>> forgetting to close it.
>> 
>> – Samir.
>> 
>> On 21 Jun 2013 15:48, "Zhong Yu" <zhong.j.yu at gmail.com> wrote:
>>> 
>>> EG is discussing the issue of closing a Stream that ties to IO
>>> resources, and I'd like to throw in my 2 cents.
>>> 
>>> Background: some new IO methods return Stream of things, for example
>>> 
>>>    class Files
>>>        /** return a stream of entries in the dir */
>>>        static Stream<Path> list(Path dir);
>>> 
>>> The problem is some IO resources are tied up and they need to be freed
>>> as soon as the Stream is no longer used.
>>> 
>>> The current solution is
>>> 
>>>        interface CloseableStream<T> extends Stream<T>, AutoCloseable
>>> 
>>>        static CloseableStream<Path> list(Path dir);
>>> 
>>> EG is discussing an alternative that makes all Streams AutoCloseable
>>> 
>>>        interface Stream<T> extends AutoCloseable
>>> 
>>> Some disagree with that approach, since most Streams do not need to be
>>> closed.
>>> 
>>> ==
>>> My proposal:
>>> 
>>> It's better to move the business of close() away from Stream to some
>>> surrounding constructs. For example:
>>> 
>>>    try(Scope scope = Scope.newInstance())
>>>    {
>>>        Stream<Path> entries = Files.list(scope, dir);
>>>    }
>>> 
>>>   interface Scope extends AutoCloseable
>>>    {
>>>        void onClose(Runnable action);
>>> 
>>>        void close();
>>>    }
>>> 
>>>    static Stream<Path> list(Scope scope, Path dir)
>>>    {
>>>        ...
>>>        scope.onClose( ()->{ free resources } );
>>>        ...
>>>    }
>>> 
>>> 
>>> Scope provides generic destructor-like functionality, orthogonal to
>>> resource types.
>>> 
>>> Zhong Yu
>>> 
>> 
> 



More information about the lambda-dev mailing list