@@ -48,6 +48,7 @@ public class BasicPullResponseHandler implements PullResponseHandler {
48
48
protected final MetadataExtractor metadataExtractor ;
49
49
protected final Connection connection ;
50
50
private final PullResponseCompletionListener completionListener ;
51
+ private final boolean syncSignals ;
51
52
52
53
private State state ;
53
54
private long toRequest ;
@@ -60,31 +61,105 @@ public BasicPullResponseHandler(
60
61
Connection connection ,
61
62
MetadataExtractor metadataExtractor ,
62
63
PullResponseCompletionListener completionListener ) {
64
+ this (query , runResponseHandler , connection , metadataExtractor , completionListener , false );
65
+ }
66
+
67
+ public BasicPullResponseHandler (
68
+ Query query ,
69
+ RunResponseHandler runResponseHandler ,
70
+ Connection connection ,
71
+ MetadataExtractor metadataExtractor ,
72
+ PullResponseCompletionListener completionListener ,
73
+ boolean syncSignals ) {
63
74
this .query = requireNonNull (query );
64
75
this .runResponseHandler = requireNonNull (runResponseHandler );
65
76
this .metadataExtractor = requireNonNull (metadataExtractor );
66
77
this .connection = requireNonNull (connection );
67
78
this .completionListener = requireNonNull (completionListener );
79
+ this .syncSignals = syncSignals ;
68
80
69
81
this .state = State .READY_STATE ;
70
82
}
71
83
72
84
@ Override
73
- public synchronized void onSuccess (Map <String , Value > metadata ) {
74
- assertRecordAndSummaryConsumerInstalled ();
75
- state .onSuccess (this , metadata );
85
+ public void onSuccess (Map <String , Value > metadata ) {
86
+ State newState ;
87
+ BiConsumer <Record , Throwable > recordConsumer = null ;
88
+ BiConsumer <ResultSummary , Throwable > summaryConsumer = null ;
89
+ ResultSummary summary = null ;
90
+ Neo4jException exception = null ;
91
+ synchronized (this ) {
92
+ assertRecordAndSummaryConsumerInstalled ();
93
+ state .onSuccess (this , metadata );
94
+ newState = state ;
95
+ if (newState == State .SUCCEEDED_STATE ) {
96
+ completionListener .afterSuccess (metadata );
97
+ try {
98
+ summary = extractResultSummary (metadata );
99
+ } catch (Neo4jException e ) {
100
+ summary = extractResultSummary (emptyMap ());
101
+ exception = e ;
102
+ }
103
+ recordConsumer = this .recordConsumer ;
104
+ summaryConsumer = this .summaryConsumer ;
105
+ if (syncSignals ) {
106
+ complete (summaryConsumer , recordConsumer , summary , exception );
107
+ }
108
+ dispose ();
109
+ } else if (newState == State .READY_STATE ) {
110
+ if (toRequest > 0 || toRequest == UNLIMITED_FETCH_SIZE ) {
111
+ request (toRequest );
112
+ toRequest = 0 ;
113
+ }
114
+ // summary consumer use (null, null) to identify done handling of success with has_more
115
+ this .summaryConsumer .accept (null , null );
116
+ }
117
+ }
118
+ if (!syncSignals && newState == State .SUCCEEDED_STATE ) {
119
+ complete (summaryConsumer , recordConsumer , summary , exception );
120
+ }
76
121
}
77
122
78
123
@ Override
79
- public synchronized void onFailure (Throwable error ) {
80
- assertRecordAndSummaryConsumerInstalled ();
81
- state .onFailure (this , error );
124
+ public void onFailure (Throwable error ) {
125
+ BiConsumer <Record , Throwable > recordConsumer ;
126
+ BiConsumer <ResultSummary , Throwable > summaryConsumer ;
127
+ ResultSummary summary ;
128
+ synchronized (this ) {
129
+ assertRecordAndSummaryConsumerInstalled ();
130
+ state .onFailure (this , error );
131
+ completionListener .afterFailure (error );
132
+ summary = extractResultSummary (emptyMap ());
133
+ recordConsumer = this .recordConsumer ;
134
+ summaryConsumer = this .summaryConsumer ;
135
+ if (syncSignals ) {
136
+ complete (summaryConsumer , recordConsumer , summary , error );
137
+ }
138
+ dispose ();
139
+ }
140
+ if (!syncSignals ) {
141
+ complete (summaryConsumer , recordConsumer , summary , error );
142
+ }
82
143
}
83
144
84
145
@ Override
85
- public synchronized void onRecord (Value [] fields ) {
86
- assertRecordAndSummaryConsumerInstalled ();
87
- state .onRecord (this , fields );
146
+ public void onRecord (Value [] fields ) {
147
+ State newState ;
148
+ Record record = null ;
149
+ synchronized (this ) {
150
+ assertRecordAndSummaryConsumerInstalled ();
151
+ state .onRecord (this , fields );
152
+ newState = state ;
153
+ if (newState == State .STREAMING_STATE ) {
154
+ record = new InternalRecord (runResponseHandler .queryKeys (), fields );
155
+ if (syncSignals ) {
156
+ recordConsumer .accept (record , null );
157
+ }
158
+ }
159
+ }
160
+ if (!syncSignals && newState == State .STREAMING_STATE ) {
161
+ recordConsumer .accept (record , null );
162
+ }
88
163
}
89
164
90
165
@ Override
@@ -99,38 +174,6 @@ public synchronized void cancel() {
99
174
state .cancel (this );
100
175
}
101
176
102
- protected void completeWithFailure (Throwable error ) {
103
- completionListener .afterFailure (error );
104
- complete (extractResultSummary (emptyMap ()), error );
105
- }
106
-
107
- protected void completeWithSuccess (Map <String , Value > metadata ) {
108
- completionListener .afterSuccess (metadata );
109
- ResultSummary summary ;
110
- Neo4jException exception = null ;
111
- try {
112
- summary = extractResultSummary (metadata );
113
- } catch (Neo4jException e ) {
114
- summary = extractResultSummary (emptyMap ());
115
- exception = e ;
116
- }
117
- complete (summary , exception );
118
- }
119
-
120
- protected void successHasMore () {
121
- if (toRequest > 0 || toRequest == UNLIMITED_FETCH_SIZE ) {
122
- request (toRequest );
123
- toRequest = 0 ;
124
- }
125
- // summary consumer use (null, null) to identify done handling of success with has_more
126
- summaryConsumer .accept (null , null );
127
- }
128
-
129
- protected void handleRecord (Value [] fields ) {
130
- Record record = new InternalRecord (runResponseHandler .queryKeys (), fields );
131
- recordConsumer .accept (record , null );
132
- }
133
-
134
177
protected void writePull (long n ) {
135
178
connection .writeAndFlush (new PullMessage (n , runResponseHandler .queryId ()), this );
136
179
}
@@ -198,12 +241,15 @@ private void assertRecordAndSummaryConsumerInstalled() {
198
241
}
199
242
}
200
243
201
- private void complete (ResultSummary summary , Throwable error ) {
244
+ private void complete (
245
+ BiConsumer <ResultSummary , Throwable > summaryConsumer ,
246
+ BiConsumer <Record , Throwable > recordConsumer ,
247
+ ResultSummary summary ,
248
+ Throwable error ) {
202
249
// we first inform the summary consumer to ensure when streaming finished, summary is definitely available.
203
250
summaryConsumer .accept (summary , error );
204
251
// record consumer use (null, null) to identify the end of record stream
205
252
recordConsumer .accept (null , error );
206
- dispose ();
207
253
}
208
254
209
255
private void dispose () {
@@ -226,13 +272,11 @@ enum State {
226
272
@ Override
227
273
void onSuccess (BasicPullResponseHandler context , Map <String , Value > metadata ) {
228
274
context .state (SUCCEEDED_STATE );
229
- context .completeWithSuccess (metadata );
230
275
}
231
276
232
277
@ Override
233
278
void onFailure (BasicPullResponseHandler context , Throwable error ) {
234
279
context .state (FAILURE_STATE );
235
- context .completeWithFailure (error );
236
280
}
237
281
238
282
@ Override
@@ -257,23 +301,19 @@ void cancel(BasicPullResponseHandler context) {
257
301
void onSuccess (BasicPullResponseHandler context , Map <String , Value > metadata ) {
258
302
if (metadata .getOrDefault ("has_more" , BooleanValue .FALSE ).asBoolean ()) {
259
303
context .state (READY_STATE );
260
- context .successHasMore ();
261
304
} else {
262
305
context .state (SUCCEEDED_STATE );
263
- context .completeWithSuccess (metadata );
264
306
}
265
307
}
266
308
267
309
@ Override
268
310
void onFailure (BasicPullResponseHandler context , Throwable error ) {
269
311
context .state (FAILURE_STATE );
270
- context .completeWithFailure (error );
271
312
}
272
313
273
314
@ Override
274
315
void onRecord (BasicPullResponseHandler context , Value [] fields ) {
275
316
context .state (STREAMING_STATE );
276
- context .handleRecord (fields );
277
317
}
278
318
279
319
@ Override
@@ -295,14 +335,12 @@ void onSuccess(BasicPullResponseHandler context, Map<String, Value> metadata) {
295
335
context .discardAll ();
296
336
} else {
297
337
context .state (SUCCEEDED_STATE );
298
- context .completeWithSuccess (metadata );
299
338
}
300
339
}
301
340
302
341
@ Override
303
342
void onFailure (BasicPullResponseHandler context , Throwable error ) {
304
343
context .state (FAILURE_STATE );
305
- context .completeWithFailure (error );
306
344
}
307
345
308
346
@ Override
@@ -324,13 +362,11 @@ void cancel(BasicPullResponseHandler context) {
324
362
@ Override
325
363
void onSuccess (BasicPullResponseHandler context , Map <String , Value > metadata ) {
326
364
context .state (SUCCEEDED_STATE );
327
- context .completeWithSuccess (metadata );
328
365
}
329
366
330
367
@ Override
331
368
void onFailure (BasicPullResponseHandler context , Throwable error ) {
332
369
context .state (FAILURE_STATE );
333
- context .completeWithFailure (error );
334
370
}
335
371
336
372
@ Override
@@ -352,13 +388,11 @@ void cancel(BasicPullResponseHandler context) {
352
388
@ Override
353
389
void onSuccess (BasicPullResponseHandler context , Map <String , Value > metadata ) {
354
390
context .state (SUCCEEDED_STATE );
355
- context .completeWithSuccess (metadata );
356
391
}
357
392
358
393
@ Override
359
394
void onFailure (BasicPullResponseHandler context , Throwable error ) {
360
395
context .state (FAILURE_STATE );
361
- context .completeWithFailure (error );
362
396
}
363
397
364
398
@ Override
0 commit comments