Skip to content

Commit e810d4a

Browse files
committed
fixed problems related to unexpired async tokens
1 parent de85019 commit e810d4a

File tree

9 files changed

+93
-33
lines changed

9 files changed

+93
-33
lines changed

Kotlin-Coroutines_1.1/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jar {
2222
}
2323

2424
verifyInstrumentation {
25-
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core:[1.1.0,1.1.1]'
25+
passes 'org.jetbrains.kotlinx:kotlinx-coroutines-core:[1.1.0,1.2.0]'
2626
excludeRegex '.*SNAPSHOT'
2727
excludeRegex '.*alpha'
2828
excludeRegex '.*eap.*'
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import com.newrelic.api.agent.Token;
55
import com.newrelic.api.agent.Trace;
66

7-
public class NRWrappedRunnable implements Runnable {
7+
public class NRRunnable implements Runnable {
88

99

1010
private static boolean isTranformed = false;
@@ -16,7 +16,7 @@ public void expireAndNullToken() {
1616
token = null;
1717
}
1818

19-
public NRWrappedRunnable(Runnable d, Token t) {
19+
public NRRunnable(Runnable d, Token t) {
2020
token = t;
2121
delegate = d;
2222
if(!isTranformed) {

Kotlin-Coroutines_1.1/src/main/java/kotlinx/coroutines/CoroutineDispatcher.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import com.newrelic.api.agent.weaver.MatchType;
66
import com.newrelic.api.agent.weaver.Weave;
77
import com.newrelic.api.agent.weaver.Weaver;
8-
import com.nr.instrumentation.kotlin.coroutines.NRWrappedRunnable;
8+
import com.nr.instrumentation.kotlin.coroutines.NRRunnable;
99

1010
import kotlin.coroutines.CoroutineContext;;
1111

@@ -14,8 +14,8 @@ public abstract class CoroutineDispatcher {
1414

1515
@Trace(excludeFromTransactionTrace=true)
1616
public void dispatch(CoroutineContext ctx, Runnable r) {
17-
if(!NRWrappedRunnable.class.isInstance(r)) {
18-
NRWrappedRunnable wrapper = new NRWrappedRunnable(r, NewRelic.getAgent().getTransaction().getToken());
17+
if(!NRRunnable.class.isInstance(r)) {
18+
NRRunnable wrapper = new NRRunnable(r, NewRelic.getAgent().getTransaction().getToken());
1919
r = wrapper;
2020
}
2121
Weaver.callOriginal();

Kotlin-Coroutines_1.1/src/main/java/kotlinx/coroutines/EventLoopImplBase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
import com.newrelic.api.agent.weaver.MatchType;
66
import com.newrelic.api.agent.weaver.Weave;
77
import com.newrelic.api.agent.weaver.Weaver;
8-
import com.nr.instrumentation.kotlin.coroutines.NRWrappedRunnable;
8+
import com.nr.instrumentation.kotlin.coroutines.NRRunnable;
99

1010
@Weave(type=MatchType.BaseClass)
1111
public abstract class EventLoopImplBase {
1212

1313
@SuppressWarnings("unused")
1414
private boolean enqueueImpl(Runnable r) {
1515
Token token = NewRelic.getAgent().getTransaction().getToken();
16-
NRWrappedRunnable wrapper = new NRWrappedRunnable(r, token);
16+
NRRunnable wrapper = new NRRunnable(r, token);
1717
r = wrapper;
1818
boolean b = Weaver.callOriginal();
1919
if(!b) {
Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
package kotlinx.coroutines;
22

3-
import java.util.concurrent.ScheduledFuture;
4-
import java.util.concurrent.TimeUnit;
5-
6-
import com.newrelic.api.agent.Trace;
3+
import com.newrelic.api.agent.NewRelic;
4+
import com.newrelic.api.agent.Token;
75
import com.newrelic.api.agent.weaver.MatchType;
86
import com.newrelic.api.agent.weaver.Weave;
97
import com.newrelic.api.agent.weaver.Weaver;
8+
import com.nr.instrumentation.kotlin.coroutines.NRRunnable;
109

11-
import kotlin.Unit;
10+
import kotlin.coroutines.CoroutineContext;
1211

1312
@Weave(type=MatchType.BaseClass)
1413
public abstract class ExecutorCoroutineDispatcherBase {
1514

16-
@Trace(dispatcher=true)
17-
public abstract void scheduleResumeAfterDelay(long timeInMS, CancellableContinuation<? super Unit> f);
18-
@Trace(dispatcher=true)
19-
public abstract DisposableHandle invokeOnTimeout(long ms, Runnable r);
20-
@Trace(dispatcher=true)
21-
private ScheduledFuture<?> scheduleBlock(Runnable r, long ms, TimeUnit tu) {
22-
return Weaver.callOriginal();
23-
}
15+
16+
public void dispatch(CoroutineContext context, Runnable block) {
17+
if(!(block instanceof NRRunnable)) {
18+
Token t = NewRelic.getAgent().getTransaction().getToken();
19+
if(t != null && t.isActive()) {
20+
NRRunnable wrapper = new NRRunnable(block, t);
21+
block = wrapper;
22+
} else if(t != null) {
23+
t.expire();
24+
}
25+
}
26+
Weaver.callOriginal();
27+
}
2428
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package kotlinx.coroutines.scheduling;
2+
3+
import com.newrelic.api.agent.NewRelic;
4+
import com.newrelic.api.agent.Token;
5+
import com.newrelic.api.agent.weaver.Weave;
6+
import com.newrelic.api.agent.weaver.Weaver;
7+
import com.nr.instrumentation.kotlin.coroutines.NRRunnable;
8+
9+
import kotlin.coroutines.CoroutineContext;
10+
11+
@Weave
12+
public abstract class ExperimentalCoroutineDispatcher {
13+
14+
public void dispatch(CoroutineContext context, Runnable block) {
15+
if(!(block instanceof NRRunnable)) {
16+
Token t = NewRelic.getAgent().getTransaction().getToken();
17+
if(t != null && t.isActive()) {
18+
NRRunnable wrapper = new NRRunnable(block, t);
19+
block = wrapper;
20+
} else if(t != null) {
21+
t.expire();
22+
}
23+
}
24+
Weaver.callOriginal();
25+
}
26+
27+
}
Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,39 @@
11
package com.newrelic.instrumentation.kotlin.coroutines;
2-
32
import com.newrelic.agent.bridge.AgentBridge;
3+
import com.newrelic.api.agent.NewRelic;
44
import com.newrelic.api.agent.Token;
55
import com.newrelic.api.agent.Trace;
66

77
public class NRRunnable implements Runnable {
88

9+
10+
private static boolean isTranformed = false;
911
private Runnable delegate = null;
1012
private Token token = null;
11-
private static boolean isTransformed = false;
1213

14+
public void expireAndNullToken() {
15+
token.expire();
16+
token = null;
17+
}
1318

14-
public NRRunnable(Runnable r, Token t) {
15-
delegate = r;
19+
public NRRunnable(Runnable d, Token t) {
1620
token = t;
17-
if(!isTransformed) {
18-
isTransformed = true;
21+
delegate = d;
22+
if(!isTranformed) {
1923
AgentBridge.instrumentation.retransformUninstrumentedClass(getClass());
24+
isTranformed = true;
2025
}
2126
}
2227

2328
@Override
2429
@Trace(async=true)
2530
public void run() {
31+
NewRelic.getAgent().getTracedMethod().setMetricName("Custom","DispatchedTask",delegate.getClass().getSimpleName(),"run");
2632
if(token != null) {
2733
token.linkAndExpire();
2834
token = null;
2935
}
30-
if(delegate != null) {
31-
delegate.run();
32-
}
36+
delegate.run();
3337
}
3438

3539
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package kotlinx.coroutines;
2+
3+
import com.newrelic.api.agent.NewRelic;
4+
import com.newrelic.api.agent.Token;
5+
import com.newrelic.api.agent.weaver.MatchType;
6+
import com.newrelic.api.agent.weaver.Weave;
7+
import com.newrelic.api.agent.weaver.Weaver;
8+
import com.newrelic.instrumentation.kotlin.coroutines.NRRunnable;
9+
10+
@Weave(type=MatchType.BaseClass)
11+
public abstract class EventLoopImplBase {
12+
13+
@SuppressWarnings("unused")
14+
private boolean enqueueImpl(Runnable r) {
15+
Token token = NewRelic.getAgent().getTransaction().getToken();
16+
NRRunnable wrapper = new NRRunnable(r, token);
17+
r = wrapper;
18+
boolean b = Weaver.callOriginal();
19+
if(!b) {
20+
wrapper.expireAndNullToken();
21+
}
22+
return b;
23+
24+
}
25+
}

settings.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ rootProject.name = 'java-instrumentation-template'
1111
include 'Kotlin-Coroutines_1.0'
1212
include 'Kotlin-Coroutines_1.1'
1313
include 'Kotlin-Coroutines_1.2'
14-
include 'Kotlin-Coroutines_1.3'
15-
include 'Kotlin-Coroutines_1.3.3'
16-
include 'Kotlin-Coroutines_1.4'
14+
include 'kroto-plus-coroutines'
15+
include 'kotlin-coroutines-reactor'
16+
include 'kotlin-coroutines-reactor'

0 commit comments

Comments
 (0)