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