-
Notifications
You must be signed in to change notification settings - Fork 566
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improved handling of Jaeger spans/scopes across threads (#3134)
* Improved handling of Jaeger spans/scopes across threads. Fixes problems with MP async calls that resulted in memory leaks of ThreadLocalScope objects due to the failed attempt to close a scope from a different thread. New implementation uses a DataPropagationProvider to close a scope on the primary thread and re-open it on the secondary thread --and eventually close it there as well. Minor change to the DataPropagationProvider spi. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com> * Deprecated rather than remove old clearData() method to ensure backward compatibility of the SPI. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com> * Fixed adding default to deprecated method. Signed-off-by: Santiago Pericasgeertsen <santiago.pericasgeertsen@oracle.com>
- Loading branch information
Showing
11 changed files
with
320 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
common/context/src/test/java/io/helidon/common/context/DataPropagationProviderTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright (c) 2021 Oracle and/or its affiliates. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.helidon.common.context; | ||
|
||
import io.helidon.common.context.spi.DataPropagationProvider; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.CoreMatchers.is; | ||
|
||
/** | ||
* Verifies backward compatibility of SPI after method deprecation. | ||
*/ | ||
class DataPropagationProviderTest { | ||
|
||
private boolean called = false; | ||
|
||
class MyDataPropagationTest implements DataPropagationProvider<Object> { | ||
|
||
@Override | ||
public Object data() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public void propagateData(Object data) { | ||
} | ||
|
||
/** | ||
* Deprecated method should be called. | ||
*/ | ||
@Override | ||
public void clearData() { | ||
called = true; | ||
} | ||
} | ||
|
||
@Test | ||
void testDeprecation() { | ||
MyDataPropagationTest dpt = new MyDataPropagationTest(); | ||
dpt.clearData("foo"); // should call deprecated method | ||
assertThat(called, is(true)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
tracing/jaeger/src/main/java/io/helidon/tracing/jaeger/JaegerDataPropagationProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/* | ||
* Copyright (c) 2021 Oracle and/or its affiliates. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.helidon.tracing.jaeger; | ||
|
||
import io.helidon.common.context.Contexts; | ||
import io.helidon.common.context.spi.DataPropagationProvider; | ||
|
||
import io.opentracing.Scope; | ||
import io.opentracing.Span; | ||
import io.opentracing.Tracer; | ||
import io.opentracing.util.GlobalTracer; | ||
|
||
/** | ||
* A data propagation provider for Jaeger. Makes sure span are properly propagated | ||
* across threads managed by {@link io.helidon.common.context.ContextAwareExecutorService}. | ||
*/ | ||
public class JaegerDataPropagationProvider implements DataPropagationProvider<JaegerDataPropagationProvider.JaegerContext> { | ||
|
||
static class JaegerContext { | ||
private final Span span; | ||
private final Tracer tracer; | ||
private Scope scope; | ||
|
||
JaegerContext(Tracer tracer, Span span) { | ||
this.tracer = tracer; | ||
this.span = span; | ||
} | ||
|
||
Scope scope() { | ||
return scope; | ||
} | ||
} | ||
|
||
/** | ||
* Closes scope in primary thread and returns a context to activate | ||
* new scope in secondary thread. | ||
* | ||
* @return active span. | ||
*/ | ||
@Override | ||
public JaegerContext data() { | ||
return Contexts.context().map(context -> { | ||
context.get(Scope.class).ifPresent(Scope::close); | ||
return context.get(Span.class).map(span -> { | ||
Tracer tracer = context.get(Tracer.class).orElseGet(GlobalTracer::get); | ||
return new JaegerContext(tracer, span); | ||
}).orElse(null); | ||
}).orElse(null); | ||
} | ||
|
||
/** | ||
* Activates scope in secondary thread. | ||
* | ||
* @param context the context. | ||
*/ | ||
@Override | ||
public void propagateData(JaegerContext context) { | ||
if (context != null) { | ||
context.scope = context.tracer.scopeManager().activate(context.span); | ||
} | ||
} | ||
|
||
/** | ||
* Closes scope in secondary thread. | ||
*/ | ||
@Override | ||
public void clearData(JaegerContext context) { | ||
if (context != null && context.scope != null) { | ||
context.scope.close(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.