Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve the MDC context during callbacks. #5

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/Deferred.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

/**
* A thread-safe implementation of a deferred result for easy asynchronous
Expand Down Expand Up @@ -570,6 +572,12 @@ public final class Deferred<T> {
private static final AtomicIntegerFieldUpdater<Deferred> stateUpdater =
AtomicIntegerFieldUpdater.newUpdater(Deferred.class, "state");

/**
* Captures the current context map of the current thread. This map is later
* reconstituted on the thread that begins the callback chain.
*/
private final Map mdcContext = MDC.getCopyOfContextMap();

/**
* Atomically compares and swaps the state of this Deferred.
* @param cmp The expected state to compare against.
Expand Down Expand Up @@ -1223,10 +1231,28 @@ public String toString() {
}
};

/**
* Sets the MDC context to the given {@code map}. It returns the original map
* that was in effect before the call took place. If {@code map} is null, the
* MDC context is cleared.
* @param map The context map to set.
* @return the original map that was in effect before this call took place.
*/
private Map setMdc(Map map) {
Map old = MDC.getCopyOfContextMap();
if (map != null) {
MDC.setContextMap(map);
} else {
MDC.clear();
}
return old;
}

/**
* Executes all the callbacks in the current chain.
*/
private void runCallbacks() {
Map old = setMdc(mdcContext);
while (true) {
Callback cb = null;
Callback eb = null;
Expand Down Expand Up @@ -1263,6 +1289,7 @@ private void runCallbacks() {
// + "), result=" + result
// + " in " + (System.nanoTime() - start) / 1000 + "us");
}
setMdc(old);
}

/**
Expand Down