31
31
import com .google .spanner .v1 .PartialResultSet ;
32
32
import com .google .spanner .v1 .ResultSetMetadata ;
33
33
import com .google .spanner .v1 .ResultSetStats ;
34
-
35
34
import java .util .Collection ;
36
35
import java .util .LinkedList ;
37
36
import java .util .List ;
40
39
import java .util .logging .Logger ;
41
40
42
41
/** Default implementation for {@link AsyncResultSet}. */
43
- class AsyncResultSetImpl extends ForwardingStructReader implements ListenableAsyncResultSet , AsyncResultSet .StreamMessageListener {
42
+ class AsyncResultSetImpl extends ForwardingStructReader
43
+ implements ListenableAsyncResultSet , AsyncResultSet .StreamMessageListener {
44
44
private static final Logger log = Logger .getLogger (AsyncResultSetImpl .class .getName ());
45
45
46
-
47
46
/** State of an {@link AsyncResultSetImpl}. */
48
47
private enum State {
49
48
INITIALIZED ,
@@ -112,6 +111,9 @@ private enum State {
112
111
113
112
private State state = State .INITIALIZED ;
114
113
114
+ /** This variable indicates that produce rows thread is initiated */
115
+ private volatile boolean produceRowsInitiated ;
116
+
115
117
/**
116
118
* This variable indicates whether all the results from the underlying result set have been read.
117
119
*/
@@ -458,7 +460,7 @@ private class InitiateStreamingRunnable implements Runnable {
458
460
@ Override
459
461
public void run () {
460
462
try {
461
- if (!initiateStreaming (AsyncResultSetImpl .this )) {
463
+ if (!initiateStreaming (AsyncResultSetImpl .this )) {
462
464
initiateProduceRows ();
463
465
}
464
466
} catch (SpannerException e ) {
@@ -489,7 +491,10 @@ public ApiFuture<Void> setCallback(Executor exec, ReadyCallback cb) {
489
491
490
492
private void initiateProduceRows () {
491
493
this .service .execute (new ProduceRowsRunnable ());
492
- this .state = State .RUNNING ;
494
+ if (this .state == State .IN_PROGRESS ) {
495
+ this .state = State .RUNNING ;
496
+ }
497
+ produceRowsInitiated = true ;
493
498
}
494
499
495
500
Future <Void > getResult () {
@@ -504,7 +509,6 @@ public void cancel() {
504
509
"cannot cancel a result set without a callback" );
505
510
state = State .CANCELLED ;
506
511
pausedLatch .countDown ();
507
- this .result .setException (CANCELLED_EXCEPTION );
508
512
}
509
513
}
510
514
@@ -625,18 +629,25 @@ public Struct getCurrentRowAsStruct() {
625
629
}
626
630
627
631
@ Override
628
- public void onStreamMessage (PartialResultSet partialResultSet , int prefetchChunks , int currentBufferSize , StreamMessageRequestor streamMessageRequestor ) {
632
+ public void onStreamMessage (
633
+ PartialResultSet partialResultSet ,
634
+ int prefetchChunks ,
635
+ int currentBufferSize ,
636
+ StreamMessageRequestor streamMessageRequestor ) {
629
637
synchronized (monitor ) {
630
- if (state == State .IN_PROGRESS ) {
631
- // if PartialResultSet contains resume token or buffer size is more than configured size or we have reached
632
- // end of stream, we can start the thread
633
- boolean startJobThread = !partialResultSet .getResumeToken ().isEmpty ()
634
- || currentBufferSize > prefetchChunks || partialResultSet == GrpcStreamIterator .END_OF_STREAM ;
635
- if (startJobThread ){
636
- initiateProduceRows ();
637
- } else {
638
- streamMessageRequestor .requestMessages (1 );
639
- }
638
+ if (produceRowsInitiated ) {
639
+ return ;
640
+ }
641
+ // if PartialResultSet contains resume token or buffer size is more than configured size or
642
+ // we have reached end of stream, we can start the thread
643
+ boolean startJobThread =
644
+ !partialResultSet .getResumeToken ().isEmpty ()
645
+ || currentBufferSize > prefetchChunks
646
+ || partialResultSet == GrpcStreamIterator .END_OF_STREAM ;
647
+ if (startJobThread || state != State .IN_PROGRESS ) {
648
+ initiateProduceRows ();
649
+ } else {
650
+ streamMessageRequestor .requestMessages (1 );
640
651
}
641
652
}
642
653
}
0 commit comments