Skip to content

Commit

Permalink
Update bookmarks API (#1211)
Browse files Browse the repository at this point in the history
* Update bookmarks API

`Bookmark` objects should represent singular bookmark values. Multiple bookmarks will be represented as a set of bookmarks (`Set<Bookmark>`).

The main API updates are highlighted below.

`Bookmark` updates:
- `value()` - new method
- `values()` - deprecated
- `isEmpty()` - deprecated

`Session` and `AsyncSession` updates:
- `Set<Bookmark> lastBookmarks()` - new method
- `Bookmark lastBookmark()` - deprecated

`ReactiveSession` updates:
- `Set<Bookmark> lastBookmarks()` - new method
- `Bookmark lastBookmark()` - deprecated (has not been released)

* Update Session Javadoc

* Update Session Javadoc
  • Loading branch information
injectives authored May 12, 2022
1 parent 0d292fd commit c521c51
Show file tree
Hide file tree
Showing 91 changed files with 1,114 additions and 869 deletions.
24 changes: 24 additions & 0 deletions driver/clirr-ignored-differences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -304,4 +304,28 @@
<method>org.neo4j.driver.Value parameters(java.util.Map)</method>
</difference>

<difference>
<className>org/neo4j/driver/Bookmark</className>
<differenceType>7012</differenceType>
<method>org.neo4j.driver.Bookmark from(java.lang.String)</method>
</difference>

<difference>
<className>org/neo4j/driver/Bookmark</className>
<differenceType>7012</differenceType>
<method>java.lang.String value()</method>
</difference>

<difference>
<className>org/neo4j/driver/Session</className>
<differenceType>7012</differenceType>
<method>java.util.Set lastBookmarks()</method>
</difference>

<difference>
<className>org/neo4j/driver/async/AsyncSession</className>
<differenceType>7012</differenceType>
<method>java.util.Set lastBookmarks()</method>
</difference>

</differences>
26 changes: 25 additions & 1 deletion driver/src/main/java/org/neo4j/driver/Bookmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package org.neo4j.driver;

import java.util.Collections;
import java.util.Set;

import org.neo4j.driver.internal.InternalBookmark;
Expand All @@ -35,17 +36,39 @@
*/
public interface Bookmark
{
/**
* Returns a string that this bookmark instance identifies.
*
* @return a string that this bookmark instance identifies.
*/
String value();

/**
* Returns a read-only set of bookmark strings that this bookmark instance identifies.
*
* @return a read-only set of bookmark strings that this bookmark instance identifies.
*/
@Deprecated
Set<String> values();

/**
* Reconstruct bookmark from \bookmarks string values.
* Reconstruct bookmark from bookmark string value.
*
* @param value value obtained from a previous bookmark.
* @return A bookmark.
*/
static Bookmark from( String value )
{
return InternalBookmark.parse( Collections.singleton( value ) );
}

/**
* Reconstruct bookmark from bookmarks string values.
*
* @param values values obtained from a previous bookmark.
* @return A bookmark.
*/
@Deprecated
static Bookmark from( Set<String> values )
{
return InternalBookmark.parse( values );
Expand All @@ -55,5 +78,6 @@ static Bookmark from( Set<String> values )
* Return true if the bookmark is empty.
* @return true if the bookmark is empty.
*/
@Deprecated
boolean isEmpty();
}
25 changes: 18 additions & 7 deletions driver/src/main/java/org/neo4j/driver/Session.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.neo4j.driver;

import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

import org.neo4j.driver.async.AsyncSession;
Expand Down Expand Up @@ -317,18 +318,28 @@ default void executeWriteWithoutResult( Consumer<TransactionContext> contextCons
Result run(Query query, TransactionConfig config );

/**
* Return the bookmark received following the last completed
* {@linkplain Transaction transaction}. If no bookmark was received
* or if this transaction was rolled back, the bookmark value will
* be null.
* Return the last bookmark of this session.
* <p>
* When no new bookmark is received, the initial bookmarks are returned as a composite {@link Bookmark} containing all initial bookmarks. This may happen
* when no work has been done using the session. If no initial bookmarks have been provided, an empty {@link Bookmark} is returned.
*
* @return a reference to a previous transaction
* @return the last bookmark.
*/
@Deprecated
Bookmark lastBookmark();

/**
* Signal that you are done using this session. In the default driver usage, closing and accessing sessions is
* very low cost.
* Return a set of last bookmarks.
* <p>
* When no new bookmark is received, the initial bookmarks are returned. This may happen when no work has been done using the session. Multivalued {@link
* Bookmark} instances will be mapped to distinct {@link Bookmark} instances. If no initial bookmarks have been provided, an empty set is returned.
*
* @return the immutable set of last bookmarks.
*/
Set<Bookmark> lastBookmarks();

/**
* Signal that you are done using this session. In the default driver usage, closing and accessing sessions is very low cost.
*/
@Override
void close();
Expand Down
35 changes: 21 additions & 14 deletions driver/src/main/java/org/neo4j/driver/SessionConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.Optional;

import org.neo4j.driver.async.AsyncSession;
import org.neo4j.driver.reactive.ReactiveSession;
import org.neo4j.driver.reactive.RxSession;

import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -186,14 +187,12 @@ private Builder()
/**
* Set the initial bookmarks to be used in a session.
* <p>
* First transaction in a session will ensure that server hosting is at least as up-to-date as the
* latest transaction referenced by the supplied bookmarks.
* The bookmarks can be obtained via {@link Session#lastBookmark()}, {@link AsyncSession#lastBookmark()},
* and/or {@link RxSession#lastBookmark()}.
* First transaction in a session will ensure that server hosting is at least as up-to-date as the latest transaction referenced by the supplied
* bookmarks. The bookmarks can be obtained via {@link Session#lastBookmarks()}, {@link AsyncSession#lastBookmarks()}, and/or {@link
* ReactiveSession#lastBookmarks()}.
*
* @param bookmarks a series of initial bookmarks.
* Both {@code null} value and empty array
* are permitted, and indicate that the bookmarks do not exist or are unknown.
* @param bookmarks a series of initial bookmarks. Both {@code null} value and empty array are permitted, and indicate that the bookmarks do not exist
* or are unknown.
* @return this builder.
*/
public Builder withBookmarks( Bookmark... bookmarks )
Expand All @@ -210,14 +209,22 @@ public Builder withBookmarks( Bookmark... bookmarks )
}

/**
* Set the initial bookmarks to be used in a session.
* First transaction in a session will ensure that server hosting is at least as up-to-date as the
* latest transaction referenced by the supplied bookmarks.
* The bookmarks can be obtained via {@link Session#lastBookmark()}, {@link AsyncSession#lastBookmark()},
* and/or {@link RxSession#lastBookmark()}.
* Set the initial bookmarks to be used in a session. First transaction in a session will ensure that server hosting is at least as up-to-date as the
* latest transaction referenced by the supplied bookmarks. The bookmarks can be obtained via {@link Session#lastBookmarks()}, {@link
* AsyncSession#lastBookmarks()}, and/or {@link ReactiveSession#lastBookmarks()}.
* <p>
* Multiple immutable sets of bookmarks may be joined in the following way:
* <pre>
* {@code
* Set<Bookmark> bookmarks = new HashSet<>();
* bookmarks.addAll( session1.lastBookmarks() );
* bookmarks.addAll( session2.lastBookmarks() );
* bookmarks.addAll( session3.lastBookmarks() );
* }
* </pre>
*
* @param bookmarks initial references to some previous transactions. Both {@code null} value and empty iterable
* are permitted, and indicate that the bookmarks do not exist or are unknown.
* @param bookmarks initial references to some previous transactions. Both {@code null} value and empty iterable are permitted, and indicate that the
* bookmarks do not exist or are unknown.
* @return this builder
*/
public Builder withBookmarks( Iterable<Bookmark> bookmarks )
Expand Down
22 changes: 17 additions & 5 deletions driver/src/main/java/org/neo4j/driver/async/AsyncSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.neo4j.driver.async;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
Expand Down Expand Up @@ -382,15 +383,26 @@ default <T> CompletionStage<T> executeWriteAsync( AsyncTransactionCallback<Compl
CompletionStage<ResultCursor> runAsync( Query query, TransactionConfig config );

/**
* Return the bookmark received following the last completed
* {@linkplain Transaction transaction}. If no bookmark was received
* or if this transaction was rolled back, the bookmark value will
* be null.
* Return the last bookmark of this session.
* <p>
* When no new bookmark is received, the initial bookmarks are returned as a composite {@link Bookmark} containing all initial bookmarks. This may happen
* when no work has been done using the session. If no initial bookmarks have been provided, an empty {@link Bookmark} is returned.
*
* @return a reference to a previous transaction
* @return the last bookmark.
*/
@Deprecated
Bookmark lastBookmark();

/**
* Return a set of last bookmarks.
* <p>
* When no new bookmark is received, the initial bookmarks are returned. This may happen when no work has been done using the session. Multivalued {@link
* Bookmark} instances will be mapped to distinct {@link Bookmark} instances. If no initial bookmarks have been provided, an empty set is returned.
*
* @return the immutable set of last bookmarks.
*/
Set<Bookmark> lastBookmarks();

/**
* Signal that you are done using this session. In the default driver usage, closing and accessing sessions is
* very low cost.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,23 @@
*/
package org.neo4j.driver.internal;

import java.util.Collections;
import java.util.Set;

import org.neo4j.driver.Bookmark;

public interface BookmarkHolder
public interface BookmarksHolder
{
Bookmark getBookmark();
Set<Bookmark> getBookmarks();

void setBookmark( Bookmark bookmark );

BookmarkHolder NO_OP = new BookmarkHolder()
BookmarksHolder NO_OP = new BookmarksHolder()
{
@Override
public Bookmark getBookmark()
public Set<Bookmark> getBookmarks()
{
return InternalBookmark.empty();
return Collections.emptySet();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,41 @@
*/
package org.neo4j.driver.internal;

import java.util.Collections;
import java.util.Set;

import org.neo4j.driver.Bookmark;

/**
* @since 2.0
*/
public class DefaultBookmarkHolder implements BookmarkHolder
public class DefaultBookmarksHolder implements BookmarksHolder
{
private volatile Bookmark bookmark;
private volatile Set<Bookmark> bookmarks;

public DefaultBookmarkHolder()
// for testing only
public DefaultBookmarksHolder()
{
this( InternalBookmark.empty() );
this( Collections.emptySet() );
}

public DefaultBookmarkHolder( Bookmark bookmark )
public DefaultBookmarksHolder( Set<Bookmark> bookmarks )
{
this.bookmark = bookmark;
this.bookmarks = bookmarks;
}

@Override
public Bookmark getBookmark()
public Set<Bookmark> getBookmarks()
{
return bookmark;
return bookmarks;
}

@Override
public void setBookmark( Bookmark bookmark )
{
if ( bookmark != null && !bookmark.isEmpty() )
{
this.bookmark = bookmark;
bookmarks = Collections.singleton( bookmark );
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ public boolean isEmpty()
return values.isEmpty();
}

@Override
public String value()
{
return values.isEmpty() ? null : values.iterator().next();
}

@Override
public Set<String> values()
{
Expand Down
35 changes: 22 additions & 13 deletions driver/src/main/java/org/neo4j/driver/internal/InternalSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.neo4j.driver.internal;

import java.util.Map;
import java.util.Set;

import org.neo4j.driver.AccessMode;
import org.neo4j.driver.Bookmark;
Expand Down Expand Up @@ -140,7 +141,13 @@ public <T> T executeWrite( TransactionCallback<T> callback, TransactionConfig co
@Override
public Bookmark lastBookmark()
{
return session.lastBookmark();
return InternalBookmark.from( session.lastBookmarks() );
}

@Override
public Set<Bookmark> lastBookmarks()
{
return session.lastBookmarks();
}

private <T> T transaction( AccessMode mode, TransactionWork<T> work, TransactionConfig config )
Expand All @@ -149,19 +156,21 @@ private <T> T transaction( AccessMode mode, TransactionWork<T> work, Transaction
// caller thread will also be the one who sleeps between retries;
// it is unsafe to execute retries in the event loop threads because this can cause a deadlock
// event loop thread will bock and wait for itself to read some data
return session.retryLogic().retry( () -> {
try ( Transaction tx = beginTransaction( mode, config ) )
{

T result = work.execute( tx );
if ( tx.isOpen() )
return session.retryLogic().retry(
() ->
{
// commit tx if a user has not explicitly committed or rolled back the transaction
tx.commit();
}
return result;
}
} );
try ( Transaction tx = beginTransaction( mode, config ) )
{

T result = work.execute( tx );
if ( tx.isOpen() )
{
// commit tx if a user has not explicitly committed or rolled back the transaction
tx.commit();
}
return result;
}
} );
}

private Transaction beginTransaction( AccessMode mode, TransactionConfig config )
Expand Down
Loading

0 comments on commit c521c51

Please sign in to comment.