I support Yuzo’s position
completely. A missing reply at the completion of S2 should be thrown to
S1. The fact that we are saying that the missingReply is thrown is when
the partnerLink or messageExchange goes out of scope says it all. How
does it go out of scope, it goes out of scope because the scope completed.
After completion we can’t come back into ourselves to catch a fault. All
that said I’d rather not have this delay 123. I’m ok with leaving
the text as it stands in the 123 proposal and solving the question of which
scope catches the fault in issue 221.
From: Alex Yiu [mailto:firstname.lastname@example.org]
Sent: Monday, December 12, 2005
To: Yuzo Fujishima
Cc: Danny van der Rijn; Chris
Keller; 'ws bpel tc'; Alex Yiu
Subject: Re: [wsbpel] Issue 123 -
Proposal for vote
Thanks for following this discussion thread. Really appreicate it ... :-)
The main motivations behind "S2-to-S2" for missingReply fault are:
==> Finer-grain reply / compensation
- If the fault is thrown to S1 instead of S2, S1
cannot do anything to fix the missing reply situation. Because, one of
resources (partnerLink or messageExchange) used in the open IMA is already
out of scope (S2) and S1 has no access those out-of-scope resources
- The missingReply situation may be caused by the
situation where some other faults happened and the enclosed scope (S2)
does not handle those fault properly. (Please see more analysis of
"programming-error-vs-runtime-error" below.) ... In the
<onEvent> or parallel <forEach> situation, assuming there are
5 instances created and 4 of them got executed successfully without any
missingReply situation. But, one of them ran into this missingReply
situation. If we throw the fault to S1 and if we want to every compensate
the work of S2, all 5 of them need to be compensated. We cannot compensate
just the faulty instance by itself. On the other hand, if we throw to S2,
we can do a partial compensation in its fault handler.
About "Reason 1" : "programming-error-vs-runtime-error"
I agree with you this is more likely a programming error, not a true runtime
error. That is why Dieter introduced this exit-on-standard-fault facility to
allow people to stop process in case of this programming error.
With or without using this exit-on-standard-fault facility, as a complete
specification, we need to specify snapshot state of the process - i.e., what
scopes are faulted and not, when the "exit" takes place.
If you think of the <onEvent> example described above, S1 should not be
faulted, when the "exit" happens. Similarly, the previous 4 instance
of "S2" should not be faulted either. Only the true missingReply
scope should be faulted.
I also agree with you that people should not rely on catching this missingReply
fault to do any complicated business logic. At most, people should just log the
fault and attempt doing the partial compensation, as described above. (This
applies to most of standard fault catchers).
I am just promoting scope-modularity. Definitely, not promoting any weired
coding style. If you want, I think we can add a caution statement along the
intention of the passed resolution of Issue 192 (Dieter's exitOnStandardFault
proposal) to spec to state that: "If people do not set exitOnStandardFault
to true, it is a good practice to restrict logic of any standard fault fault
handler to some minimalistic repair work (e.g. error logging and partial
Actually, the same wisdom applies to most of conventional programming language.
E.g. in Java, if one got an IOException, SQLException, or Security permission
related Exception, there are only few things that a Java application programmer
can do / should do (similar to above).
About "Reason 2: When to judge if a reply is missing":
we should expect a fault handler to send a reply.
Yes, I totally agree with you here. :-)
Our intended behavior are actually very similar. :-) ... I guess the
related text in my previous email writeup is muddled. Sorry for the
not-organized enough text.
Let me add some clarification and refinement here:
There are two
checkpoints to decide whether a bpws:missingReply fault needs to be thrown in a
the normal execution of the scope (S2) is finished but before the scope is
considered completed and the fault handlers of the scope (S2) are
uninstalled, if no fault has been thrown to the scope (S2) during the
the execution of a fault handler of the scope (S2) is finished, if a fault
has been thrown to scope (S2) during the normal execution of the scope
(S2), and that fault triggers the fault handler of the scope (S2), and no
fault has been thrown by execution of the fault handler
The bpws:missingReply fault thrown by missingReply
checkpoint logic in
the case #1 will be caught by a fault handler at the scope (S2)
which matches bpws:missingReply fault, if there is one.
If the triggered fault handler (either
by bpws:missingReply fault or other kinds of fault) does not
generate proper replies to
any open IMAs, a missingReply fault MUST be thrown. This is the case #2 checkpoint
case #2, there is NO an infinite loop situation, because any
faults triggered or thrown by a fault handler (e.g. <rethrow>
activity) will NOT be caught by any fault handler of the same scope (S2)
and they can only be caught by its ancestor scopes (e.g. S1).
- If a
fault is thrown either during the normal execution of the scope (S2),
checkpoint logic of case #1 will not be executed. That implies, if such a
fault happens and the scope (S2) does not have a matching fault handler,
this fault will be propagated to the parent scope (S1) and it will
overshadow overall missingReply logic.
- If a
fault is thrown or rethrown during the execution of a fault handler of the
scope (S2), checkpoint logic of case #2 will not be executed. That
implies, if such a fault happens, this fault will overshadow missingReply
logic of case #2.
Here is a fragment of process definition that illustrates the relationship of scope
S1 and S2 described above:
<partnerLink name="pl1" ... />
<receive partnerLink="pl1" ... />
<!-- receive without reply -->
Note: The bpws:missingReply fault is thrown by scope S2 to scope S2 itself.
[I highlighted the clarification changes in GREEN.]
To summarsize, we agree more than disagree. :-) ....
Case #2 is where the fault is thrown by S2 to S1.
I am merely adding one more differentiated checkpoint (case #1) to allow the
fault thrown by S2 to S2 to achieve the semantics of scope-modularity and
finer-grain repair and compensation. (IMHO, that is very important for
I hope I have explain my intended behavior better this time. :-)
More thoughts on this topic ... ? :-)
Yuzo Fujishima wrote:
Alex Yiu wrote:
Hi Danny and Chris,
Please see inline.
*Q1*: /have the process' faultHandlers been
Answer: As I mentioned in the my previous email: (please see the example)
I prefer the direction of which: the fault is thrown by scope S2 to scope S2.
I am not a big fan of this "S2 to S2" semantics for
the following reasons:
Reason 1: Credibility of the use case.
I am not convinced that there are (many) cases where
scope S2 fails to reply without throwing a fault (except
missingReply). If S2 does, it should be a programming
error rather than a runtime error.
More likely are, in my opinion, the cases where
scope S2 fails to reply due to some fault.
For such cases,
S2 should define a fault handler to catch the fault and
send a reply there.
Not catching the cause fault and instead waiting for the
missingReply to occur doesn't seem to be a good programming
practice. The language should not promote that.
Reason 2: When to judge if a reply is missing.
A missingReply should be thrown only after the whole execution
of the scope S2, including the fault handlers, completed
without sending a reply. (As explained in the example for Reason 1,
we should expect a fault handler to send a reply.)
Then the natural destination of the missingReply fault should be
the parent of S2, i.e., S1.