From e2106cc60fca476de0f7bf794d04a8df0352d410 Mon Sep 17 00:00:00 2001 From: Doug Hilpipre Date: Thu, 11 Sep 2025 07:52:58 -0500 Subject: [PATCH] fixed problems with Delay and CancellableContinuation --- ...lableContinuationImpl_Instrumentation.java | 65 +++++++ ...lableContinuationImpl_Instrumentation.java | 65 +++++++ .../NRDelayCancellableContinuation.java | 159 ------------------ ...lableContinuationImpl_Instrumentation.java | 65 +++++++ .../coroutines/Delay_Instrumentation.java | 7 +- settings.gradle | 2 +- 6 files changed, 199 insertions(+), 164 deletions(-) create mode 100644 Kotlin-Coroutines_1.4/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java create mode 100644 Kotlin-Coroutines_1.7/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java delete mode 100644 Kotlin-Coroutines_1.9/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_19/NRDelayCancellableContinuation.java create mode 100644 Kotlin-Coroutines_1.9/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java diff --git a/Kotlin-Coroutines_1.4/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java b/Kotlin-Coroutines_1.4/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java new file mode 100644 index 0000000..279800a --- /dev/null +++ b/Kotlin-Coroutines_1.4/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java @@ -0,0 +1,65 @@ +package kotlinx.coroutines; + +import com.newrelic.api.agent.Trace; +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; +import kotlin.Unit; +import kotlin.coroutines.CoroutineContext; +import kotlin.jvm.functions.Function1; +import kotlin.jvm.functions.Function3; + +@Weave(originalName = "kotlinx.coroutines.CancellableContinuationImpl") +public abstract class CancellableContinuationImpl_Instrumentation { + + @Trace + public void resumeWith(Object obj) { + Weaver.callOriginal(); + } + + @Trace + public java.lang.Object tryResumeWithException(Throwable t) { + + return Weaver.callOriginal(); + } + + @Trace + public Object tryResume(T t, Object o) { + return Weaver.callOriginal(); + } + + @Trace + public java.lang.Object tryResume(R r, Object obj, Function3 function3) { + return Weaver.callOriginal(); + } + + @Trace + public void completeResume(Object object) { + Weaver.callOriginal(); + } + + @Trace + public boolean cancel(Throwable t) { + return Weaver.callOriginal(); + } + + @Trace + public void invokeOnCancellation(Function1 function1) { + Weaver.callOriginal(); + } + + @Trace + public void resumeUndispatched(CoroutineDispatcher dispatcher, T t) { + Weaver.callOriginal(); + } + + @Trace + public void resumeUndispatchedWithException(CoroutineDispatcher dispatcher, Throwable t) { + Weaver.callOriginal(); + } + + @Trace + public void resume(R r, Function3 function3) { + Weaver.callOriginal(); + } +} diff --git a/Kotlin-Coroutines_1.7/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java b/Kotlin-Coroutines_1.7/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java new file mode 100644 index 0000000..279800a --- /dev/null +++ b/Kotlin-Coroutines_1.7/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java @@ -0,0 +1,65 @@ +package kotlinx.coroutines; + +import com.newrelic.api.agent.Trace; +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; +import kotlin.Unit; +import kotlin.coroutines.CoroutineContext; +import kotlin.jvm.functions.Function1; +import kotlin.jvm.functions.Function3; + +@Weave(originalName = "kotlinx.coroutines.CancellableContinuationImpl") +public abstract class CancellableContinuationImpl_Instrumentation { + + @Trace + public void resumeWith(Object obj) { + Weaver.callOriginal(); + } + + @Trace + public java.lang.Object tryResumeWithException(Throwable t) { + + return Weaver.callOriginal(); + } + + @Trace + public Object tryResume(T t, Object o) { + return Weaver.callOriginal(); + } + + @Trace + public java.lang.Object tryResume(R r, Object obj, Function3 function3) { + return Weaver.callOriginal(); + } + + @Trace + public void completeResume(Object object) { + Weaver.callOriginal(); + } + + @Trace + public boolean cancel(Throwable t) { + return Weaver.callOriginal(); + } + + @Trace + public void invokeOnCancellation(Function1 function1) { + Weaver.callOriginal(); + } + + @Trace + public void resumeUndispatched(CoroutineDispatcher dispatcher, T t) { + Weaver.callOriginal(); + } + + @Trace + public void resumeUndispatchedWithException(CoroutineDispatcher dispatcher, Throwable t) { + Weaver.callOriginal(); + } + + @Trace + public void resume(R r, Function3 function3) { + Weaver.callOriginal(); + } +} diff --git a/Kotlin-Coroutines_1.9/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_19/NRDelayCancellableContinuation.java b/Kotlin-Coroutines_1.9/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_19/NRDelayCancellableContinuation.java deleted file mode 100644 index 9ea9be0..0000000 --- a/Kotlin-Coroutines_1.9/src/main/java/com/newrelic/instrumentation/kotlin/coroutines_19/NRDelayCancellableContinuation.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.newrelic.instrumentation.kotlin.coroutines_19; - -import kotlin.jvm.functions.Function3; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Segment; - -import kotlin.Unit; -import kotlin.coroutines.CoroutineContext; -import kotlin.jvm.functions.Function1; -import kotlinx.coroutines.CancellableContinuation; -import kotlinx.coroutines.CoroutineDispatcher; - -/* - * Used to wrap the tracking of a call to the Coroutine delay function if tracking is enabled - * Will report the delay as a segment - */ -public class NRDelayCancellableContinuation implements CancellableContinuation { - - private final CancellableContinuation delegate; - private Segment segment; - - public NRDelayCancellableContinuation(CancellableContinuation delegate, String type) { - this.delegate = delegate; - String name = Utils.getContinuationString(delegate); - segment = NewRelic.getAgent().getTransaction().startSegment(type); - segment.addCustomAttribute("CancellableContinuation", name); - } - - @Override - public void resumeWith(@NotNull Object o) { - if(segment != null) { - segment.end(); - segment = null; - } - if(delegate != null) { - delegate.resumeWith(o); - } - } - - @Override - public @NotNull CoroutineContext getContext() { - return delegate.getContext(); - } - - @Override - public boolean isActive() { - return delegate.isActive(); - } - - @Override - public boolean isCompleted() { - return delegate.isCompleted(); - } - - @Override - public boolean isCancelled() { - return delegate.isCancelled(); - } - - @Override - public @Nullable Object tryResume(T t, @Nullable Object o) { - if(segment != null) { - segment.end(); - segment = null; - } - return delegate.tryResume(t,o); - } - - @Override - public @Nullable Object tryResumeWithException(@NotNull Throwable throwable) { - NewRelic.noticeError(throwable); - if(segment != null) { - segment.end(); - segment = null; - } - return delegate.tryResumeWithException(throwable); - } - - @Override - public void completeResume(@NotNull Object o) { - if(segment != null) { - segment.end(); - segment = null; - } - delegate.completeResume(o); - } - - @Override - public void initCancellability() { - delegate.initCancellability(); - } - - @Override - public boolean cancel(@Nullable Throwable throwable) { - if(segment != null) { - segment.end(); - segment = null; - } - return delegate.cancel(throwable); - } - - @Override - public void invokeOnCancellation(@NotNull Function1 function1) { - if(segment != null) { - segment.end(); - segment = null; - } - delegate.invokeOnCancellation(function1); - } - - @Override - public void resumeUndispatched(@NotNull CoroutineDispatcher coroutineDispatcher, T t) { - if(segment != null) { - segment.end(); - segment = null; - } - delegate.resumeUndispatched(coroutineDispatcher, t); - } - - @Override - public void resumeUndispatchedWithException(@NotNull CoroutineDispatcher coroutineDispatcher, @NotNull Throwable throwable) { - if(segment != null) { - segment.end(); - segment = null; - } - delegate.resumeUndispatchedWithException(coroutineDispatcher, throwable); - } - - @SuppressWarnings("deprecation") - @Override - public void resume(T t, @Nullable Function1 function1) { - if(segment != null) { - segment.end(); - segment = null; - } - delegate.resume(t,function1); - } - - @Override - public @Nullable Object tryResume(R r, @Nullable Object o,@Nullable Function3 function3) { - if(segment != null) { - segment.end(); - segment = null; - } - return delegate.tryResume(r,o,function3); - } - - @Override - public void resume(R r, @Nullable Function3 function3) { - if(segment != null) { - segment.end(); - segment = null; - } - delegate.resume(r,function3); - } -} diff --git a/Kotlin-Coroutines_1.9/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java b/Kotlin-Coroutines_1.9/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java new file mode 100644 index 0000000..279800a --- /dev/null +++ b/Kotlin-Coroutines_1.9/src/main/java/kotlinx/coroutines/CancellableContinuationImpl_Instrumentation.java @@ -0,0 +1,65 @@ +package kotlinx.coroutines; + +import com.newrelic.api.agent.Trace; +import com.newrelic.api.agent.weaver.MatchType; +import com.newrelic.api.agent.weaver.Weave; +import com.newrelic.api.agent.weaver.Weaver; +import kotlin.Unit; +import kotlin.coroutines.CoroutineContext; +import kotlin.jvm.functions.Function1; +import kotlin.jvm.functions.Function3; + +@Weave(originalName = "kotlinx.coroutines.CancellableContinuationImpl") +public abstract class CancellableContinuationImpl_Instrumentation { + + @Trace + public void resumeWith(Object obj) { + Weaver.callOriginal(); + } + + @Trace + public java.lang.Object tryResumeWithException(Throwable t) { + + return Weaver.callOriginal(); + } + + @Trace + public Object tryResume(T t, Object o) { + return Weaver.callOriginal(); + } + + @Trace + public java.lang.Object tryResume(R r, Object obj, Function3 function3) { + return Weaver.callOriginal(); + } + + @Trace + public void completeResume(Object object) { + Weaver.callOriginal(); + } + + @Trace + public boolean cancel(Throwable t) { + return Weaver.callOriginal(); + } + + @Trace + public void invokeOnCancellation(Function1 function1) { + Weaver.callOriginal(); + } + + @Trace + public void resumeUndispatched(CoroutineDispatcher dispatcher, T t) { + Weaver.callOriginal(); + } + + @Trace + public void resumeUndispatchedWithException(CoroutineDispatcher dispatcher, Throwable t) { + Weaver.callOriginal(); + } + + @Trace + public void resume(R r, Function3 function3) { + Weaver.callOriginal(); + } +} diff --git a/Kotlin-Coroutines_1.9/src/main/java/kotlinx/coroutines/Delay_Instrumentation.java b/Kotlin-Coroutines_1.9/src/main/java/kotlinx/coroutines/Delay_Instrumentation.java index 2137b85..2793d1d 100644 --- a/Kotlin-Coroutines_1.9/src/main/java/kotlinx/coroutines/Delay_Instrumentation.java +++ b/Kotlin-Coroutines_1.9/src/main/java/kotlinx/coroutines/Delay_Instrumentation.java @@ -1,16 +1,18 @@ package kotlinx.coroutines; +import com.newrelic.api.agent.NewRelic; import com.newrelic.api.agent.Trace; import com.newrelic.api.agent.weaver.MatchType; import com.newrelic.api.agent.weaver.Weave; import com.newrelic.api.agent.weaver.Weaver; -import com.newrelic.instrumentation.kotlin.coroutines_19.NRDelayCancellableContinuation; import com.newrelic.instrumentation.kotlin.coroutines_19.NRDelayContinuation; import com.newrelic.instrumentation.kotlin.coroutines_19.Utils; import kotlin.Unit; import kotlin.coroutines.Continuation; import kotlin.coroutines.CoroutineContext; +import java.util.logging.Level; + @Weave(type = MatchType.Interface, originalName = "kotlinx.coroutines.Delay") public class Delay_Instrumentation { @@ -24,9 +26,6 @@ public Object delay(long timeMills, Continuation continuation) { @Trace public void scheduleResumeAfterDelay(long timeMills, CancellableContinuation continuation) { - if(Utils.DELAYED_ENABLED && !(continuation instanceof NRDelayContinuation)) { - continuation = new NRDelayCancellableContinuation<>(continuation,"scheduleResumeAfterDelay"); - } Weaver.callOriginal(); } diff --git a/settings.gradle b/settings.gradle index 0f268f4..4e38b63 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,4 @@ -rootProject.name = 'java-instrumentation-template' +rootProject.name = 'kotlin-coroutines' include 'Kotlin-Coroutines_1.0' include 'Kotlin-Coroutines_1.1' include 'Kotlin-Coroutines_1.2'