19
19
20
20
import com .datastax .dse .driver .api .core .DseProtocolVersion ;
21
21
import com .datastax .dse .driver .api .core .cql .continuous .ContinuousAsyncResultSet ;
22
+ import com .datastax .dse .driver .api .core .graph .AsyncGraphResultSet ;
22
23
import com .datastax .dse .driver .internal .core .DseProtocolFeature ;
23
24
import com .datastax .dse .driver .internal .core .cql .DseConversions ;
24
25
import com .datastax .dse .protocol .internal .request .Revise ;
25
26
import com .datastax .dse .protocol .internal .response .result .DseRowsMetadata ;
26
27
import com .datastax .oss .driver .api .core .AllNodesFailedException ;
28
+ import com .datastax .oss .driver .api .core .AsyncPagingIterable ;
27
29
import com .datastax .oss .driver .api .core .CqlIdentifier ;
28
30
import com .datastax .oss .driver .api .core .DriverTimeoutException ;
29
31
import com .datastax .oss .driver .api .core .NodeUnavailableException ;
@@ -626,7 +628,7 @@ public void operationComplete(@NonNull Future<java.lang.Void> future) {
626
628
Throwable error = future .cause ();
627
629
if (error instanceof EncoderException
628
630
&& error .getCause () instanceof FrameTooLongException ) {
629
- trackNodeError (node , error .getCause ());
631
+ trackNodeError (node , error .getCause (), null );
630
632
lock .lock ();
631
633
try {
632
634
abort (error .getCause (), false );
@@ -643,7 +645,7 @@ public void operationComplete(@NonNull Future<java.lang.Void> future) {
643
645
.getMetricUpdater ()
644
646
.incrementCounter (DefaultNodeMetric .UNSENT_REQUESTS , executionProfile .getName ());
645
647
recordError (node , error );
646
- trackNodeError (node , error .getCause ());
648
+ trackNodeError (node , error .getCause (), null );
647
649
sendRequest (statement , null , executionIndex , retryCount , scheduleSpeculativeExecution );
648
650
}
649
651
} else {
@@ -738,7 +740,8 @@ private void onPageTimeout(int expectedPage) {
738
740
* Invoked when a continuous paging response is received, either a successful or failed one.
739
741
*
740
742
* <p>Delegates further processing to appropriate methods: {@link #processResultResponse(Result,
741
- * Frame)} if the response was successful, or {@link #processErrorResponse(Error)} if it wasn't.
743
+ * Frame)} if the response was successful, or {@link #processErrorResponse(Error, Frame)} if it
744
+ * wasn't.
742
745
*
743
746
* @param response the received {@link Frame}.
744
747
*/
@@ -759,15 +762,15 @@ public void onResponse(@NonNull Frame response) {
759
762
processResultResponse ((Result ) responseMessage , response );
760
763
} else if (responseMessage instanceof Error ) {
761
764
LOG .trace ("[{}] Got error response" , logPrefix );
762
- processErrorResponse ((Error ) responseMessage );
765
+ processErrorResponse ((Error ) responseMessage , response );
763
766
} else {
764
767
IllegalStateException error =
765
768
new IllegalStateException ("Unexpected response " + responseMessage );
766
- trackNodeError (node , error );
769
+ trackNodeError (node , error , response );
767
770
abort (error , false );
768
771
}
769
772
} catch (Throwable t ) {
770
- trackNodeError (node , t );
773
+ trackNodeError (node , t , response );
771
774
abort (t , false );
772
775
}
773
776
} finally {
@@ -901,7 +904,7 @@ private void processResultResponse(@NonNull Result result, @Nullable Frame frame
901
904
* @param errorMessage the error message received.
902
905
*/
903
906
@ SuppressWarnings ("GuardedBy" ) // this method is only called with the lock held
904
- private void processErrorResponse (@ NonNull Error errorMessage ) {
907
+ private void processErrorResponse (@ NonNull Error errorMessage , @ NonNull Frame frame ) {
905
908
assert lock .isHeldByCurrentThread ();
906
909
if (errorMessage instanceof Unprepared ) {
907
910
processUnprepared ((Unprepared ) errorMessage );
@@ -910,7 +913,7 @@ private void processErrorResponse(@NonNull Error errorMessage) {
910
913
if (error instanceof BootstrappingException ) {
911
914
LOG .trace ("[{}] {} is bootstrapping, trying next node" , logPrefix , node );
912
915
recordError (node , error );
913
- trackNodeError (node , error );
916
+ trackNodeError (node , error , frame );
914
917
sendRequest (statement , null , executionIndex , retryCount , false );
915
918
} else if (error instanceof QueryValidationException
916
919
|| error instanceof FunctionFailureException
@@ -922,7 +925,7 @@ private void processErrorResponse(@NonNull Error errorMessage) {
922
925
NodeMetricUpdater metricUpdater = ((DefaultNode ) node ).getMetricUpdater ();
923
926
metricUpdater .incrementCounter (
924
927
DefaultNodeMetric .OTHER_ERRORS , executionProfile .getName ());
925
- trackNodeError (node , error );
928
+ trackNodeError (node , error , frame );
926
929
abort (error , true );
927
930
} else {
928
931
try {
@@ -1061,7 +1064,7 @@ private void processUnprepared(@NonNull Unprepared errorMessage) {
1061
1064
+ "This usually happens when you run a 'USE...' query after "
1062
1065
+ "the statement was prepared." ,
1063
1066
Bytes .toHexString (idToReprepare ), Bytes .toHexString (repreparedId )));
1064
- trackNodeError (node , illegalStateException );
1067
+ trackNodeError (node , illegalStateException , null );
1065
1068
fatalError = illegalStateException ;
1066
1069
} else {
1067
1070
LOG .trace (
@@ -1080,18 +1083,18 @@ private void processUnprepared(@NonNull Unprepared errorMessage) {
1080
1083
|| prepareError instanceof FunctionFailureException
1081
1084
|| prepareError instanceof ProtocolError ) {
1082
1085
LOG .trace ("[{}] Unrecoverable error on re-prepare, rethrowing" , logPrefix );
1083
- trackNodeError (node , prepareError );
1086
+ trackNodeError (node , prepareError , null );
1084
1087
fatalError = prepareError ;
1085
1088
}
1086
1089
}
1087
1090
} else if (exception instanceof RequestThrottlingException ) {
1088
- trackNodeError (node , exception );
1091
+ trackNodeError (node , exception , null );
1089
1092
fatalError = exception ;
1090
1093
}
1091
1094
if (fatalError == null ) {
1092
1095
LOG .trace ("[{}] Re-prepare failed, trying next node" , logPrefix );
1093
1096
recordError (node , exception );
1094
- trackNodeError (node , exception );
1097
+ trackNodeError (node , exception , null );
1095
1098
sendRequest (statement , null , executionIndex , retryCount , false );
1096
1099
}
1097
1100
}
@@ -1119,18 +1122,18 @@ private void processRetryVerdict(@NonNull RetryVerdict verdict, @NonNull Throwab
1119
1122
switch (verdict .getRetryDecision ()) {
1120
1123
case RETRY_SAME :
1121
1124
recordError (node , error );
1122
- trackNodeError (node , error );
1125
+ trackNodeError (node , error , null );
1123
1126
sendRequest (
1124
1127
verdict .getRetryRequest (statement ), node , executionIndex , retryCount + 1 , false );
1125
1128
break ;
1126
1129
case RETRY_NEXT :
1127
1130
recordError (node , error );
1128
- trackNodeError (node , error );
1131
+ trackNodeError (node , error , null );
1129
1132
sendRequest (
1130
1133
verdict .getRetryRequest (statement ), null , executionIndex , retryCount + 1 , false );
1131
1134
break ;
1132
1135
case RETHROW :
1133
- trackNodeError (node , error );
1136
+ trackNodeError (node , error , null );
1134
1137
abort (error , true );
1135
1138
break ;
1136
1139
case IGNORE :
@@ -1443,12 +1446,20 @@ private void reenableAutoReadIfNeeded() {
1443
1446
1444
1447
// ERROR HANDLING
1445
1448
1446
- private void trackNodeError (@ NonNull Node node , @ NonNull Throwable error ) {
1449
+ private void trackNodeError (
1450
+ @ NonNull Node node , @ NonNull Throwable error , @ Nullable Frame frame ) {
1447
1451
if (nodeErrorReported .compareAndSet (false , true )) {
1448
1452
long latencyNanos = System .nanoTime () - this .messageStartTimeNanos ;
1449
1453
context
1450
1454
.getRequestTracker ()
1451
- .onNodeError (this .statement , error , latencyNanos , executionProfile , node , logPrefix );
1455
+ .onNodeError (
1456
+ this .statement ,
1457
+ error ,
1458
+ latencyNanos ,
1459
+ executionProfile ,
1460
+ node ,
1461
+ createExecutionInfo (frame ),
1462
+ logPrefix );
1452
1463
}
1453
1464
}
1454
1465
@@ -1562,21 +1573,32 @@ private void completeResultSetFuture(
1562
1573
if (resultSetClass .isInstance (pageOrError )) {
1563
1574
if (future .complete (resultSetClass .cast (pageOrError ))) {
1564
1575
throttler .signalSuccess (ContinuousRequestHandlerBase .this );
1576
+
1577
+ ExecutionInfo executionInfo = null ;
1578
+ if (pageOrError instanceof AsyncPagingIterable ) {
1579
+ executionInfo = ((AsyncPagingIterable ) pageOrError ).getExecutionInfo ();
1580
+ } else if (pageOrError instanceof AsyncGraphResultSet ) {
1581
+ executionInfo = ((AsyncGraphResultSet ) pageOrError ).getRequestExecutionInfo ();
1582
+ }
1583
+
1565
1584
if (nodeSuccessReported .compareAndSet (false , true )) {
1566
1585
context
1567
1586
.getRequestTracker ()
1568
- .onNodeSuccess (statement , nodeLatencyNanos , executionProfile , node , logPrefix );
1587
+ .onNodeSuccess (
1588
+ statement , nodeLatencyNanos , executionProfile , node , executionInfo , logPrefix );
1569
1589
}
1570
1590
context
1571
1591
.getRequestTracker ()
1572
- .onSuccess (statement , totalLatencyNanos , executionProfile , node , logPrefix );
1592
+ .onSuccess (
1593
+ statement , totalLatencyNanos , executionProfile , node , executionInfo , logPrefix );
1573
1594
}
1574
1595
} else {
1575
1596
Throwable error = (Throwable ) pageOrError ;
1576
1597
if (future .completeExceptionally (error )) {
1577
1598
context
1578
1599
.getRequestTracker ()
1579
- .onError (statement , error , totalLatencyNanos , executionProfile , node , logPrefix );
1600
+ .onError (
1601
+ statement , error , totalLatencyNanos , executionProfile , node , null , logPrefix );
1580
1602
if (error instanceof DriverTimeoutException ) {
1581
1603
throttler .signalTimeout (ContinuousRequestHandlerBase .this );
1582
1604
session
@@ -1607,6 +1629,22 @@ private ExecutionInfo createExecutionInfo(@NonNull Result result, @Nullable Fram
1607
1629
executionProfile );
1608
1630
}
1609
1631
1632
+ @ NonNull
1633
+ private ExecutionInfo createExecutionInfo (@ Nullable Frame response ) {
1634
+ return new DefaultExecutionInfo (
1635
+ statement ,
1636
+ node ,
1637
+ startedSpeculativeExecutionsCount .get (),
1638
+ executionIndex ,
1639
+ errors ,
1640
+ null ,
1641
+ response ,
1642
+ true ,
1643
+ session ,
1644
+ context ,
1645
+ executionProfile );
1646
+ }
1647
+
1610
1648
private void logTimeoutSchedulingError (IllegalStateException timeoutError ) {
1611
1649
// If we're racing with session shutdown, the timer might be stopped already. We don't want
1612
1650
// to schedule more executions anyway, so swallow the error.
0 commit comments