Brian's Waste of Time

Mon, 08 Dec 2003

Intercept .1.2 Release

Bug fix to fix an NPE when attempting to wrap an already wrapped object. Also includes improved documentation.

Source Tarball, Binary Tarball, and Javadocs

A comment I missed a while back asked about the performance of Signature.matches(...). Bo's concern was that calling this on every interceptor on every invocation would be painfuly slow. Rest easy, this isn't done. The broker builds match information when the interceptor is added and when a new class (not new instance, just new class) is first wrapped. It caches the interception information on a per-class/per-method basis so that the invocation sequence looks like:

  1. foo.doSomething()
  2. ServiceHandler.intercept(...) { query this.methodInterceptMatrix for interceptors for this method }
  3. MethodInterceptMatrix.interceptsFor(...) { hash lookup for interceptors for a method. This might be able to be optimized to an array index lookup instead of a hash lookup, but I haven't had a chance to investigate yet. }
  4. ServiceHandler.intercept(...) { back here, create a new InterceptorStack and return stack.yield() }
  5. Stack.yield() { Your interceptors here }
The MethodInterceptMatrix is key as it allows a hash lookup speed interceptor stack generation (plus interceptor instantiation time for the "new interceptor for every invocation" style interceptors). As mentioned, I am pretty sure I can reduce this to an array index, but havent had time/need to do so yet. The MethodInterceptMatrix is responsible for keeping track of what interceptors care about what methods and builds this information when new interceptors are added, or when new MethodInterceptMatrix instances are created when a class is generated.

The benefit to this design is faster interceptor stack invocation. The drawbacks are that adding a new interceptor to a broker with a lot of classes registered is slow, and adding a class to a broker with a lot of interceptors is slow. An additional drawback is that you only have java.util.reflect.Method information in the Signature.matches(...) test. There have been cases where I want to match calls against a specific instance only intead of all calls to that type's method. This has to be filtered at invocation time (as Bo was afraid of) so needs to be done in the interceptor instead of the Signature which is ugly =/ I have thought about splitting signatures into two types -- compile-time and invocation-time in order to make this cleaner, but haven't yet as I haven't had the need and no one has asked for it.

0 writebacks [/src/java/commons-intercept] permanent link