Hi Dan,

I'm glad I convinced you on one point that was rockin' my boat.  :) Thanks.

My only objection to the current and proposed scheme is the "reentrant" interceptor chain execution scheme. This seems like a violation of a control principle. Why should an interceptor actively control the mechanism that is controlling the interceptors?

I guess it's like a disk device driver deciding bus access affecting other devices it doesn't know about. (maybe a bad example). Or a user process manipulating the operating system process table deciding what should processes to run next.

Furthermore, I think the sole purpose of the "reentrant" model is so that a particular interceptor in Phase A, can perform an operation X after Phase B further down the chain, which seems confusing to me. I would think action X would be executed in some phase *after* B, not in Phase A.

So, I have three points:

Point 1: Lets say, if I put an interceptor in the position of the last phase, shouldn't I expect that I am the last interceptor point, and the last actions that are done are mine?

Point 2: fault handling. Granted, the doIntercept() call returns false instead of true if the chain was aborted or not completed yet, and maybe the actions after that can take that into account, but *why* is it *allowed* to do this? This interceptor should have *already* had handleFault called, yet this interceptor is still in the handleMessage() call, technically 'handling" the message. This gives me a big "Huh?".

Point 3: What if you call doIntercept() in a handleFault() operation? Nothing can prevent it. If you look at the code for the PhaseInterceptorChain, the chain is not yet ABORTED, and this can reek havoc, by starting down the the rest of the chain when it should be unwinding!

[There's also another problem is an interceptor removes itself from the chain, or something else removes the currently executing interceptor, but may get into that later :) ]

Thanks for listening to my concerns.

Cheers,
-Polar

Dan Diephouse wrote:
Hiya,

On 2/14/07, Polar Humenn <[EMAIL PROTECTED]> 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


Reply via email to