Hi Danny,
~I~
1) The existing missingReply fault, I remind
you, is thrown only upon
process exit.
Yes, that's why we are trying to change that via Issue 221 based on the
passed resolution of Issue 123.
2) I don't find exitOnStandardFault to be very
useful in this context.
I want the process to *portably continue*.
I feel that when taken alongside the rest of the business logic that is
represented, the fact that the process failed to reply is not cause to
interrupt control flow. My point was that if the elephant wants to
clean up some peanut shells 'cause it's a good citizen, then it should
feel free to do so. But throwing a fault is, in my mind, the moral
equivalent of halting a parade in order to return a penny that someone
dropped. (OK, I'll stop the metaphors now..)
I think understand more what you want now. I don't oppose that
"elephant" doing some automatic clean up work for open IMA, if user
choose to ask the "elephant" to do so. And, specifying a missingReply
fault and its semantics does not prevent the "elephant" from doing this
clean up trick.
If the "elephant" knows this clean up trick and send out the default
reply, the missingReply will NOT be triggered at all. HOWEVER, it
should NOT be the default semantics without any elephant extension or
using "exitOnStandardFault". Especially, since the work is done by
the "elephant", I am not sure whether we can make this elephant work
portable at all without invent a bunch of mechanism around it. (e.g. we
need to specify what is the default reply sent out, if a user's reply
is missing?).
The "portably" word in "*portably continue*" seems a bit contradictory,
ironic and infeasible.
The key semantics that we need to maintain is: if the elephant does not
provide this clean service, the scope that causes this missing reply
situation needs to be FAULTED, not completed.
~II~
Asking the "elephant" to do a cleanup work exists in many forms. One of
them can be your missingReplyHandler. The other form can be:
<receive operation="validatePO" variable="x" ...>
<foo:defaultReply variable="y" ... />
</receive>
A much cleaner way to solve this in the process
would be to add:
<OracleExtension:missingReplyHandler>
I found it extra interesting, as you use "Oracle" word here, given you
passed a resolution to remove the "rendezvous" wording. :-) ;-)
~III~
Let me repeat myself [ again :-) ]. There are two checkpoints in my
suggestion:
- step (5) in Chris' 7-step description for Normal Completion of a
scope
- step (F4) in my 4-step description for Fault Handler execution of a
scope
Danny wrote:
my point in the second example:
S2
catch missingReply
replyToReceive
S1
FaultHandler "F1"
sequence
doSomeCleanup
rethrow "F1"
catch missingReply
replyToReceive
Sequence
receive
doSomethingThatThrowsFault "F1"
reply
is that careful programmers will be forced to put the S1 catch
missingReply in in order to clean up after themselves. People who
include others' code in a modular fashion will be forced to wrap them a
la S2, since there is no way (that I can see) of the encloser of S2 to
be sure that S1 will not throw a missingReply (unless it has no
IMAs...).
The catch missingReply activity, if present, can have an IMA in it, or
could fail to successfully reply. Without examining each enclosed
scope to determine what its IMA/missingReply behavior would be, all
enclosing scopes are going to have to do this wrapping to protect
themselves. I'd be happy to find out that I'm wrong in this, but it's
what it looks like to me on first examination.
Actually, you may be happy to find out that in your scenario you
depict, those blue codes are NOT needed. BOTH check points are NOT
reached due to a fault throw or rethrowing.
Similar situation for your second iteration of your second example.
Those blue codes are not needed.
~IV~
On the other hand, I am **relatively** OK to loosen up checkpoint in
step (F4), while I **strongly** supports reinforcing checkpoint in step
(5) for normal completion. Because the scope is already faulted in the
case of (F1)-(F3). It is ok up to the child scope to control whether to
throw a business fault or a standard missingReply to its parent scope.
This arrangement will not break any scope-modularity design principle.
Then, even if we removed "rethrow F1", the parent scope still does not
need to do anything with missingReply.
Regards,
Alex Yiu
Danny van der Rijn wrote:
Alex Yiu wrote:
Hi Danny,
The reply is indeed like "stream-of-consciousness". :-) ... Still,
thank you for your reply.
[1]
Danny wrote:
I think we might be much better off leaving
this "modelling error" to the elephant.
With existing missingReply fault and Dieter's "exitOnStandardFault"
facility, this modelling error can be handed over to the "elephant"
easily. We are trying to define the common paradigm of:
- when this missingReply fault happens (i.e. to define when the
"elephant" can do its magic job)
- where this missingReply fault is thrown to (i.e. to define
the
snapshot state of process and scope, when the "elephant" steps in. e.g.
which scope is faulted, which scope is completed).
If we take out "missingReply" fault, we would leave both of the above
items undefined. That seems too much of handwaving to me. Users would
get lost in different kinds of "wonderland" of "elephants".
1) The existing missingReply fault, I remind you, is thrown only upon
process exit.
2) I don't find exitOnStandardFault to be very useful in this context.
I want the process to *portably continue*.
I feel that when taken alongside the rest of the business logic that is
represented, the fact that the process failed to reply is not cause to
interrupt control flow. My point was that if the elephant wants to
clean up some peanut shells 'cause it's a good citizen, then it should
feel free to do so. But throwing a fault is, in my mind, the moral
equivalent of halting a parade in order to return a penny that someone
dropped. (OK, I'll stop the metaphors now..)
[2]
You may have misunderstood current fault propagation
model and my proposal unfortunately.
[2a]:
Danny wrote:
Chris' 7-points mail looks to me like it's
throwing the fault to the
parent scope:
If we do
that then like any other fault
generated by a fault handler it would be thrown to the parent scope.
But this isn't what you're proposing, is it?
With my suggested proposal, the typical chain of events for
missingReply would be
(S2 is a child scope, S1 is the parent scope).
=> S2 throws a missingReply fault to S2 => S2 (given the default
fault handler behavior) will throw a missingReply fault to S1.
In short, if S2 does NOT try to intercept a missingReply fault (default
behavior) and does NOT set "exitOnStandardFault" to true (default
behavior), a missingReply fault will be thrown to S1 as the result.
[2b]:
Copy and paste a part of my proposal again here:
------------------------------------------
F1 - marks scope as faulted
F2 - matches and selects a fault handler (it can be the default one)
and uninstall other fault handlers and termination handler
F3 - executes the activity of the selected fault handler (A
fault may
be thrown to the parent during this step. If so, step F4 will not be
reached).
F4 - validates that message exchanges have closed (A missingReply fault
may be thrown to the parent during this step) [ same logic as in step
(5) ]
[No source links will be fired after F4. Instead, DPE may be triggered.]
------------------------------------------
Ah, I missed the italicized part of F3. Thanks. That makes it a bit
more consistent to me, but sitll doesn't win me over. So missingReply
is a "backstop fault" - I'll complain about this if there's nothing
else to complain about.
Using your first example:
------------------------------------------
S1
FaultHandler
sequence
doSomeCleanup
rethrow F1
Sequence
receive
doSomethingThatThrowsFault
reply
------------------------------------------
F1 will be thrown to the parent scope, instead of missingReply. Because
F4 logic will not be reached.
If the "rethrow F1" is missing, then a missingReply fault will be
thrown to the parent scope of S1.
[2c]
I am not sure I follow your second BPEL source code example. Maybe,
that example was constructed based on some misunderstanding of my
suggestion. The way I read of your second example is: both blue "catch missingReply" handler will NOT be
triggered.
my point in the second example:
S2
catch missingReply
replyToReceive
S1
FaultHandler
sequence
doSomeCleanup
rethrow
catch missingReply
replyToReceive
Sequence
receive
doSomethingThatThrowsFault
reply
is that careful programmers will be forced to put the S1 catch
missingReply in in order to clean up after themselves. People who
include others' code in a modular fashion will be forced to wrap them a
la S2, since there is no way (that I can see) of the encloser of S2 to
be sure that S1 will not throw a missingReply (unless it has no
IMAs...).
The catch missingReply activity, if present, can have an IMA in it, or
could fail to successfully reply. Without examining each enclosed
scope to determine what its IMA/missingReply behavior would be, all
enclosing scopes are going to have to do this wrapping to protect
themselves. I'd be happy to find out that I'm wrong in this, but it's
what it looks like to me on first examination.
Perhaps my example should have been:
S2
catch missingReply
empty <!-- Did my best, now just make the darned thing GO
AWAY -->
S1
FaultHandler
sequence
doSomeCleanup
rethrow
catch missingReply
replyToReceive <!-- Rats, somebody was left hanging.
Attempt to let them know that I failed -->
Sequence
receive
doSomethingThatMayThrowAFault
Maybereply
There are many cases here: doSomethingThatMayThrowAFault may fault and it may not.
Maybereply might reply and it
might not. To protect against all these cases, you need both of those
handlers. The sad thing is that if doSomethingThatMayThrowAFault does throw a fault, then
the missingReply fault is never thrown, and we've failed to manage to
clean up that IMA.
Why give people an 80% solution here? It would be much cleaner (for
everyone) if we leave this to the elephant.
A much cleaner way to solve this in the process would be to add:
<OracleExtension:missingReplyHandler>
as another handler on a scope or process. This would be run after the
scope is complete, and all other handlers are uninstalled. It is
presented with a list of open IMAs and it does with them as it sees
fit. I wish you luck in implementing it ;-)
I hope this clarify any misunderstanding.
Thanks!
Regards,
Alex Yiu
|