Skip to content

Commit c1898f3

Browse files
authored
Switching to use Span concurrent map in Scala plugin (#2323)
1 parent d7751ba commit c1898f3

File tree

1 file changed

+7
-10
lines changed

1 file changed

+7
-10
lines changed

apm-agent-plugins/apm-scala-concurrent-plugin/src/main/java/co/elastic/apm/agent/scalaconcurrent/FutureInstrumentation.java

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
package co.elastic.apm.agent.scalaconcurrent;
2020

2121
import co.elastic.apm.agent.bci.TracerAwareInstrumentation;
22+
import co.elastic.apm.agent.collections.WeakConcurrentProviderImpl;
2223
import co.elastic.apm.agent.impl.transaction.AbstractSpan;
23-
import co.elastic.apm.agent.sdk.weakconcurrent.WeakConcurrent;
2424
import co.elastic.apm.agent.sdk.weakconcurrent.WeakMap;
2525
import net.bytebuddy.asm.Advice;
2626
import net.bytebuddy.description.method.MethodDescription;
@@ -39,8 +39,7 @@
3939
public abstract class FutureInstrumentation extends TracerAwareInstrumentation {
4040

4141
@SuppressWarnings("WeakerAccess")
42-
public static final WeakMap<Object, AbstractSpan<?>> promisesToContext =
43-
WeakConcurrent.buildMap();
42+
public static final WeakMap<Object, AbstractSpan<?>> promisesToContext = WeakConcurrentProviderImpl.createWeakSpanMap();
4443

4544
@Nonnull
4645
@Override
@@ -66,9 +65,6 @@ public static void onExit(@Advice.This Object thiz) {
6665
final AbstractSpan<?> context = tracer.getActive();
6766
if (context != null) {
6867
promisesToContext.put(thiz, context);
69-
// this span might be ended before the Promise$Transformation#run method starts
70-
// we have to avoid that this span gets recycled, even in the above mentioned case
71-
context.incrementReferences();
7268
}
7369
}
7470
}
@@ -91,12 +87,13 @@ public static class AdviceClass {
9187
@Nullable
9288
@Advice.OnMethodEnter(suppress = Throwable.class, inline = false)
9389
public static Object onEnter(@Advice.This Object thiz) {
94-
AbstractSpan<?> context = promisesToContext.remove(thiz);
90+
// We cannot remove yet, as this may decrement the ref count of the span to 0 if it has already ended,
91+
// thus causing it to be recycled just before we activate it on the current thread. So we first get().
92+
AbstractSpan<?> context = promisesToContext.get(thiz);
9593
if (context != null) {
9694
context.activate();
97-
// decrements the reference we incremented to avoid that the parent context gets recycled before the promise is run
98-
// because we have activated it, we can be sure it doesn't get recycled until we deactivate in the OnMethodExit advice
99-
context.decrementReferences();
95+
// Now it's safe to remove, as ref count is at least 2
96+
promisesToContext.remove(thiz);
10097
}
10198
return context;
10299
}

0 commit comments

Comments
 (0)