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