20
20
import static java .net .HttpURLConnection .HTTP_NOT_FOUND ;
21
21
22
22
import com .google .api .core .BetaApi ;
23
+ import com .google .api .core .InternalApi ;
23
24
import com .google .api .services .bigquery .model .GetQueryResultsResponse ;
24
25
import com .google .api .services .bigquery .model .JobConfigurationQuery ;
25
26
import com .google .api .services .bigquery .model .QueryParameter ;
@@ -496,6 +497,38 @@ void parseRpcDataAsync(
496
497
queryTaskExecutor .execute (parseDataTask );
497
498
}
498
499
500
+ /**
501
+ * This method is called when the current thread is interrupted, this communicates to ResultSet by
502
+ * adding a EoS
503
+ *
504
+ * @param buffer
505
+ */
506
+ @ InternalApi
507
+ void markEoS (BlockingQueue <AbstractList <FieldValue >> buffer ) { // package-private
508
+ try {
509
+ buffer .put (new EndOfFieldValueList ()); // All the pages has been processed, put this marker
510
+ } catch (InterruptedException e ) {
511
+ logger .log (Level .WARNING , "\n " + Thread .currentThread ().getName () + " Interrupted" , e );
512
+ }
513
+ }
514
+
515
+ /**
516
+ * This method is called when the current thread is interrupted, this communicates to ResultSet by
517
+ * adding a isLast Row
518
+ *
519
+ * @param buffer
520
+ */
521
+ @ InternalApi
522
+ void markLast (BlockingQueue <BigQueryResultImpl .Row > buffer ) { // package-private
523
+ try {
524
+ buffer .put (
525
+ new BigQueryResultImpl .Row (
526
+ null , true )); // All the pages has been processed, put this marker
527
+ } catch (InterruptedException e ) {
528
+ logger .log (Level .WARNING , "\n " + Thread .currentThread ().getName () + " Interrupted" , e );
529
+ }
530
+ }
531
+
499
532
@ VisibleForTesting
500
533
void populateBufferAsync (
501
534
BlockingQueue <Tuple <TableDataList , Boolean >> rpcResponseQueue ,
@@ -516,18 +549,25 @@ void populateBufferAsync(
516
549
"\n " + Thread .currentThread ().getName () + " Interrupted" ,
517
550
e ); // Thread might get interrupted while calling the Cancel method, which is
518
551
// expected, so logging this instead of throwing the exception back
552
+ markEoS (
553
+ buffer ); // Thread has been interrupted, communicate to ResultSet by adding EoS
519
554
}
520
555
521
556
if (Thread .currentThread ().isInterrupted ()
522
557
|| fieldValueLists
523
558
== null ) { // do not process further pages and shutdown (outerloop)
559
+ markEoS (
560
+ buffer ); // Thread has been interrupted, communicate to ResultSet by adding EoS
524
561
break ;
525
562
}
526
563
527
564
for (FieldValueList fieldValueList : fieldValueLists ) {
528
565
try {
529
566
if (Thread .currentThread ()
530
567
.isInterrupted ()) { // do not process further pages and shutdown (inner loop)
568
+ markEoS (
569
+ buffer ); // Thread has been interrupted, communicate to ResultSet by adding
570
+ // EoS
531
571
break ;
532
572
}
533
573
buffer .put (fieldValueList );
@@ -537,19 +577,15 @@ void populateBufferAsync(
537
577
}
538
578
}
539
579
540
- if (Thread .currentThread ()
541
- .isInterrupted ()) { // clear the buffer for any outstanding records
542
- buffer .clear ();
543
- rpcResponseQueue
544
- .clear (); // IMP - so that if it's full then it unblocks and the interrupt logic
545
- // could trigger
546
- }
547
-
548
580
try {
549
- buffer .put (
550
- new EndOfFieldValueList ()); // All the pages has been processed, put this marker
551
- } catch (InterruptedException e ) {
552
- throw new BigQueryException (0 , e .getMessage (), e );
581
+ if (Thread .currentThread ()
582
+ .isInterrupted ()) { // clear the buffer for any outstanding records
583
+ rpcResponseQueue
584
+ .clear (); // IMP - so that if it's full then it unblocks and the interrupt logic
585
+ // could trigger
586
+ buffer .clear ();
587
+ }
588
+ markEoS (buffer ); // All the pages has been processed, put this marker
553
589
} finally {
554
590
queryTaskExecutor .shutdownNow (); // Shutdown the thread pool
555
591
}
@@ -790,12 +826,8 @@ private void processArrowStreamAsync(
790
826
} catch (Exception e ) {
791
827
throw BigQueryException .translateAndThrow (e );
792
828
} finally {
793
- try {
794
- buffer .put (new BigQueryResultImpl .Row (null , true )); // marking end of stream
795
- queryTaskExecutor .shutdownNow (); // Shutdown the thread pool
796
- } catch (InterruptedException e ) {
797
- logger .log (Level .WARNING , "\n Error occurred " , e );
798
- }
829
+ markLast (buffer ); // marking end of stream
830
+ queryTaskExecutor .shutdownNow (); // Shutdown the thread pool
799
831
}
800
832
};
801
833
@@ -856,6 +888,7 @@ private void processRows(
856
888
857
889
if (Thread .currentThread ().isInterrupted ()
858
890
|| queryTaskExecutor .isShutdown ()) { // do not process and shutdown
891
+ markLast (buffer ); // puts an isLast Row in the buffer for ResultSet to process
859
892
break ; // exit the loop, root will be cleared in the finally block
860
893
}
861
894
@@ -869,9 +902,7 @@ private void processRows(
869
902
}
870
903
buffer .put (new BigQueryResultImpl .Row (curRow ));
871
904
}
872
- root .clear (); // TODO: make sure to clear the root while implementing the thread
873
- // interruption logic (Connection.close method)
874
-
905
+ root .clear ();
875
906
} catch (RuntimeException | InterruptedException e ) {
876
907
throw BigQueryException .translateAndThrow (e );
877
908
} finally {
0 commit comments