I am currently working on event/activity logging system, which I'm implementing as an aspect using method interceptors. At the moment, the system/framework assumes that each method is one activity but I want to extend this so that an activity can span multiple method invocations. In order to do this, the first approach that come to mind is by providing some context to all the related method calls. However, I only know a way to do this if all method invocations are within the context of a single thread (like Log4J's MDC/NDC). Is there any way to provide context for multiple threads (probably without the code being aware of multithreading)?
3 Answers
Don't think about "logging". It goes to something even more fundamental: if you want the actions done by multiple thread being treated in the same context, what is you propagating to let each thread aware which context they are in?
If you can answer this, then this context is what you need to put in MDC/NDC for logging (probably not the whole context, but some key information in that context).
If your application doesn't carry such information around, there is no way anyone can determine that for you.
Edit:
I may give u some idea on how you may perform the setup. Whether it is appropriate to use AOP to further enhance it, that's your further study :)
// Assume I have a ContextManager which Context is stored in thread local:
abstract class ContextAwaredJob implements Runnable {
public ContextAwaredJob() {
this.context = ContextManager.getCurrentContext();
}
public void run() {
ContextManager.setCurrentContext(this.context);
doRun();
}
protected abstract void doRun();
}
You new "job" is going to extend this parent class, and context will be automatically setup if you are running this by another thread. (The design of course can be refined a lot but it give u a basic idea on what is happening)

- 38,812
- 10
- 83
- 131
-
I'm not sure if I understand this correctly. Anyway, since the approach is aspect oriented, there's going to be a component in the background that would be tasked to keep track of the context, say a ContextManager. I'd like to structure it such that, no matter how any method gets executed, whether within the same or different thread from the original stack of execution, the context remains the same. I'm not sure if I'm making sense here; I don't have much experience with multithreading (at least not directly). – Psycho Punch Apr 16 '12 at 12:05
-
The problem is "whether within the same or different thread from the original stack of execution". Normally, method invocation stack within the same stack can be reasonably considered to be under same context. However, when you have having other thread to perform, no one except u knows the correct context. For example, u have a job dispatcher which put jobs for a thread pool to run. You would like the "context" to be the user session, you gotta setup the context for the new thread. I believe some specific fw setup specific context in such case but only u know what you really wants – Adrian Shum Apr 17 '12 at 01:28
Class ThreadLocal? This sems like it actually might be a valid and resonable use for TLS - adding a cotext to code that already exists.

- 24,453
- 3
- 36
- 60
-
Actually that's what I'm planning to use. I'm just not sure if it's still going to work with multithreading. – Psycho Punch Apr 16 '12 at 12:08
-
ThreadLocal is to solve certain problem in multi-threading (And in my answer, the ContextManager is usually implemented with ThreadLocal inside). The main problem you should think of is the way to carry the context content to another Thread. Please do remember that there are lots of way to make your app multi-thread. Spawning a new thread every time is usually the worst way to do. How you are performing multi-threading will surely affect the way you propagate the context. – Adrian Shum Apr 20 '12 at 02:26
I stumbled upon InheritableThreadLocal, which I think could work for my code. This is assuming that all related threads are spawned from some parent/root thread (which I think is a safe assumption).

- 6,418
- 9
- 53
- 86
-
1it is not as simple as that. One potential issue is like this: http://stackoverflow.com/questions/7296623/inheritablethreadlocal-and-thread-pools . That's why I always emphasize that such context need to be setup in kind of explicit way. – Adrian Shum Apr 20 '12 at 02:20
-
My only problem with your suggestion right now is that the application I'm working on does not currently have explicit spawning of threads. Some third party API may be doing it in the background but there's none that I'm aware so far. I'm quite satisfied with whatever limited support for multithread context the InheritableThreadLocal offers at the moment. I'll be sure to take note of your suggestions so I can use them when I encounter such issues in the future. Thanks. – Psycho Punch Apr 21 '12 at 01:58