cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Polar Humenn <>
Subject Re: Proposal for chaning CXF Interceptor APIs. WAS: RE: When should we close the handlers in CXF?
Date Wed, 14 Feb 2007 05:57:52 GMT

> And the idea that onTermination() is called after the chain has been 
> invoked
> is just as simple to understand. Are you telling me that a developer 
> can't
> understand that a method is executed at the end of the chain?

But I'm confused, onTermination() isn't called at the "end" of the 
chain. The first call to an onTermination() method is in the "middle" of 
the chain. That's because you are still "handling" the message in 
onTermination() calls of the interceptors. For instance, in the outgoing 
interceptor phase chain, the message isn't guaranteed to pop-out at the 
end of the chain, it pops out at the beginning of the chain!

Let's take the MessageSenderInterceptor. This interceptor is placed at 
the "PREPARE_SEND" Phase. Looking at its current implementation there is 
a Chain.doIntercept() call. I will assume that it is the split where 
handleMessage and onTermination() will now exist.

handleMessage will call conduit.send(message);
          (which basically readies the message to get handled by other 
           in the PRE_STREAM, etc. phases.)

onTermination will call conduit.close(message);
          (which closes the OutputStream, i.e. flushes the final buffers 
writing data to the wire, guaranteeing that the message has been sent.)

So, my basic question is, and what is confusing to me, is why is 
conduit.close(message) called in the PREPARE_SEND phase? Shouldn't it 
logically be called in the "SEND" Phase, which is the *last* outgoing phase?

And what if that onTermination() call got an IOException on the 
OutputStream.close(). (The message really cant be said it made it out to 
the wire. None of the interceptors after the PREPARE_SEND phase will get 

> First, there is no handleFault, it needs to be removed.  If there is a
> fault, an interceptor can detect it in onTermination and correct for it
> there. 
I disagree. The handleFault and handleMessage are complementary. 
HandleFault is there to unwind the actions the previous interceptors 
took in handleMessage.

 From what I can gather from the proposal, this onTermination() method 
*always* gets called whether a fault happened or not, in order, back 
down the chain regardless. But there is no chance to unwind or undo any 
actions taken if an "earlier" interceptor onTermination() throws a fault.

A.handleMessage() action A.
B.handleMessage() action B.
C.handleMessage() action C.
D.handleMessage() action D.
D.onTermination()   action D'
C.onTermination() throw Fault.
B.onTermination() does what?
A.onTermination() does what?

So let me get this straight, since C.onTermination() throws a Fault, 
then interceptor D will not get any notification that the message never 
made it through the chain? Since D.onTermination() has already been 
called and long forgotten?
> Second, I think your example is more theoretical than real. If someone 
> needs
> more control over the termination actions, they can always write a second
> interceptor. There is nothing about onTermination() that prevents that.
I gave you a very real example that does parallel ongoing encryption. 
The bookend interceptors are staggered because of lifecyle issues.

A.starting needs to create an object.
B.starting needs to "use" A's object.
A.ending needs to "close" it's object.
B.ending operates on A's "finalized" object.

And really, is there is anything wrong with a little theory? :)

With onTermination() each interceptor will get called twice even if the 
interceptor doesn't need or want to do anything with the onTermination() 
call. That is a wasted call, and leads to unavoidable inefficiencies.

> Regards,
> Dan

View raw message