Skip to content

DATACMNS-650 - Provide a CloseableIterator abstraction as a foundation for streaming of results. #116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from

Conversation

thomasdarimont
Copy link

Introduced CloseableIterator, AutoCloseableIterator and ForwardingAutoCloseableIterator to bridge between the two.

thomasdarimont pushed a commit that referenced this pull request Feb 24, 2015
…n for streaming of results.

Introduced CloseableIterator, AutoCloseableIterator and ForwardingAutoCloseableIterator to bridge between the two.

Original pull request: #116.
@jhoeller
Copy link

Guys, java.io.Closeable extends java.lang.AutoCloseable anyway... So I'm not sure what AutoCloseableIterator really adds here, and why the forwarding is needed?

We're implementing Java 6's Closeable to implicitly get Java 7 AutoCloseable behavior in a few places in the core framework as well. Seems to work fine for those purposes.

@thomasdarimont
Copy link
Author

AutoCloseable was just introduced with Java 7 so it isn't available if SD Commons is used with Java 6.
Or am I missing something here?

@jhoeller
Copy link

Sure, but my point is: Any of our classes implementing Closeable implicitly implements AutoCloseable on Java 7, since the Closeable interface itself happens to extend AutoCloseable on Java 7+. This is perfectly Java 6 compatible and also enables AutoCloseable when running on Java 7, simply through implementing Closeable. Any extra business with AutoCloseable decoration is effectively unnecessary.

thomasdarimont pushed a commit that referenced this pull request Feb 24, 2015
…on for streaming of results.

A CloseableIterator abstracts the underlying result with support for releasing the associated resources via close() which can be transparently be used with TRW in Java 7 since Closeable implements AutoCloseable from Java 7 upwards.

Original pull request: #116.
@thomasdarimont
Copy link
Author

A gotcha :) You are right.

thomasdarimont pushed a commit that referenced this pull request Feb 24, 2015
…on for streaming of results.

A CloseableIterator abstracts the underlying result with support for releasing the associated resources via close() which can be transparently be used with TRW in Java 7 since Closeable implements AutoCloseable from Java 7 upwards.
Added detector methods to QueryMethod to check whether the current method returns a Stream or a CloseableIterator.
Introduced ReflectionUtils.isJava8StreamType to safely detect whether the given type is assignable to a Java 8 Stream type.
Introdocued CloseableIteratorDisposingRunnable that can be registered as a cleanup action on a Stream.

Original pull request: #116.
thomasdarimont pushed a commit that referenced this pull request Feb 24, 2015
…on for streaming of results.

A CloseableIterator abstracts the underlying result with support for releasing the associated resources via close() which can be transparently be used with TRW in Java 7 since Closeable implements AutoCloseable from Java 7 upwards.
Added detector methods to QueryMethod to check whether the current method returns a Stream or a CloseableIterator.
Introduced ReflectionUtils.isJava8StreamType to safely detect whether the given type is assignable to a Java 8 Stream type.
Introdocued CloseableIteratorDisposingRunnable that can be registered as a cleanup action on a Stream.

Original pull request: #116.
String streamClassName = "java.util.stream.Stream";

Class<?> cls = null;
if (ClassUtils.isPresent(streamClassName, ReflectionUtils.class.getClassLoader())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we just use ClassUtils.forName(…) here?

@odrotbohm
Copy link
Member

As outline in the comments on the original pull request I think we should focus on a CloseableIterable as return type. Using an Iterator as return type seems rather uncommon.

@thomasdarimont
Copy link
Author

After having played a bit with the API I still think that a CloseableIterable<T>provides a richer API experience.

Consider the following variants:

//Variant 1 - CloseableIterator<Person>
@Query("{firstname:{$in:?0}}")
CloseableIterator<Person> findByCustomQueryByFirstnames(List<String> firstnames);

//V1: Use case 1 - loop over all results.
try (CloseableIterator<Person> result = repository.findByCustomQueryByFirstnames(Arrays.asList("Dave"))){
    for (Person person : result) {
        readPersons.add(person);
    }
}

//V1: Use case 2 - check for results and process later
try (CloseableIterator<Person> result = repository.findByCustomQueryByFirstnames(Arrays.asList("Dave"))){
    if(result.hasNext()){
        //doSomething
    }else{
        //doSomething else
    }

    for (Person person : result) {
        readPersons.add(person);
    }   
}


//Variant 2 - CloseableIterable<Person>
@Query("{firstname:{$in:?0}}")
CloseableIterable<Person> findByCustomQueryByFirstnames(List<String> firstnames);

//V2: Use case 1 - loop over all results.
try (CloseableIterable<Person> result = repository.findByCustomQueryByFirstnames(Arrays.asList("Dave"))){
    for (Person person : result) {
        readPersons.add(person);
    }
}

//V2: Use case 2 - check for results and process later
try (CloseableIterable<Person> result = repository.findByCustomQueryByFirstnames(Arrays.asList("Dave"))){

    Iterator iter = result.iterator();

    if(iter.hasNext()){
        //doSomething
    } else{
        //doSomething else
    }

    for (Person person : result) {
        readPersons.add(person);
    }   

    //what to close now? iterator or result?
}

In Variant1 it is clear what the "resource" and a user can conveniently iterate over the results.
Variant2 however doesn't make this clear per se - IMHO.

Variant1 is also much easier to work with (older) Collection libraries that don't support Iterable yet - so one can safe a method call here... it is not that important but adds to the list IMHO.

Thomas Darimont added 3 commits March 2, 2015 11:20
…n for streaming of results.

Prepare issue branch.
…on for streaming of results.

A CloseableIterator abstracts the underlying result with support for releasing the associated resources via close() which can be transparently be used with TRW in Java 7 since Closeable implements AutoCloseable from Java 7 upwards.
Added detector methods to QueryMethod to check whether the current method returns a Stream or a CloseableIterator.
Introduced ReflectionUtils.isJava8StreamType to safely detect whether the given type is assignable to a Java 8 Stream type.
Introdocued CloseableIteratorDisposingRunnable that can be registered as a cleanup action on a Stream.

Original pull request: #116.
…on for streaming of results.

More lean check for presence of Java 8 Streams.
Thomas Darimont added 2 commits March 2, 2015 15:40
…on for streaming of results.

CloseableIterable doesn’t inherit from Iterable anymore in order to have more narrow contract. Inheriting from Iterable would imply to be able to create new iterators which is potentially not possible in all cases.

For this release we focus on providing Stream support for Java 8 instead of providing a similar query model for older Java versions.
…on for streaming of results.

Introduced Java8StreamUtils that helps with construction of Streams from iterators.
thomasdarimont pushed a commit that referenced this pull request Mar 3, 2015
…on for streaming of results.

A CloseableIterator abstracts the underlying result with support for releasing the associated resources via close() which can be transparently be used with try-with-resources in Java 7 since Closeable implements AutoCloseable from Java 7 on upwards. Added detector methods to QueryMethod to check whether the current method returns a Stream. 

Introduced ReflectionUtils.isJava8StreamType to safely detect whether the given type is assignable to a Java 8 Stream. Introduced CloseableIteratorDisposingRunnable that can be registered as a cleanup action on a Stream.

Original pull request: #116.
odrotbohm added a commit that referenced this pull request Mar 3, 2015
Added stream to the list of supported query method prefixes. Allow Stream to be used as return type for paginating queries, too.

Renamed Java8StreamUtils to StreamUtils. Some additional JavaDoc.

Original pull request: #116.
@odrotbohm odrotbohm closed this Mar 10, 2015
@odrotbohm odrotbohm deleted the issue/DATACMNS-650 branch March 10, 2015 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants