Skip to content

Commit 308febf

Browse files
committed
Added javadocs for async APIs
1 parent ac7062a commit 308febf

File tree

5 files changed

+441
-30
lines changed

5 files changed

+441
-30
lines changed

driver/src/main/java/org/neo4j/driver/v1/Driver.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,20 @@ public interface Driver extends AutoCloseable
139139
Session session( AccessMode mode, Iterable<String> bookmarks );
140140

141141
/**
142-
* Close all the resources assigned to this driver, including any open connections.
142+
* Close all the resources assigned to this driver, including open connections and IO threads.
143+
* <p>
144+
* This operation works the same way as {@link #closeAsync()} but blocks until all resources are closed.
143145
*/
146+
@Override
144147
void close();
145148

149+
/**
150+
* Close all the resources assigned to this driver, including open connections and IO threads.
151+
* <p>
152+
* This operation is asynchronous and returns a {@link CompletionStage}. This stage is completed with
153+
* {@code null} when all resources are closed. It is completed exceptionally if termination fails.
154+
*
155+
* @return a {@link CompletionStage completion stage} that represents the asynchronous close.
156+
*/
146157
CompletionStage<Void> closeAsync();
147158
}

driver/src/main/java/org/neo4j/driver/v1/Session.java

Lines changed: 98 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
package org.neo4j.driver.v1;
2020

2121
import java.util.concurrent.CompletionStage;
22+
import java.util.concurrent.Executor;
23+
import java.util.function.Function;
2224

2325
import org.neo4j.driver.v1.util.Resource;
2426

