[parfait] push by tallpsm...@gmail.com - Issue 11 Fixed so that ThreadContext.clear() actually updates the unde... on 2011-03-10 09:52 GMT

0 views
Skip to first unread message

par...@googlecode.com

unread,
Mar 10, 2011, 4:52:57 AM3/10/11
to parfa...@googlegroups.com
Revision: 4c76f4ebd8
Author: Paul Smith <psm...@apache.org>
Date: Thu Mar 10 01:52:25 2011
Log: Issue 11 Fixed so that ThreadContext.clear() actually updates the
underlying MDC value (if set).

This is an insideous bug because without this the MDC becomes tainted with
previous execution values. Evil.
http://code.google.com/p/parfait/source/detail?r=4c76f4ebd8

Modified:

/parfait-core/src/main/java/com/custardsource/parfait/timing/ThreadContext.java

/parfait-core/src/test/java/com/custardsource/parfait/timing/ThreadContextTest.java

=======================================
---
/parfait-core/src/main/java/com/custardsource/parfait/timing/ThreadContext.java
Thu Dec 16 00:06:37 2010
+++
/parfait-core/src/main/java/com/custardsource/parfait/timing/ThreadContext.java
Thu Mar 10 01:52:25 2011
@@ -40,8 +40,17 @@
private final ConcurrentMap<Thread, Map<String, Object>>
PER_THREAD_CONTEXTS = new MapMaker()
.weakKeys().makeComputingMap(NEW_CONTEXT_CREATOR);

- private static volatile MdcBridge mdcBridge = new NullMdcBridge();
-
+ private volatile MdcBridge mdcBridge = new NullMdcBridge();
+
+ public ThreadContext() {
+ this(new NullMdcBridge());
+ }
+
+ public ThreadContext(MdcBridge mdcBridge) {
+ // TODO should that be a static variable..?
+ this.mdcBridge=mdcBridge;
+ }
+
/**
* Adds the given key/value pair to the current thread's context, and
updates {@link MDC} with
* same.
@@ -71,6 +80,15 @@
* Clears all values for the current thread.
*/
public void clear() {
+
+ /**
+ * Unfortunately log4j's MDC historically never had a mechanism to
block remove keys,
+ * so we're forced to do this one by one.
+ */
+ for (String key : allKeys()) {
+ mdcBridge.remove(key);
+ }
+
PER_THREAD_CONTEXTS.get(Thread.currentThread()).clear();
}

@@ -92,7 +110,21 @@
public Object getForThread(Thread thread, String key) {
return PER_THREAD_CONTEXTS.get(thread).get(key);
}
-
+
+ /**
+ * Factory method that creates a new ThreadContext initialized to also
update Log4j's MDC.
+ */
+ public static ThreadContext newMDCEnabledContext() {
+ return new ThreadContext(new Log4jMdcBridge());
+ }
+
+ /**
+ * Factory method that creates a new ThreadContext initialised to also
update SLF4J's MDC
+ */
+ public static ThreadContext newSLF4JEnabledContext() {
+ return new ThreadContext(new Slf4jMDCBridge());
+ }
+
public interface MdcBridge {
void put(String key, Object object);

=======================================
---
/parfait-core/src/test/java/com/custardsource/parfait/timing/ThreadContextTest.java
Tue Feb 16 20:21:06 2010
+++
/parfait-core/src/test/java/com/custardsource/parfait/timing/ThreadContextTest.java
Thu Mar 10 01:52:25 2011
@@ -1,8 +1,11 @@
package com.custardsource.parfait.timing;

+import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

+import org.apache.log4j.MDC;
+
import junit.framework.TestCase;

public class ThreadContextTest extends TestCase {
@@ -10,7 +13,14 @@

public void setUp() {
context = new ThreadContext();
- }
+
+ Hashtable hashtable = MDC.getContext();
+ if (hashtable != null) {
+ hashtable.clear();
+ }
+ }
+
+

public void testGetOfUnusedKeyReturnsNull() {
final String testKey = "handy";
@@ -59,4 +69,25 @@
context.clear();
assertNull("get() after clear should return null",
context.get(testKey));
}
-}
+
+ public void testClearRemovesMDCValue(){
+
+ ThreadContext log4jThreadContext =
ThreadContext.newMDCEnabledContext();
+
+ Hashtable mdcContext = MDC.getContext();
+ assertNull(mdcContext);
+
+ final String testKey = "painter";
+ log4jThreadContext.put(testKey, 7);
+
+ mdcContext = MDC.getContext();
+ assertEquals(1, mdcContext.size());
+
+
+ log4jThreadContext.clear();
+
+ assertEquals(0, mdcContext.size());
+
+ assertNull("get() after clear should return null",
log4jThreadContext.get(testKey));
+ }
+}

Reply all
Reply to author
Forward
0 new messages