27
27
import io .temporal .common .interceptors .WorkflowOutboundCallsInterceptor ;
28
28
import io .temporal .common .interceptors .WorkflowOutboundCallsInterceptorBase ;
29
29
import io .temporal .opentracing .OpenTracingOptions ;
30
+ import io .temporal .workflow .Functions ;
31
+ import io .temporal .workflow .Promise ;
30
32
import io .temporal .workflow .Workflow ;
31
33
import io .temporal .workflow .WorkflowInfo ;
32
34
import io .temporal .workflow .unsafe .WorkflowUnsafe ;
35
+ import java .util .concurrent .TimeUnit ;
36
+ import java .util .concurrent .TimeoutException ;
33
37
34
38
public class OpenTracingWorkflowOutboundCallsInterceptor
35
39
extends WorkflowOutboundCallsInterceptorBase {
36
40
private final SpanFactory spanFactory ;
37
41
private final Tracer tracer ;
38
42
private final ContextAccessor contextAccessor ;
39
43
44
+ private class PromiseWrapper <R > implements Promise <R > {
45
+ private final Span capturedSpan ;
46
+ private final Promise <R > delegate ;
47
+
48
+ PromiseWrapper (Span capturedSpan , Promise <R > delegate ) {
49
+ this .capturedSpan = capturedSpan ;
50
+ this .delegate = delegate ;
51
+ }
52
+
53
+ private <O > O wrap (Functions .Func <O > fn ) {
54
+ Span activeSpan = tracer .scopeManager ().activeSpan ();
55
+ if (activeSpan == null && capturedSpan != null ) {
56
+ try (Scope ignored = tracer .scopeManager ().activate (capturedSpan )) {
57
+ return fn .apply ();
58
+ }
59
+ } else {
60
+ return fn .apply ();
61
+ }
62
+ }
63
+
64
+ @ Override
65
+ public boolean isCompleted () {
66
+ return delegate .isCompleted ();
67
+ }
68
+
69
+ @ Override
70
+ public R get () {
71
+ return delegate .get ();
72
+ }
73
+
74
+ @ Override
75
+ public R cancellableGet () {
76
+ return delegate .cancellableGet ();
77
+ }
78
+
79
+ @ Override
80
+ public R get (long timeout , TimeUnit unit ) throws TimeoutException {
81
+ return delegate .get (timeout , unit );
82
+ }
83
+
84
+ @ Override
85
+ public R cancellableGet (long timeout , TimeUnit unit ) throws TimeoutException {
86
+ return delegate .cancellableGet (timeout , unit );
87
+ }
88
+
89
+ @ Override
90
+ public RuntimeException getFailure () {
91
+ return delegate .getFailure ();
92
+ }
93
+
94
+ @ Override
95
+ public <U > Promise <U > thenApply (Functions .Func1 <? super R , ? extends U > fn ) {
96
+ return delegate .thenApply ((r ) -> wrap (() -> fn .apply (r )));
97
+ }
98
+
99
+ @ Override
100
+ public <U > Promise <U > handle (Functions .Func2 <? super R , RuntimeException , ? extends U > fn ) {
101
+ return delegate .handle ((r , e ) -> wrap (() -> fn .apply (r , e )));
102
+ }
103
+
104
+ @ Override
105
+ public <U > Promise <U > thenCompose (Functions .Func1 <? super R , ? extends Promise <U >> fn ) {
106
+ return delegate .thenCompose ((r ) -> wrap (() -> fn .apply (r )));
107
+ }
108
+
109
+ @ Override
110
+ public Promise <R > exceptionally (Functions .Func1 <Throwable , ? extends R > fn ) {
111
+ return delegate .exceptionally ((t ) -> wrap (() -> fn .apply (t )));
112
+ }
113
+ }
114
+
40
115
public OpenTracingWorkflowOutboundCallsInterceptor (
41
116
WorkflowOutboundCallsInterceptor next ,
42
117
OpenTracingOptions options ,
@@ -51,13 +126,16 @@ public OpenTracingWorkflowOutboundCallsInterceptor(
51
126
@ Override
52
127
public <R > ActivityOutput <R > executeActivity (ActivityInput <R > input ) {
53
128
if (!WorkflowUnsafe .isReplaying ()) {
129
+ Span capturedSpan = tracer .scopeManager ().activeSpan ();
54
130
Span activityStartSpan =
55
131
contextAccessor .writeSpanContextToHeader (
56
132
() -> createActivityStartSpanBuilder (input .getActivityName ()).start (),
57
133
input .getHeader (),
58
134
tracer );
59
135
try (Scope ignored = tracer .scopeManager ().activate (activityStartSpan )) {
60
- return super .executeActivity (input );
136
+ ActivityOutput <R > output = super .executeActivity (input );
137
+ return new ActivityOutput <>(
138
+ output .getActivityId (), new PromiseWrapper <>(capturedSpan , output .getResult ()));
61
139
} finally {
62
140
activityStartSpan .finish ();
63
141
}
@@ -69,13 +147,15 @@ public <R> ActivityOutput<R> executeActivity(ActivityInput<R> input) {
69
147
@ Override
70
148
public <R > LocalActivityOutput <R > executeLocalActivity (LocalActivityInput <R > input ) {
71
149
if (!WorkflowUnsafe .isReplaying ()) {
150
+ Span capturedSpan = tracer .scopeManager ().activeSpan ();
72
151
Span activityStartSpan =
73
152
contextAccessor .writeSpanContextToHeader (
74
153
() -> createActivityStartSpanBuilder (input .getActivityName ()).start (),
75
154
input .getHeader (),
76
155
tracer );
77
156
try (Scope ignored = tracer .scopeManager ().activate (activityStartSpan )) {
78
- return super .executeLocalActivity (input );
157
+ LocalActivityOutput <R > output = super .executeLocalActivity (input );
158
+ return new LocalActivityOutput <>(new PromiseWrapper <>(capturedSpan , output .getResult ()));
79
159
} finally {
80
160
activityStartSpan .finish ();
81
161
}
@@ -87,11 +167,15 @@ public <R> LocalActivityOutput<R> executeLocalActivity(LocalActivityInput<R> inp
87
167
@ Override
88
168
public <R > ChildWorkflowOutput <R > executeChildWorkflow (ChildWorkflowInput <R > input ) {
89
169
if (!WorkflowUnsafe .isReplaying ()) {
170
+ Span capturedSpan = tracer .scopeManager ().activeSpan ();
90
171
Span childWorkflowStartSpan =
91
172
contextAccessor .writeSpanContextToHeader (
92
173
() -> createChildWorkflowStartSpanBuilder (input ).start (), input .getHeader (), tracer );
93
174
try (Scope ignored = tracer .scopeManager ().activate (childWorkflowStartSpan )) {
94
- return super .executeChildWorkflow (input );
175
+ ChildWorkflowOutput <R > output = super .executeChildWorkflow (input );
176
+ return new ChildWorkflowOutput <>(
177
+ new PromiseWrapper <>(capturedSpan , output .getResult ()),
178
+ new PromiseWrapper <>(capturedSpan , output .getWorkflowExecution ()));
95
179
} finally {
96
180
childWorkflowStartSpan .finish ();
97
181
}
@@ -104,13 +188,17 @@ public <R> ChildWorkflowOutput<R> executeChildWorkflow(ChildWorkflowInput<R> inp
104
188
public <R > ExecuteNexusOperationOutput <R > executeNexusOperation (
105
189
ExecuteNexusOperationInput <R > input ) {
106
190
if (!WorkflowUnsafe .isReplaying ()) {
191
+ Span capturedSpan = tracer .scopeManager ().activeSpan ();
107
192
Span nexusOperationExecuteSpan =
108
193
contextAccessor .writeSpanContextToHeader (
109
194
() -> createStartNexusOperationSpanBuilder (input ).start (),
110
195
input .getHeaders (),
111
196
tracer );
112
197
try (Scope ignored = tracer .scopeManager ().activate (nexusOperationExecuteSpan )) {
113
- return super .executeNexusOperation (input );
198
+ ExecuteNexusOperationOutput <R > output = super .executeNexusOperation (input );
199
+ return new ExecuteNexusOperationOutput <>(
200
+ new PromiseWrapper <>(capturedSpan , output .getResult ()),
201
+ new PromiseWrapper <>(capturedSpan , output .getOperationExecution ()));
114
202
} finally {
115
203
nexusOperationExecuteSpan .finish ();
116
204
}
@@ -122,6 +210,7 @@ public <R> ExecuteNexusOperationOutput<R> executeNexusOperation(
122
210
@ Override
123
211
public SignalExternalOutput signalExternalWorkflow (SignalExternalInput input ) {
124
212
if (!WorkflowUnsafe .isReplaying ()) {
213
+ Span capturedSpan = tracer .scopeManager ().activeSpan ();
125
214
WorkflowInfo workflowInfo = Workflow .getInfo ();
126
215
Span childWorkflowStartSpan =
127
216
contextAccessor .writeSpanContextToHeader (
@@ -136,7 +225,8 @@ public SignalExternalOutput signalExternalWorkflow(SignalExternalInput input) {
136
225
input .getHeader (),
137
226
tracer );
138
227
try (Scope ignored = tracer .scopeManager ().activate (childWorkflowStartSpan )) {
139
- return super .signalExternalWorkflow (input );
228
+ SignalExternalOutput output = super .signalExternalWorkflow (input );
229
+ return new SignalExternalOutput (new PromiseWrapper <>(capturedSpan , output .getResult ()));
140
230
} finally {
141
231
childWorkflowStartSpan .finish ();
142
232
}
0 commit comments