@@ -42,19 +44,21 @@
4244
* the graph seen by the previous query. For more on causal consistency, see
4345
* the Neo4j clustering manual.
4446
* <p>
45-
* Typically, a session will wrap a TCP connection. Such a connection will be
46-
* acquired from a connection pool and released back there when the session is
47-
* destroyed. One connection can therefore be adopted by many sessions,
48-
* although by only one at a time. Application code should never need to deal
49-
* directly with connection management.
47+
* Typically, a session will acquire a TCP connection to execute query or
48+
* transaction. Such a connection will be acquired from a connection pool
49+
* and released back there when query result is consumed or transaction is
50+
* committed or rolled back. One connection can therefore be adopted by many
51+
* sessions, although by only one at a time. Application code should never need
52+
* to deal directly with connection management.
5053
* <p>
5154
* A session inherits its destination address and permissions from its
52-
* underlying connection. This means that one session may only ever target one
53-
* machine within a cluster and does not support re-authentication. To achieve
54-
* otherwise requires creation of a separate session.
55+
* underlying connection. This means that for a single query/transaction one
56+
* session may only ever target one machine within a cluster and does not
57+
* support re-authentication. To achieve otherwise requires creation of a
58+
* separate session.
5559
* <p>
5660
* Similarly, multiple sessions should be used when working with concurrency;
57-
* session implementations are generally not thread safe.
61+
* session implementations are not thread safe.
5862
*
5963
* @since 1.0
6064
*/
@@ -65,6 +69,9 @@ public interface Session extends Resource, StatementRunner
6569
* most one transaction may exist in a session at any point in time. To
6670
* maintain multiple concurrent transactions, use multiple concurrent
6771
* sessions.
72+
* <p>
73+
* This operation works the same way as {@link #beginTransactionAsync()} but blocks until transaction is actually
74+
* started.
6875
*
6976
* @return a new {@link Transaction}
7077
*/
@@ -84,34 +91,101 @@ public interface Session extends Resource, StatementRunner
8491
@Deprecated
8592
Transaction beginTransaction( String bookmark );
8693

94+
/**
95+
* Begin a new <em>explicit {@linkplain Transaction transaction}</em>. At
96+
* most one transaction may exist in a session at any point in time. To
97+
* maintain multiple concurrent transactions, use multiple concurrent
98+
* sessions.
99+
* <p>
100+
* This operation is asynchronous and returns a {@link CompletionStage}. This stage is completed with a new
101+
* {@link Transaction} object when begin operation is successful. It is completed exceptionally if
102+
* transaction can't be started.
103+
* <p>
104+
* Returned stage can be completed by an IO thread which should never block. Otherwise IO operations on this and
105+
* potentially other network connections might deadlock. Please do not chain blocking operations like
106+
* {@link #run(String)} on the returned stage. Driver will throw {@link IllegalStateException} when blocking API
107+
* call is executed in IO thread. Consider using asynchronous calls throughout the chain or offloading blocking
108+
* operation to a different {@link Executor}. This can be done using methods with "Async" suffix like
109+
* {@link CompletionStage#thenApplyAsync(Function)} or {@link CompletionStage#thenApplyAsync(Function, Executor)}.
110+
*
111+
* @return a {@link CompletionStage completion stage} that represents the asynchronous begin of a transaction.
112+
*/
87113
CompletionStage<Transaction> beginTransactionAsync();
88114

89115
/**
90116
* Execute given unit of work in a {@link AccessMode#READ read} transaction.
91117
* <p>
92118
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or from
93119
* {@link Transaction#close()} or transaction is explicitly marked for failure via {@link Transaction#failure()}.
120+
* <p>
121+
* This operation works the same way as {@link #readTransactionAsync(TransactionWork)} but blocks until given
122+
* blocking unit of work is completed.
94123
*
95124
* @param work the {@link TransactionWork} to be applied to a new read transaction.
96125
* @param <T> the return type of the given unit of work.
97126
* @return a result as returned by the given unit of work.
98127
*/
99128
<T> T readTransaction( TransactionWork<T> work );
100129

130+
/**
131+
* Execute given unit of asynchronous work in a {@link AccessMode#READ read} asynchronous transaction.
132+
* <p>
133+
* Transaction will automatically be committed unless given unit of work fails or
134+
* {@link Transaction#commitAsync() async transaction commit} fails. It will also not be committed if explicitly
135+
* rolled back via {@link Transaction#rollbackAsync()}.
136+
* <p>
137+
* Returned stage and given {@link TransactionWork} can be completed/executed by an IO thread which should never
138+
* block. Otherwise IO operations on this and potentially other network connections might deadlock. Please do not
139+
* chain blocking operations like {@link #run(String)} on the returned stage and do not use them inside the
140+
* {@link TransactionWork}. Driver will throw {@link IllegalStateException} when blocking API
141+
* call is executed in IO thread. Consider using asynchronous calls throughout the chain or offloading blocking
142+
* operation to a different {@link Executor}. This can be done using methods with "Async" suffix like
143+
* {@link CompletionStage#thenApplyAsync(Function)} or {@link CompletionStage#thenApplyAsync(Function, Executor)}.
144+
*
145+
* @param work the {@link TransactionWork} to be applied to a new read transaction. Operation executed by the
146+
* given work must be asynchronous.
147+
* @param <T> the return type of the given unit of work.
148+
* @return a {@link CompletionStage completion stage} completed with the same result as returned by the given
149+
* unit of work. Stage can be completed exceptionally if given work or commit fails.
150+
*/
101151
<T> CompletionStage<T> readTransactionAsync( TransactionWork<CompletionStage<T>> work );
102152

103153
/**
104-
* Execute given unit of work in a {@link AccessMode#WRITE write} transaction.
154+
* Execute given unit of work in a {@link AccessMode#WRITE write} transaction.
105155
* <p>
106156
* Transaction will automatically be committed unless exception is thrown from the unit of work itself or from
107157
* {@link Transaction#close()} or transaction is explicitly marked for failure via {@link Transaction#failure()}.
158+
* <p>
159+
* This operation works the same way as {@link #writeTransactionAsync(TransactionWork)} but blocks until given
160+
* blocking unit of work is completed.
108161
*
109162
* @param work the {@link TransactionWork} to be applied to a new write transaction.
110163
* @param <T> the return type of the given unit of work.
111164
* @return a result as returned by the given unit of work.
112165
*/
113166
<T> T writeTransaction( TransactionWork<T> work );
114167

168+
/**
169+
* Execute given unit of asynchronous work in a {@link AccessMode#WRITE write} asynchronous transaction.
170+
* <p>
171+
* Transaction will automatically be committed unless given unit of work fails or
172+
* {@link Transaction#commitAsync() async transaction commit} fails. It will also not be committed if explicitly
173+
* rolled back via {@link Transaction#rollbackAsync()}.
174+
* <p>
175+
* Returned stage and given {@link TransactionWork} can be completed/executed by an IO thread which should never
176+
* block. Otherwise IO operations on this and potentially other network connections might deadlock. Please do not
177+
* chain blocking operations like {@link #run(String)} on the returned stage and do not use them inside the
178+
* {@link TransactionWork}. Driver will throw {@link IllegalStateException} when blocking API
179+
* call is executed in IO thread. Consider using asynchronous calls throughout the chain or offloading blocking
180+
* operation to a different {@link Executor}. This can be done using methods with "Async" suffix like
181+
* {@link CompletionStage#thenApplyAsync(Function)} or {@link CompletionStage#thenApplyAsync(Function, Executor)}.
182+
*
183+
* @param work the {@link TransactionWork} to be applied to a new write transaction. Operation executed by the
184+
* given work must be asynchronous.
185+
* @param <T> the return type of the given unit of work.
186+
* @return a {@link CompletionStage completion stage} completed with the same result as returned by the given
187+
* unit of work. Stage can be completed exceptionally if given work or commit fails.
188+
*/
115189
<T> CompletionStage<T> writeTransactionAsync( TransactionWork<CompletionStage<T>> work );
116190

117191
/**
@@ -142,14 +216,23 @@ public interface Session extends Resource, StatementRunner
142216
void reset();
143217

144218
/**
145-
* Signal that you are done using this session. In the default driver usage, closing
146-
* and accessing sessions is very low cost, because sessions are pooled by {@link Driver}.
147-
*
148-
* When this method returns, all outstanding statements in the session are guaranteed to
149-
* have completed, meaning any writes you performed are guaranteed to be durably stored.
219+
* Signal that you are done using this session. In the default driver usage, closing and accessing sessions is
220+
* very low cost.
221+
* <p>
222+
* This operation works the same way as {@link #closeAsync()} but blocks until session is actually closed.
150223
*/
151224
@Override
152225
void close();
153226

227+
/**
228+
* Signal that you are done using this session. In the default driver usage, closing and accessing sessions is
229+
* very low cost.
230+
* <p>
231+
* This operation is asynchronous and returns a {@link CompletionStage}. Stage is completed when all outstanding
232+
* statements in the session have completed, meaning any writes you performed are guaranteed to be durably stored.
233+
* It might be completed exceptionally when there are unconsumed errors from previous statements or transactions.
234+
*
235+
* @return a {@link CompletionStage completion stage} that represents the asynchronous close.
236+
*/
154237
CompletionStage<Void> closeAsync();
155238
}

