You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cloudstack.apache.org by Darren Shepherd <da...@gmail.com> on 2013/09/06 02:40:06 UTC
CallContext and others
In order to manage the database context at the bottom of the stack I'm
having to create a small framework that does stuff as the code enters
the managed context and leaves. So the easiest way to use the framework
is if you have
new Runnable() {
public void run() {....}
}
in your code somewhere you just instead just do
new ManagedContextRunnable() {
public void doRun {...}
}
Additionally for places where there is no runnable at the bottom of the
stack (like ApiServer), there is a simple API as below.
public interface ManagedContext {
public void runWithContext(Runnable run);
public <T> T callWithContext(Callable<T> callable) throws
Exception;
public void registerListener(ManagedContextListener<?> listener);
public void unregisterListener(ManagedContextListener<?> listener);
}
The (un)register methods are for registering listeners to do stuff as
things enter/leave the context (like setup the transaction, etc).
Now this gets to my question. So this is yet another context thread
local thing that needs to be setup. So I'm somewhat trying to tie the
CallContext, ServerContext, AsyncJobExecutionContext, and this together.
So the "managed context" framework is the central place to wire this
all up. Here's what I'm doing, tell me if its terribly bad.
CallContext: One thing I see with the CallContext is that its really
easy to register twice and then leak the NDC stack. What I propose is
that on entering the ManagedContext I will setup the CallContext with a
context that has the user as system and the context id as random. As
people call register/unregister it will push/pop a CallContext on some
stack and additionally push/pop the NDC. When leaving the
ManagedContext I will ensure that all CallContexts are pop'd off the
stack, thus clearing the NDC. This approach has the added benefit that
by default the context will be setup as system and then all background
tasks don't explicitly have to call register(...)
ServerContexts: Just delete it? Basically it seems to just open/close
transaction and I'll be doing that anyhow. It doesn't seem to really be
used yet. Maybe my "Manage Context" framework essentially is in the
spirit of what that was going to be?
AsyncJobExecutionContext: Not too much, I can just ensure that the
AsyncJobExecutionContext is cleared on exit.
On last thought (sorry this is long). I also created the concept of a
ManagedThreadLocal. Its like one thread local to rule them all. Thread
locals are fine, but people forget to clear them. So what you do is
have a "managed thread local" that looks and acts just like a TL but is
really tied to a master TL. When the main context of the thread clears,
the master TL is cleared and all associated managed TLs will be cleared
too. Then you don't ever leak TLs.
Darren