Skip to content

Commit bd65ef4

Browse files
authored
Replace onAttach/onDetach context event pair with onUpdate(before, after) (#11859)
Replace onAttach/onDetach context event pair with onUpdate(before, after) Co-authored-by: stuart.mcculloch <stuart.mcculloch@datadoghq.com>
1 parent f51d33e commit bd65ef4

6 files changed

Lines changed: 114 additions & 165 deletions

File tree

components/context/src/main/java/datadog/context/ContextListener.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,12 @@
44
public interface ContextListener {
55

66
/**
7-
* Notifies that the given context has been attached to the current execution unit.
7+
* Notifies that the context has been updated for the current execution unit.
88
*
9-
* @param context the attached context.
9+
* @param before the context before.
10+
* @param after the context after.
1011
*/
11-
default void onAttach(Context context) {}
12-
13-
/**
14-
* Notifies that the given context has been detached from the current execution unit.
15-
*
16-
* @param context the detached context.
17-
*/
18-
default void onDetach(Context context) {}
12+
default void onUpdate(Context before, Context after) {}
1913

2014
/**
2115
* Notifies that the given context has been captured by a continuation.

components/context/src/main/java/datadog/context/ThreadLocalContextManager.java

Lines changed: 17 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
final class ThreadLocalContextManager implements ContextManager {
99
static final ThreadLocalContextManager INSTANCE = new ThreadLocalContextManager();
1010

11-
private static final NoopContextContinuation ROOT_CONTINUATION =
12-
new NoopContextContinuation(Context.root());
13-
1411
private static final ThreadLocal<ContextHolder> CONTEXT_HOLDER =
1512
ThreadLocal.withInitial(ContextHolder::new);
1613

14+
private static final NoopContextContinuation ROOT_CONTINUATION =
15+
new NoopContextContinuation(Context.root());
16+
1717
private final Object listenersWriteLock = new Object();
1818
volatile ContextListener[] listeners = {};
1919

@@ -40,16 +40,11 @@ ContextScope doAttach(Context context, @Nullable ContextContinuationImpl continu
4040
return context.asScope(); // convert to scope without attaching
4141
}
4242

43-
ContextListener[] ls = listeners;
44-
notifyDetach(beforeAttach, ls);
4543
holder.current = context;
46-
notifyAttach(context, ls);
47-
48-
if (continuation == null) {
49-
return new ContextScopeImpl(context, holder, beforeAttach);
50-
} else {
51-
return new ResumedScopeImpl(context, holder, beforeAttach, continuation);
52-
}
44+
notifyUpdate(listeners, beforeAttach, context);
45+
return continuation == null
46+
? new ContextScopeImpl(context, holder, beforeAttach)
47+
: new ResumedScopeImpl(context, holder, beforeAttach, continuation);
5348
}
5449

5550
@Override
@@ -61,21 +56,14 @@ public Context swap(Context context) {
6156
return beforeSwap;
6257
}
6358

64-
ContextListener[] ls = listeners;
65-
notifyDetach(beforeSwap, ls);
6659
holder.current = context;
67-
notifyAttach(context, ls);
68-
60+
notifyUpdate(listeners, beforeSwap, context);
6961
return beforeSwap;
7062
}
7163

7264
@Override
7365
public ContextContinuation capture(Context context) {
74-
if (context == Context.root()) {
75-
return ROOT_CONTINUATION;
76-
} else {
77-
return new ContextContinuationImpl(context);
78-
}
66+
return context == Context.root() ? ROOT_CONTINUATION : new ContextContinuationImpl(context);
7967
}
8068

8169
@Override
@@ -99,31 +87,16 @@ void clearListeners() {
9987
}
10088
}
10189

102-
static void notifyAttach(Context context, ContextListener[] listeners) {
103-
if (context == Context.root()) {
104-
return; // don't emit attach events for the default "no context" case
105-
}
106-
for (ContextListener l : listeners) {
107-
try {
108-
l.onAttach(context);
109-
} catch (Throwable ignore) {
110-
}
111-
}
112-
}
113-
114-
static void notifyDetach(Context context, ContextListener[] listeners) {
115-
if (context == Context.root()) {
116-
return; // don't emit detach events for the default "no context" case
117-
}
90+
static void notifyUpdate(ContextListener[] listeners, Context before, Context after) {
11891
for (ContextListener l : listeners) {
11992
try {
120-
l.onDetach(context);
93+
l.onUpdate(before, after);
12194
} catch (Throwable ignore) {
12295
}
12396
}
12497
}
12598

126-
static void notifyCapture(Context context, ContextListener[] listeners) {
99+
static void notifyCapture(ContextListener[] listeners, Context context) {
127100
// only called for non-empty continuations
128101
for (ContextListener l : listeners) {
129102
try {
@@ -133,7 +106,7 @@ static void notifyCapture(Context context, ContextListener[] listeners) {
133106
}
134107
}
135108

136-
static void notifyRelease(Context context, ContextListener[] listeners) {
109+
static void notifyRelease(ContextListener[] listeners, Context context) {
137110
// only called for non-empty continuations
138111
for (ContextListener l : listeners) {
139112
try {
@@ -166,10 +139,8 @@ public final Context context() {
166139
public void close() {
167140
// check for out-of-order close to avoid corrupting the current state
168141
if (!closed && context == holder.current) {
169-
ContextListener[] ls = INSTANCE.listeners;
170-
notifyDetach(context, ls);
171142
holder.current = beforeAttach;
172-
notifyAttach(beforeAttach, ls);
143+
notifyUpdate(INSTANCE.listeners, context, beforeAttach);
173144
closed = true;
174145
}
175146
}
@@ -232,7 +203,7 @@ private static final class ContextContinuationImpl implements ContextContinuatio
232203

233204
ContextContinuationImpl(Context context) {
234205
this.context = context;
235-
notifyCapture(context, INSTANCE.listeners);
206+
notifyCapture(INSTANCE.listeners, context);
236207
}
237208

238209
@Override
@@ -270,7 +241,7 @@ public void release() {
270241
while (current == 0) {
271242
// no outstanding resumes and hold has been removed
272243
if (COUNT.compareAndSet(this, current, RELEASED)) {
273-
notifyRelease(context, INSTANCE.listeners);
244+
notifyRelease(INSTANCE.listeners, context);
274245
return;
275246
}
276247
current = count;
@@ -280,7 +251,7 @@ public void release() {
280251
void releaseOnScopeClose() {
281252
if (COUNT.compareAndSet(this, 1, RELEASED)) {
282253
// fast path: only one resume of the continuation (no hold)
283-
notifyRelease(context, INSTANCE.listeners);
254+
notifyRelease(INSTANCE.listeners, context);
284255
} else if (COUNT.decrementAndGet(this) == 0) {
285256
// slow path: multiple resumes, all scopes now closed (no hold)
286257
release();

0 commit comments

Comments
 (0)