Skip to content

Commit 55cee78

Browse files
committed
fix(tracing): make CompositeScope.close idempotent and clear references
1 parent 5a3fb6b commit 55cee78

2 files changed

Lines changed: 32 additions & 7 deletions

File tree

‎sdk-platform-java/gax-java/gax/src/main/java/com/google/api/gax/tracing/CompositeTracer.java‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,17 @@ private static class CompositeScope implements Scope {
116116
public void close() {
117117
Throwable firstException = null;
118118
for (int i = count - 1; i >= 0; i--) {
119-
try {
120-
scopes[i].close();
121-
} catch (Throwable t) {
122-
if (firstException == null) {
123-
firstException = t;
124-
} else if (firstException != t) {
125-
firstException.addSuppressed(t);
119+
Scope scope = scopes[i];
120+
if (scope != null) {
121+
scopes[i] = null;
122+
try {
123+
scope.close();
124+
} catch (Throwable t) {
125+
if (firstException == null) {
126+
firstException = t;
127+
} else if (firstException != t) {
128+
firstException.addSuppressed(t);
129+
}
126130
}
127131
}
128132
}

‎sdk-platform-java/gax-java/gax/src/test/java/com/google/api/gax/tracing/CompositeTracerTest.java‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import static org.mockito.Mockito.doThrow;
3636
import static org.mockito.Mockito.inOrder;
3737
import static org.mockito.Mockito.mock;
38+
import static org.mockito.Mockito.times;
3839
import static org.mockito.Mockito.verify;
3940
import static org.mockito.Mockito.when;
4041

@@ -125,6 +126,26 @@ void testInScope_childScopeCloseThrows() {
125126
inOrder.verify(scope1).close();
126127
}
127128

129+
@Test
130+
void testInScope_compositeScopeClose_isIdempotent() {
131+
ApiTracer.Scope scope1 =
132+
mock(ApiTracer.Scope.class, Mockito.withSettings().withoutAnnotations());
133+
ApiTracer.Scope scope2 =
134+
mock(ApiTracer.Scope.class, Mockito.withSettings().withoutAnnotations());
135+
136+
when(child1.inScope()).thenReturn(scope1);
137+
when(child2.inScope()).thenReturn(scope2);
138+
139+
ApiTracer.Scope compositeScope = compositeTracer.inScope();
140+
141+
compositeScope.close();
142+
// Subsequent close should be idempotent and not invoke underlying scopes again
143+
compositeScope.close();
144+
145+
verify(scope2, times(1)).close();
146+
verify(scope1, times(1)).close();
147+
}
148+
128149
@Test
129150
void testOperationSucceeded() {
130151
compositeTracer.operationSucceeded();

0 commit comments

Comments
 (0)