Wednesday, November 14, 2007

Aspect Variations

In a prior post, I suggested an analogy between different ways of formulating Physics and the contrast between thinking about objects and aspects. If OO is like vectors and matrices, then aspects are like variational principles. There's a cute little follow-up that I'd like to explore presently.

I'm very fond of Log4J and diagnostic contexts. In a word, diagnostic contexts conveniently allow the code to store arbitrary strings in thread local storage. So suppose I have a jar that offers functionality to persist to a database or a file. The application level code can set a diagnostic context, and then the log messages written by the jar's code will contain that useful information.

In pseudo-code, we might do something like this...

import org.apache.log4j.NDC;
import mypersistpackage.Persister;
//...
NDC.push("current cseq=" + cseq);
Persister.save(foo);


Then any Log4J messages written by the Persister.save method will contain the specified cseq number. This is incredibly useful, and we didn't have to modify the Persister source code at all.

However, a subtle problem arises when we're using thread pools. Whenever the application code makes an RPC, there's a chance that the thread will get returned to the pool during the call. This means that when the remote procedure returns, we might pick up where we left off in a different thread. This means that any context held in thread local storage will be stale.

In our example, we'd risk printing out the wrong cseq number after making a remote procedure call. The risks of this would increase when the system is under load, which is exactly when log messages are most important.

In a prior post, it was suggested that an aspect could advise all RPCs, so that timing information could be gathered. This is an example of a global principle that can be applied across the entire application. We can press that aspect into service to make sure our diagnostic contexts are not mangled when coming back from a remote call.

Even though we could do this with our OO helper class described in the prior post, this solution just plain didn't occur to us until we started thinking in aspects. (In fact, we abandoned using diagnostic contexts altogether.) And sure, I could solve the brachistochrone problem numerically using vectors, but I'm sure that a computed solution wouldn't give me the same insight I'd get by using the calculus of variations.

No comments: