Skip to content

Commit c181059

Browse files
Fixed small perf overhead due to NPE for readItem returning 404 (Azure#44008)
* Addressing NPE for readItem returning 404 * Update CHANGELOG.md * Update SparkE2EGatewayChangeFeedITest.scala
1 parent e22d399 commit c181059

File tree

7 files changed

+93
-7
lines changed

7 files changed

+93
-7
lines changed

sdk/cosmos/azure-cosmos-spark_3_2-12/src/test/scala/com/azure/cosmos/spark/SparkE2EGatewayChangeFeedITest.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ class SparkE2EGatewayChangeFeedITest
116116
assertMetrics(meterRegistry, "cosmos.client.op.latency", expectedToFind = true)
117117
assertMetrics(meterRegistry, "cosmos.client.system.avgCpuLoad", expectedToFind = true)
118118
assertMetrics(meterRegistry, "cosmos.client.req.gw", expectedToFind = true)
119-
assertMetrics(meterRegistry, "cosmos.client.req.rntbd", expectedToFind = false)
120119
}
121120
//scalastyle:on magic.number
122121
//scalastyle:on multiple.string.literals

sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/ClientMetricsTest.java

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.azure.cosmos.implementation.AsyncDocumentClient;
1010
import com.azure.cosmos.implementation.Configs;
1111
import com.azure.cosmos.implementation.ConsoleLoggingRegistryFactory;
12+
import com.azure.cosmos.implementation.DiagnosticsProvider;
1213
import com.azure.cosmos.implementation.GlobalEndpointManager;
1314
import com.azure.cosmos.implementation.ImplementationBridgeHelpers;
1415
import com.azure.cosmos.implementation.InternalObjectNode;
@@ -88,6 +89,8 @@ public class ClientMetricsTest extends BatchTestBase {
8889
private CosmosClientTelemetryConfig inputClientTelemetryConfig;
8990
private CosmosMicrometerMetricsOptions inputMetricsOptions;
9091
private Tag clientCorrelationTag;
92+
private long diagnosticHandlerFailuresBaseline;
93+
private DiagnosticsProvider diagnosticsProvider;
9194

9295
@Factory(dataProvider = "clientBuildersWithDirectTcpSession")
9396
public ClientMetricsTest(CosmosClientBuilder clientBuilder) {
@@ -113,7 +116,6 @@ public void beforeTest(
113116
assertThat(this.meterRegistry).isNull();
114117

115118
this.meterRegistry = ConsoleLoggingRegistryFactory.create(1);
116-
117119
this.inputMetricsOptions = new CosmosMicrometerMetricsOptions()
118120
.meterRegistry(this.meterRegistry)
119121
.setMetricCategories(metricCategories)
@@ -137,6 +139,9 @@ public void beforeTest(
137139
.clientTelemetryConfig(inputClientTelemetryConfig)
138140
.buildClient();
139141

142+
this.diagnosticsProvider = ReflectionUtils.getDiagnosticsProvider(client.asyncClient());
143+
this.diagnosticHandlerFailuresBaseline = diagnosticsProvider.getDiagnosticHandlerFailuresSnapshot();
144+
140145
assertThat(
141146
ImplementationBridgeHelpers
142147
.CosmosAsyncClientHelper
@@ -162,6 +167,10 @@ public void beforeTest(
162167
}
163168

164169
public void afterTest() {
170+
if (this.diagnosticsProvider != null) {
171+
assertThat(this.diagnosticsProvider.getDiagnosticHandlerFailuresSnapshot())
172+
.isEqualTo(this.diagnosticHandlerFailuresBaseline);
173+
}
165174
this.container = null;
166175
CosmosClient clientSnapshot = this.client;
167176
if (clientSnapshot != null) {
@@ -414,6 +423,38 @@ public void readItem() throws Exception {
414423
}
415424
}
416425

426+
@Test(groups = { "fast" }, timeOut = TIMEOUT)
427+
public void readNonExistingItem() throws Exception {
428+
this.beforeTest(CosmosMetricCategory.DEFAULT);
429+
try {
430+
431+
try {
432+
container.readItem(
433+
UUID.randomUUID().toString(),
434+
new PartitionKey(UUID.randomUUID().toString()),
435+
new CosmosItemRequestOptions(),
436+
InternalObjectNode.class);
437+
} catch (CosmosException expectedError) {
438+
assertThat(expectedError.getStatusCode()).isEqualTo(404);
439+
assertThat(expectedError.getSubStatusCode()).isEqualTo(0);
440+
}
441+
442+
this.validateMetrics(
443+
Tag.of(
444+
TagName.Operation.toString(), "Document/Read"),
445+
Tag.of(TagName.RequestOperationType.toString(), "Document/Read"),
446+
0,
447+
500
448+
);
449+
450+
Tag queryPlanTag = Tag.of(TagName.RequestOperationType.toString(), "DocumentCollection_QueryPlan");
451+
this.assertMetrics("cosmos.client.req.gw", false, queryPlanTag);
452+
this.assertMetrics("cosmos.client.req.rntbd", false, queryPlanTag);
453+
} finally {
454+
this.afterTest();
455+
}
456+
}
457+
417458
@Test(groups = { "fast" }, timeOut = TIMEOUT)
418459
public void readManySingleItem() throws Exception {
419460
this.beforeTest(CosmosMetricCategory.DEFAULT);

sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/CosmosTracerTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,36 @@ public void cosmosAsyncContainer(
911911
mockTracer.reset();
912912
}
913913

914+
@Test(groups = { "fast", "simple" }, timeOut = 10 * TIMEOUT)
915+
public void readItemWith404() {
916+
ITEM_ID = "tracerDoc_" + testCaseCount.incrementAndGet();
917+
TracerUnderTest mockTracer = Mockito.spy(new TracerUnderTest());
918+
919+
DiagnosticsProvider provider = createAndInitializeDiagnosticsProvider(
920+
mockTracer,
921+
false,
922+
true,
923+
ShowQueryMode.NONE,
924+
false,
925+
1);
926+
927+
long diagnosticHandlerFailuresBaseline = provider.getDiagnosticHandlerFailuresSnapshot();
928+
try {
929+
cosmosAsyncContainer
930+
.readItem(ITEM_ID, new PartitionKey(ITEM_ID), null, ObjectNode.class)
931+
.block();
932+
933+
fail("404 Expected");
934+
} catch (CosmosException cosmosException) {
935+
assertThat(cosmosException.getStatusCode()).isEqualTo(404);
936+
}
937+
938+
assertThat(provider.getDiagnosticHandlerFailuresSnapshot())
939+
.isEqualTo(diagnosticHandlerFailuresBaseline);
940+
941+
mockTracer.reset();
942+
}
943+
914944
@Test(groups = { "fast", "simple" }, dataProvider = "traceTestCaseProvider", timeOut = TIMEOUT)
915945
public void cosmosAsyncScripts(
916946
boolean useLegacyTracing,

sdk/cosmos/azure-cosmos-tests/src/test/java/com/azure/cosmos/implementation/directconnectivity/ReflectionUtils.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,13 @@ public static void setDiagnosticsProvider(CosmosAsyncClient cosmosAsyncClient, D
187187
set(cosmosAsyncClient, tracerProvider, "diagnosticsProvider");
188188
}
189189

190+
public static DiagnosticsProvider getDiagnosticsProvider(CosmosAsyncClient cosmosAsyncClient){
191+
return get(
192+
DiagnosticsProvider.class,
193+
cosmosAsyncClient,
194+
"diagnosticsProvider");
195+
}
196+
190197
public static void setClientTelemetryConfig(CosmosAsyncClient cosmosAsyncClient, CosmosClientTelemetryConfig cfg){
191198
set(cosmosAsyncClient, cfg, "clientTelemetryConfig");
192199
AsyncDocumentClient asyncClient = get(

sdk/cosmos/azure-cosmos/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
#### Breaking Changes
88

99
#### Bugs Fixed
10-
* Fixes an issue in change feed processor where records are skipped and excessive requests are prefetched. - See [PR 43788](https://github.com/Azure/azure-sdk-for-java/pull/43788)
10+
* Fixed an issue in change feed processor where records are skipped and excessive requests are prefetched. - See [PR 43788](https://github.com/Azure/azure-sdk-for-java/pull/43788)
11+
* Fixed small perf overhead due to NPE for readItem returning 404. - See [PR 44008](https://github.com/Azure/azure-sdk-for-java/pull/44008)
1112
* Perform cross-region retry for `Document` reads when enclosing address requests hit request timeouts (408:10002). - See [PR 43937](https://github.com/Azure/azure-sdk-for-java/pull/43937)
1213

1314
#### Other Changes

sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/DiagnosticsProvider.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ public final class DiagnosticsProvider {
107107
private final CosmosClientTelemetryConfig telemetryConfig;
108108
private final boolean shouldSystemExitOnError;
109109

110+
private final AtomicLong diagnosticsHandlerFailures = new AtomicLong(0);
111+
110112
final Supplier<Double> samplingRateSnapshotSupplier;
111113

112114

@@ -210,6 +212,10 @@ public static Context getContextFromReactorOrNull(ContextView reactorContext) {
210212
return null;
211213
}
212214

215+
public long getDiagnosticHandlerFailuresSnapshot() {
216+
return this.diagnosticsHandlerFailures.get();
217+
}
218+
213219
/**
214220
* Stores {@link Context} in Reactor {@link reactor.util.context.Context}.
215221
*
@@ -538,6 +544,7 @@ private void handleDiagnostics(Context context, CosmosDiagnosticsContext cosmosC
538544
try {
539545
handler.handleDiagnostics(cosmosCtx, context);
540546
} catch (Exception e) {
547+
this.diagnosticsHandlerFailures.incrementAndGet();
541548
LOGGER.error("HandledDiagnostics failed. ", e);
542549
}
543550
}
@@ -1698,6 +1705,7 @@ private void handleErrors(Throwable throwable, int systemExitCode) {
16981705
if (throwable instanceof Error) {
16991706
handleFatalError((Error) throwable, systemExitCode);
17001707
} else {
1708+
this.diagnosticsHandlerFailures.incrementAndGet();
17011709
LOGGER.error("Unexpected exception in DiagnosticsProvider.endSpan. ", throwable);
17021710
throw new RuntimeException(throwable);
17031711
}

sdk/cosmos/azure-cosmos/src/main/java/com/azure/cosmos/implementation/clienttelemetry/ClientTelemetryMetrics.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,10 @@ private static void recordOperation(
269269
latency,
270270
maxItemCount == null ? -1 : maxItemCount,
271271
actualItemCount == null ? -1: actualItemCount,
272-
opCountPerEvaluation,
273-
opRetriedCountPerEvaluation,
274-
globalOpCount,
275-
targetMaxMicroBatchSize,
272+
opCountPerEvaluation == null ? 0 : opCountPerEvaluation,
273+
opRetriedCountPerEvaluation == null ? 0 : opRetriedCountPerEvaluation,
274+
globalOpCount == null ? 0 : globalOpCount,
275+
targetMaxMicroBatchSize == null ? 0 : targetMaxMicroBatchSize,
276276
diagnosticsContext,
277277
contactedRegions
278278
);

0 commit comments

Comments
 (0)