Skip to content

Commit de85019

Browse files
committed
changed where token is created
1 parent c0f2b1d commit de85019

File tree

7 files changed

+219
-28
lines changed

7 files changed

+219
-28
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.newrelic.instrumentation.kotlin.coroutines;
2+
3+
import com.newrelic.agent.bridge.AgentBridge;
4+
import com.newrelic.api.agent.Token;
5+
import com.newrelic.api.agent.Trace;
6+
7+
public class NRRunnable implements Runnable {
8+
9+
private Runnable delegate = null;
10+
private Token token = null;
11+
private static boolean isTransformed = false;
12+
13+
14+
public NRRunnable(Runnable r, Token t) {
15+
delegate = r;
16+
token = t;
17+
if(!isTransformed) {
18+
isTransformed = true;
19+
AgentBridge.instrumentation.retransformUninstrumentedClass(getClass());
20+
}
21+
}
22+
23+
@Override
24+
@Trace(async=true)
25+
public void run() {
26+
if(token != null) {
27+
token.linkAndExpire();
28+
token = null;
29+
}
30+
if(delegate != null) {
31+
delegate.run();
32+
}
33+
}
34+
35+
}
Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
package kotlinx.coroutines;
22

3-
import com.newrelic.api.agent.NewRelic;
4-
import com.newrelic.api.agent.Token;
5-
import com.newrelic.api.agent.Trace;
3+
//import com.newrelic.api.agent.NewRelic;
4+
//import com.newrelic.api.agent.Token;
5+
//import com.newrelic.api.agent.Trace;
66
import com.newrelic.api.agent.weaver.MatchType;
7-
import com.newrelic.api.agent.weaver.NewField;
7+
//import com.newrelic.api.agent.weaver.NewField;
88
import com.newrelic.api.agent.weaver.Weave;
9-
import com.newrelic.api.agent.weaver.Weaver;
9+
//import com.newrelic.api.agent.weaver.Weaver;
1010

1111
@Weave(type=MatchType.BaseClass)
1212
public abstract class DispatchedTask<T> {
1313

14-
@NewField
15-
protected Token token = null;
16-
17-
public DispatchedTask(int mode) {
18-
if(token == null) {
19-
Token t = NewRelic.getAgent().getTransaction().getToken();
20-
if(t != null && t.isActive()) {
21-
token = t;
22-
} else if(t != null) {
23-
t.expire();
24-
t = null;
25-
}
26-
}
27-
}
28-
29-
@Trace(async=true)
30-
public void run() {
31-
if(token != null) {
32-
token.linkAndExpire();
33-
token = null;
34-
}
35-
Weaver.callOriginal();
36-
}
14+
// @NewField
15+
// protected Token token = null;
16+
//
17+
// public DispatchedTask(int mode) {
18+
// if(token == null) {
19+
// Token t = NewRelic.getAgent().getTransaction().getToken();
20+
// if(t != null && t.isActive()) {
21+
// token = t;
22+
// } else if(t != null) {
23+
// t.expire();
24+
// t = null;
25+
// }
26+
// }
27+
// }
28+
//
29+
// @Trace(async=true)
30+
// public void run() {
31+
// if(token != null) {
32+
// token.linkAndExpire();
33+
// token = null;
34+
// }
35+
// Weaver.callOriginal();
36+
// }
3737

3838
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
import kotlin.coroutines.CoroutineContext;
11+
12+
@Weave(type=MatchType.BaseClass)
13+
public abstract class ExecutorCoroutineDispatcherBase {
14+
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+
}
28+
}
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.newrelic.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+
}

kroto-plus-coroutines/build.gradle

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
// Build.gradle generated for instrumentation module kroto-plus
3+
4+
apply plugin: 'java'
5+
6+
dependencies {
7+
implementation 'com.github.marcoferrer.krotoplus:kroto-plus-coroutines:0.3.0'
8+
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.0'
9+
implementation 'io.grpc:grpc-stub:1.15.1'
10+
11+
12+
// New Relic Java Agent dependencies
13+
implementation 'com.newrelic.agent.java:newrelic-agent:6.0.0'
14+
implementation 'com.newrelic.agent.java:newrelic-api:6.0.0'
15+
implementation fileTree(include: ['*.jar'], dir: '../libs')
16+
}
17+
18+
jar {
19+
manifest {
20+
attributes 'Implementation-Title': 'com.newrelic.instrumentation.kroto-plus'
21+
attributes 'Implementation-Vendor': 'New Relic'
22+
attributes 'Implementation-Vendor-Id': 'com.newrelic'
23+
attributes 'Implementation-Version': 1.0
24+
}
25+
}
26+
27+
verifyInstrumentation {
28+
passes 'com.github.marcoferrer.krotoplus:kroto-plus-coroutines:[0.3.0,)'
29+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.github.marcoferrer.krotoplus.coroutines.client;
2+
3+
import com.newrelic.api.agent.Trace;
4+
import com.newrelic.api.agent.weaver.Weave;
5+
import com.newrelic.api.agent.weaver.Weaver;
6+
7+
import io.grpc.CallOptions;
8+
import io.grpc.Channel;
9+
import io.grpc.MethodDescriptor;
10+
import kotlin.coroutines.Continuation;
11+
12+
@Weave
13+
public abstract class ClientCallsKt {
14+
15+
@Trace
16+
public static final <ReqT, RespT> Object clientCallUnary(ReqT request,MethodDescriptor<ReqT, RespT> method, Channel channel, CallOptions options, Continuation<? super RespT> completion) {
17+
return Weaver.callOriginal();
18+
}
19+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.github.marcoferrer.krotoplus.coroutines.client;
2+
3+
import com.newrelic.api.agent.NewRelic;
4+
import com.newrelic.api.agent.Token;
5+
import com.newrelic.api.agent.Trace;
6+
import com.newrelic.api.agent.weaver.NewField;
7+
import com.newrelic.api.agent.weaver.Weave;
8+
import com.newrelic.api.agent.weaver.Weaver;
9+
10+
import kotlin.coroutines.Continuation;
11+
12+
@Weave
13+
public class SuspendingUnaryObserver<RespT> {
14+
15+
@NewField
16+
private Token token = null;
17+
18+
public SuspendingUnaryObserver(Continuation<RespT> cont) {
19+
Token t = NewRelic.getAgent().getTransaction().getToken();
20+
if(t != null && t.isActive()) {
21+
token =t;
22+
} else if(t != null) {
23+
t.expire();
24+
t = null;
25+
}
26+
27+
}
28+
29+
@Trace(async=true)
30+
public void onNext(Object value) {
31+
if(token != null) {
32+
token.link();
33+
}
34+
Weaver.callOriginal();
35+
}
36+
37+
public void onError(Throwable t) {
38+
NewRelic.noticeError(t);
39+
if(token != null) {
40+
token.expire();
41+
token = null;
42+
}
43+
Weaver.callOriginal();
44+
}
45+
46+
public void onCompleted() {
47+
if(token != null) {
48+
token.expire();
49+
token = null;
50+
}
51+
Weaver.callOriginal();
52+
}
53+
}

0 commit comments

Comments
 (0)