cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dan Diephouse" <...@envoisolutions.com>
Subject Re: Proposal for chaning CXF Interceptor APIs. WAS: RE: When should we close the handlers in CXF?
Date Wed, 14 Feb 2007 14:39:23 GMT
Hiya,

On 2/14/07, Polar Humenn <phumenn@iona.com> wrote:
>
>
> > 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
> interceptors,
>            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?


Our phases aren't very well named at the moment. Its been on my todo list
for forever to clean them up.

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
> notified.


Ahhhh, I see your point now. You're right, that does get sticky. I think you
may be right - this may make that proposal a non starter. (Sorry it took me
a while.)

I hope no one minds if I float two more proposals that we've talked about
earlier for the sake of completeness:

The first idea that we've floated before is supporting reentrant interceptor
chains in a slightly different manner. The idea being that instead of
doInterceptInSubChain we would support something like this:

public void handleMessage(Message m)
startSend();
message.getChain().doIntercept(message, endPhase)
close();
}

This is basically just a variation on the current theme, but making it
cleaner. The main advantage of this over the current API would be that
databinding interceptors wouldn't need to call chain.endSubChain().

The second idea would be to rework writing so that it was more encapsulated.
In XFire we had the idea of a Serializer. One of the final interceptors was
responsible for opening the connection, doing serializer.write(message), and
finally closing the connection. The idea here is that as we move through the
chain we can replace/modify the serializer as we feel necessary. The thing I
like about this is that it completely removes the need for reentrant
interceptorchains/onTermination.  Here's an example of how it might work:
1. BareOutInterceptor sets the serializer to something which writes the
message in a doc/lit style
2. Outgoing SAAJ interceptor uses this serializer to write the message to a
SAAJ tree. The serializer is then replaced with a SAAJ serializer
3. Attachment out interceptor wraps the current serializer with one which
starts writing the attachments, then delegates to the SAAJ serializer, and
then finishes writing the attachments
4. A MessageSenderInterceptor opens the connection, executes the current
serializer (outputting the message to the wire), and then closes the
connection.

The thing that I don't like about this is that it introduces a new concept,
but it does become much more straightforward how to do output IMO.

And then there is the standing proposal to just completely remove
doInterceptInSubChain() :-) Thoughts? At the moment I have a preference
toward continuing our support for reentrant interceptors a la the first
proposal that I floated, but I could be swayed either way yet.

Thanks Polar,

- Dan

-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message