Skip to content
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

Update bookmarks API #1211

Merged
merged 4 commits into from
May 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
injectives marked this conversation as resolved.
Show resolved Hide resolved
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();
injectives marked this conversation as resolved.
Show resolved Hide resolved

/**
* 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