driver/src/main/java/org/neo4j/driver/v1/StatementResultCursor.java

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,45 @@
2020

2121
import java.util.List;
2222
import java.util.concurrent.CompletionStage;
23+
import java.util.concurrent.Executor;
2324

25+
import org.neo4j.driver.v1.exceptions.NoSuchRecordException;
2426
import org.neo4j.driver.v1.summary.ResultSummary;
2527
import org.neo4j.driver.v1.util.Consumer;
2628
import org.neo4j.driver.v1.util.Function;
2729

30+
/**
31+
* The result of asynchronous execution of a Cypher statement, conceptually an asynchronous stream of
32+
* {@link Record records}.
33+
* <p>
34+
* Result can be eagerly fetched in a list using {@link #listAsync()} or navigated lazily using
35+
* {@link #forEachAsync(Consumer)} or {@link #nextAsync()}.
36+
* <p>
37+
* Results are valid until the next statement is run or until the end of the current transaction,
38+
* whichever comes first. To keep a result around while further statements are run, or to use a result outside the scope
39+
* of the current transaction, see {@link #listAsync()}.
40+
* <p>
41+
* <h2>Important note on semantics</h2>
42+
* <p>
43+
* In order to handle very large results, and to minimize memory overhead and maximize
44+
* performance, results are retrieved lazily. Please see {@link StatementRunner} for
45+
* important details on the effects of this.
46+
* <p>
47+
* The short version is that, if you want a hard guarantee that the underlying statement
48+
* has completed, you need to either call {@link Transaction#commitAsync()} on the {@link Transaction transaction}
49+
* or {@link Session#closeAsync()} on the {@link Session session} that created this result, or you need to use
50+
* the result.
51+
* <p>
52+
* <b>Note:</b> Every returned {@link CompletionStage} can be completed by an IO thread which should never block.
53+
* Otherwise IO operations on this and potentially other network connections might deadlock. Please do not chain
54+
* blocking operations like {@link Session#run(String)} on the returned stages. Driver will throw
55+
* {@link IllegalStateException} when blocking API call is executed in IO thread. Consider using asynchronous calls
56+
* throughout the chain or offloading blocking operation to a different {@link Executor}. This can be done using
57+
* methods with "Async" suffix like {@link CompletionStage#thenApplyAsync(java.util.function.Function)} or
58+
* {@link CompletionStage#thenApplyAsync(java.util.function.Function, Executor)}.
59+
*
60+
* @since 1.5
61+
*/
2862
public interface StatementResultCursor
2963
{
3064
/**
@@ -34,19 +68,97 @@ public interface StatementResultCursor
3468
*/
3569
List<String> keys();
3670

71+
/**
72+
* Asynchronously retrieve the result summary.
73+
* <p>
74+
* If the records in the result is not fully consumed, then calling this method will force to pull all remaining
75+
* records into buffer to yield the summary.
76+
* <p>
77+
* If you want to obtain the summary but discard the records, use {@link #consumeAsync()} instead.
78+
*
79+
* @return a {@link CompletionStage} completed with a summary for the whole query result. Stage can also be
80+
* completed exceptionally if query execution fails.
81+
*/
3782
CompletionStage<ResultSummary> summaryAsync();
3883

84+
/**
85+
* Asynchronously navigate to and retrieve the next {@link Record} in this result. Returned stage can contain
86+
* {@code null} if end of records stream has been reached.
87+
*
88+
* @return a {@link CompletionStage} completed with a record or {@code null}. Stage can also be
89+
* completed exceptionally if query execution fails.
90+
*/
3991
CompletionStage<Record> nextAsync();
4092

93+
/**
94+
* Asynchronously investigate the next upcoming {@link Record} without moving forward in the result. Returned
95+
* stage can contain {@code null} if end of records stream has been reached.
96+
*
97+
* @return a {@link CompletionStage} completed with a record or {@code null}. Stage can also be
98+
* completed exceptionally if query execution fails.
99+
*/
41100
CompletionStage<Record> peekAsync();
42101

102+
/**
103+
* Asynchronously return the first record in the result, failing if there is not exactly
104+
* one record left in the stream.
105+
*
106+
* @return a {@link CompletionStage} completed with the first and only record in the stream. Stage will be
107+
* completed exceptionally with {@link NoSuchRecordException} if there is not exactly one record left in the
108+
* stream. It can also be completed exceptionally if query execution fails.
109+
*/
43110
CompletionStage<Record> singleAsync();
44111

112+
/**
113+
* Asynchronously consume the entire result, yielding a summary of it. Calling this method exhausts the result.
114+
*
115+
* @return a {@link CompletionStage} completed with a summary for the whole query result. Stage can also be
116+
* completed exceptionally if query execution fails.
117+
*/
45118
CompletionStage<ResultSummary> consumeAsync();
46119

120+
/**
121+
* Asynchronously apply the given {@link Consumer action} to every record in the result, yielding a summary of it.
122+
*
123+
* @param action the function to be applied to every record in the result. Provided function should not block.
124+
* @return a {@link CompletionStage} completed with a summary for the whole query result. Stage can also be
125+
* completed exceptionally if query execution or provided function fails.
126+
*/
47127
CompletionStage<ResultSummary> forEachAsync( Consumer<Record> action );
48128

129+
/**
130+
* Asynchronously retrieve and store the entire result stream.
131+
* This can be used if you want to iterate over the stream multiple times or to store the
132+
* whole result for later use.
133+
* <p>
134+
* Note that this method can only be used if you know that the statement that
135+
* yielded this result returns a finite stream. Some statements can yield
136+
* infinite results, in which case calling this method will lead to running
137+
* out of memory.
138+
* <p>
139+
* Calling this method exhausts the result.
140+
*
141+
* @return a {@link CompletionStage} completed with a list of all remaining immutable records. Stage can also be
142+
* completed exceptionally if query execution fails.
143+
*/
49144
CompletionStage<List<Record>> listAsync();
50145

146+
/**
147+
* Asynchronously retrieve and store a projection of the entire result.
148+
* This can be used if you want to iterate over the stream multiple times or to store the
149+
* whole result for later use.
150+
* <p>
151+
* Note that this method can only be used if you know that the statement that
152+
* yielded this result returns a finite stream. Some statements can yield
153+
* infinite results, in which case calling this method will lead to running
154+
* out of memory.
155+
* <p>
156+
* Calling this method exhausts the result.
157+
*
158+
* @param mapFunction a function to map from Record to T. See {@link Records} for some predefined functions.
159+
* @param <T> the type of result list elements
160+
* @return a {@link CompletionStage} completed with a list of all remaining immutable records. Stage can also be
161+
* completed exceptionally if query execution or provided function fails.
162+
*/
51163
<T> CompletionStage<List<T>> listAsync( Function<Record,T> mapFunction );
52164
}

0 commit comments

Comments
 (0)