Re: [wsbpel] Issue 6 - Rough draft of proposal for vote

From
Alex Yiu <>
Date
2004-09-14T04:21:43+00:00
ID
Thread
Re: [wsbpel] Issue 6 - Rough draft of proposal for vote
Hi, Yaron,

Don't get me wrong. :-) 

I don't want an over-engineered complete condition proposal either.

If you read my emails again, you can see: 

  
I am for completionCondition (including the branchCondition
version)

  
I am not so sure about "isComplete()" function value. 

  

  
IMHO, ignoreFault is not necessary and it does not look like a
good idea. (I feel that it is a "tail wagging the dog" situation). 

  

Basically, completionCondition (and branchCondition) is an extended
version of your orJoin="yes" proposal (eq. to branch="1"). That offers
a very nice high-level abstraction of a complete condition, that can be
applied to <flow>, serial and parallel version of forEach. That
is a declarative approach. 

On the other hand, "break" or its equivalents offers an imperative
approach. 

I think we should try to enable both, if feasible. Because, they are
for different audiences. The declarative approach is more for business
analysist. The imperative approach is more for programmers who wish to
control fine details on how to end a flow. 

The only catch of "break" is we need to nicely define the following: 

  
the target of the "break"-jump (while, switch, scope, flow)?

  
its effect on sibiling flows, the compensation/fault handler
states of parent scopes, the links of parent activities

  

Anyway, that will belongs to Issue 142 discussion thread. 

Thanks!

Regards,

Alex Yiu

Yaron Y. Goland wrote:

I believe
that the complexity of the current proposal is well above the
capabilities of what I expect to be the average BPEL programmer.
Completion conditions, ignorable faults, new XPATH functions, etc.
introduces a lot of complexity that I believe that average BPEL
programmer would not be interested in dealing with.
  

  

We know from many decades of language experience that average
programmers can deal with break/continue. I know from at least our own
experience at BEA that users can deal with the concept of a flow where
a break in the flow results in the other members of the flow being
terminated in the BPEL meaning of the term.
  

  

Defining a break activity and specifying that if break is used in the
context of flow then this means that the flow activity ends and any
uncompleted members of the flow are terminated would both fit directly
into BPEL's existing syntax and semantics and I believe be simple
enough that the average programmer can handle it. I would therefore
offer break (and it's relative 'continue') as an alternative.
  

  

    Thanks,
  

  

        Yaron
  

  

Alex Yiu wrote:
  

  

  

Hi,
    

    

Ivana, thanks for sending out this proposal.
    

I believe a number of us (including me) like the
<completionConditon> construct from your proposal high level
speaking.
    

    

After reading the proposal, I guess we need to work on a number of
details. I would like to ask a few questions / mention a few points:
    

    

    * Minor syntax and semantics questions :
    

          o Do we want to allow expression for branch attribute?
instead
    

            of just a constant integer?
    

          o We may need to some minor syntax adjustment for expression
    

            attribute because we have passed Isseu 13 already.
    

          o If answers to the above question are yes, then the
condition
    

            syntax may become a choice (xsd:choice) of the following
two:
    

            <condition
    

           
expressionLanguage="anyURI"?>boolean-expression</condition>
    

            <branchCondition
    

           
expressionLanguage="anyURI"?>integer-expression</condition>
    

    

    * About completionConditionFailure : it looks like a nice idea so
    

      far ...
    

    

    * About the new "isCompleted()" function :  I am not against this
    

      function. But, I tend to think there are usually BPEL variables
    

      being modifed as the execution result of a flow activity. (See
the
    

      train-or-plane-and-hotel example). Is it more typical to have
    

      completionCondition to be evaluated on those variables?
    

      Also, after the completion of the whole flow, it is not uncommon
    

      for people to have logic to find out which branch is finished
    

      (especially when "or" is involved in the condition). The
    

      "isComplete()" function would be available only within the
    

      completionCondition within the flow. People may get confused and
    

      attempt to use the "isComplete()" function outside the flow. If
    

      the completionCondition relies on variables, the same logic is
    

      applicable outside of the flow.
    

    

    * About the IgnoreFault semantics: I recall this ignoreFault idea
    

      back to March F2F. With ignoreFault semantics, it essentially
    

      introduces two brand new semantics.
    

          o It turns <flow> into a semi-<scope> like
construct
    

          o It adds this new "ignoreFault" semantics: which catches
    

            certain fault and the catching action will not cause any
    

            scope to be marked as faulted.
    

    

    I tend to think this "ignoreFault" functionality has quite a heavy
    

    weight impact to <flow> and fault handling picture in BPEL.
If there
    

    is an alternative way to achieve similar business logic, I would go
    

    for the alternative way.
    

    

    Quoted from Ivana's email:
    

    " Not all activities must complete in order the enclosing flow
    

    activity to complete. The way to identify that an enclosed activity
    

    did not complete is to propagate faults. "
    

    

    I agree with the first sentence. But, I am not sure that
propagating
    

    fault is the only way to identify an enclosed activity did not
    

    complete. I would rather use a scope as an activity enclosed by
    

    flow. If we wish to suppress any minor fault which happens during
    

    the execution of the scope, then we can just add a fault handler.
If
    

    the fault that happen, the scope will be marked as "faulted".
    

    

    The completeConditon can identify the "incomplete" state of the
    

    scope by two ways:
    

    

        * completeCondition can be evaluated based on BPEL variables,
    

          which are set to "incomplete" state by pre-flow
initialization
    

          or related fault-handler logic.
    

        * branch-based condition will interprete a faulted scope as
    

          "incomplete" branch and will not count them into the required
    

          N branches.
    

    

    This will allow us to suppress minor fault with or without the
    

    <completionCondition> construct. Please see the following
example.
    

    It is already legal and working today. It shows how to suppress
    

    "foo:barFault" without the <completeCondition> construct
    

    

    <flow>
    

       <scope name="A">
    

          <faultHandler>
    

             <catch faultName="foo:barFault" ... > ...
</catch>
    

          </faultHandler>
    

          <sequence>
    

             ...  <invoke name="doA" ... /> ...
    

          </sequence>
    

       </scope>
    

       <scope name="B"> ... <!-- similar to A --> ...
</scope>      </flow>
    

    

    If the invoke of "doA" triggers "foo:barFault", the scope "A" will
    

    be marked as faulted. On the other hand, scope "B" will be allowed
    

    to continue and complete. After scope "B" is completed, the
    

    compensation handler of scope "B" will be installed. And, the
    

    overall execution of flow is still considered a normal completion.
    

    

    I hope I have illustrated we can achieve similar logic without
    

    introducing a new "ignoreFault" construct and concept to BPEL.
    

    

    What "completionCondition" does should be just providing a way to
    

    pro-actively cancel/terminate other flows without waiting to them
to
    

    complete or to be faulted.
    

    

    * About "Cancel-other-flows":   (Let me consolidate what I am
    

      leaning towards so far.) We need to formal define the notion of a
    

      " cancel-other-flows " mechanism. This mechanism is specified and
    

      attached to <flow> construct (and future parallel forEach
    

      construct).  When this mechanism is triggered by one of parallel
    

      flows, it will cancel/terminate other parallel flows which are
    

      still running, after the triggering flow is completed. If the
    

      other flow activties are scope activities, the scope will be
    

      marked as cancelled.
    

    

      This mechanism will be triggered upon the completionCondition is
    

      evaluated to be true.
    

    

      [Note: (a) since this mechanism is triggered by without using any
    

      fault directly. This will again decrease the need of
"ignoreFault"
    

      construct (b) This mechanism will affect the wordings of Issue
135
    

      to an extent.]
    

    

      [Question: again, should we enforce scope-only activity when
    

      completionCondition is used? I tend to say yes.]
    

    

    

    

Thank you all for following and reading this email thread!!!
    

    

    

    

Regards,
    

Alex Yiu
    

 
    

    

    

Trickovic, Ivana wrote:
    

    

     
      

      

Here is a proposal for the completion condition - it addresses some
issues not tackled so far (at least not in case of
<completeCondition>). It is a version of the proposal for
completion condition for the bundle element. This proposal includes
comments from many people including Frank Leymann, Dieter Koenig,
Dieter Roller and Satish Thatte. It does not mean that they completely
support the proposal - they may have issues with any part of the
proposal.
      

      

 
      

      

 
      

      

Completion condition
      

      

=====================
      

      

The current semantics of the flow activity is that it waits for all
concurrent activities to complete. The completion also means that an
enclosed activity/scope may end abnormally or be skipped (e.g. the join
condition of the activity evaluated to false). If a fault is thrown
within an enclosed activity/scope and one of the local fault handlers
catch the fault (and does not rethrow the fault), the enclosed
activity/scope will be deemed to be completed (although ended
abnormally). If a fault is not caught by any local fault handler (or is
rethrown) the flow activity will terminate all active concurrent
activities and corresponding fault handler may be initiated.
      

      

 
      

      

A completion condition for the flow activity is needed for scenarios
where not all concurrent activities of a flow activity must complete in
order the flow activity to complete. Note: We are not talking about
"successful completion" of enclosed concurrent activities because that
would not be consistent with the semantics of the current flow
activity.
      

      

 
      

      

The completion condition may have different flavors, such as:
      

      

(1) N out of M
      

      

(2) The two most important requests completed
      

      

(3) A Boolean condition operating upon process variables
      

      

 
      

      

Not all activities must complete in order the enclosing flow activity
to complete. The way to identify that an enclosed activity did not
complete is to propagate faults. We may distinguish between severe
faults and those that can be ignored. Severe faults cause the enclosing
flow activity (or more precisely, enclosing scope) to terminate the
flow activity, including all active concurrent activities, and
corresponding fault handler may be initiated. Other faults may be
ignored - the flow activity is "informed" that a concurrent activity
did not complete but still allows other active concurrent activities to
continue with execution.
      

      

 
      

      

Ignore semantics
      

      

=================
      

      

Faults thrown within enclosed concurrent activities/scopes and not
handled by local fault handlers are rethrown. Enclosing <flow>
element decides which of these rethrown faults can be ignored. This new
"ignore" semantics should be part of the completion condition and
should apply to all enclosed activities. This new semantics does not
introduce a new fault handling mechanism. It is needed for identifying
how many of the enclosed activities failed.
      

      

 
      

      

 
      

      

Proposed syntax
      

      

================
      

      

<flow standard-attributes>
      

      

   standard-elements
      

      

   <completionCondition/>?
      

      

   <links>?
      

      

      <link name="ncname">+
      

      

   </links>
      

      

   activity+
      

      

</flow>
      

      

 
      

      

<completionCondition>
      

      

   <conditions branch="xsd:integer"?
      

      

               expression=xpath?/>?
      

      

   <ignoreFaults>?
      

      

      <fault name="qname"? value="ncname"?/>*
      

      

      <ignoreAll/>?
      

      

   </ignoreFaults>
      

      

</completionCondition>
      

      

 
      

      

Attribute branch is used to specify a condition of flavor "wait for /N/
out of /M/ activities to complete", or more precisely value N.
Attribute expression is used to specify a Boolean condition operating
upon process variables or a condition of flavor "the two most important
requests completed".
      

      

 
      

      

Both conditions ( branch and expression) may be specified at the same
time. They will be checked when one instance of the scope activity
reaches the end. If at least one condition evaluates to true all active
instances will be terminated.
      

      

 
      

      

Element <ignoreFaults> specifies faults that may be ignored.
Element fault is used to specify a fault which may be ignored (fault
name and fault data may be specified). Element <ignoreAll> would
mean that all faults thrown/rethrown by any concurrent activity/scope
may be ignored. If this element is specified <fault> element must
be omitted.
      

      

 
      

      

Completion condition failure
      

      

=============================
      

      

A new standard fault, e.g. completionConditionFailure, should be
introduced to notify that the completion condition of a flow activity
evaluated to false (note: all concurrent activities have been
completed). The fault is thrown in the scope enclosing the flow
element.
      

      

 
      

      

Completion condition and links
      

      

==============================
      

      

There should be no difference between a flow activity with a completion
condition and a flow activity without completion condition. For
example, if the completion condition fails all links leaving the flow
activity should have value "false" (or be reverted to a negative
status).
      

      

 
      

      

There are just a few additional rules:
      

      

(1) Let's assume enclosed activity A is the source of a link. If the
completion condition evaluates to true and activity A is not completed
it will be terminated and the value of the link will be set to "false".
      

      

(2) Let's assume enclosed activity A is the source of a link and the
activity failed but the fault is "ignored" by the enclosing flow
activity. The value of the link will be set to "false".
      

      

 
      

      

New function for completion condition of flavor "the two most important
requests completed"
      

      

============================================================================================
      

      

For completion conditions of flavor "the two most important requests
completed" standard attribute "name" must be specified for all
enclosing activities in order to be able to distinguish them. In
addition a new function, e.g. isCompleted('activityName') must be
introduced. The semantics of the function is: if activity completed
successfully the function returns value true.
      

      

 
      

      

Example
      

      

    <completionCondition expression=
      

      

           "isCompleted('A') AND isCompleted('B')"         

     </completionConditions>
      

      

 
      

      

 
      

      

Regards,
      

      

 
      

      

Ivana
      

      

 
      

      

    -----Original Message-----
      

    *From:* Alex Yiu [mailto:]
      

    *Sent:* Samstag, 11. September 2004 00:49
      

    *To:* Axel Martens
      

    *Cc:* ' <mailto:>';
Trickovic,
      

    Ivana; '
<mailto:>';
      

    '
      

    <mailto:>'; Alex Yiu
      

    *Subject:* Re: [wsbpel] Issue 6 - Rough draft of proposal for vote
      

      

      

    Hi, Axel,
      

      

    Thanks for liking parts of my proposal so far.
      

    Actually, the idea of my proposal is borrowed from a part of
      

    presentation from Ivana and Dieter Roller in March F2F. I just
      

    generalize it to apply to <flow> also.
      

      

    About using links or not:
      

    I don't have a huge opposition to Axel's proposal which enriches
      

    the semantics of joinCondition evaluation. However, it is not that
      

    difficult for people to make mistakes in joinCondition. Look at
      

    the 2-out-of-3 example. The join condition already gets so
      

    complicated. If people make a mistake in their joinCondition, the
      

    whole flow can get struck for no good reasons. (The
      

    completeCondition approach will less likely to have the whole flow
      

    struck. Because, it does not introduce a new parallel activity in
      

    the flow). But, if this is what Petri-net-oriented and
      

    control-link-oriented audience really want, I can accept it in a
      

    sense, as long as this is not the only way to achieve similar
      

    business logic.
      

      

    About static vs dynamic parallelism:
      

    Static parallelism is basically <flow> construct in BPEL.
Dynamic
      

    parallelism is "parallel forEach" or "bundle". Issue 4 and 147 are
      

    related issues.
      

    http://www.choreology.com/external/WS_BPEL_issues_list.html#Issue4
      

   
http://www.choreology.com/external/WS_BPEL_issues_list.html#Issue147
      

      

    About "Terminating still running tasks versus proceeding in
      

    control flow while those tasks are
      

    still running":
      

    I am not 100% that I understand your question. Let me try to
      

    answer it anyway. The completeCondition is about triggering
      

    termination of still-running tasks. The "proceeding in control
      

    flow" (if I understand you correctly) will be handled by an outter
      

    flow. [I guess it is related to (hotel and (train or plane))
flow??]
      

      

    About changes of "forcedTermination" fault handler:
      

    If you got a chance to see some recent emails on Issue 135, Satish
      

    has recently suggested to remove the notion "forcedTermination"
      

    fault and replace its fault handler with cancelHandler. Frank,
      

    Yaron, Edwin and I all agree with this direction. Because,
      

    overloading fault with the concept of "forcedTermination" is a
      

    "false economy" and it creates quite a bit of unnecessary
confusion.
      

      

    I don't think we should go back to this route or even further
      

    overload the "forcedTermination" fault handler semantics. Because,
      

    fault handling is way too generic and the changes you mentioned
      

    will create even more confusion. (e.g. Will this change of marking
      

    as "completed" apply to all "forcedTermination" fault handler /
      

    cancel handler of all scopes? )
      

      

    I guess most of us agree that we should have a new mechanism to
      

    kill / do an early completion of a flow in a nice and clean way.
      

    However, overloading a standard fault handler does not seem to be
      

    the best one. I would rather introduce a construct which is very
      

    specific to <flow> or parallel-forEach. For example, this
      

    <completeCondition> construct or maybe a new activity called
      

    <completeFlow />.  I will send out more emails on joint
thinking
      

    of both Issue 6 and Issue 135.  Please stay tuned.
      

      

      

    Thanks!
      

      

      

      

    Regards,
      

    Alex Yiu
      

      

      

    Axel Martens wrote:
      

      

      

    Hi,
        

        

    I like the simplicity of the syntax of Alex's proposal. Although,
        

    for me it is quite easy to model in terms of links and join
        

    conditions, and I want to keep my proposal alive (because of the
        

    minimal changes to BPEL's syntax and semantics), it looks like a
        

    nice macro to provide more convenience to the customers.
        

        

    Alex, could you shortly explain to me, what do you mean by static
        

    and dynamic parallelism? How do you handle the two different cases
        

    after evaluating the completeCondition: Terminating still running
        

    tasks versus proceeding in control flow while those tasks are
        

    still running (Sorry, I missed your previous emails)?
        

        

    I agree to Alex's opinion, that we need a mechanism to kill
        

    parallel flow nice and clean. This could be done either by a new
        

    mechanism which does not throw a fault or by changing the way
        

    fault are handled. I have discussed already an example of the
        

    second case with Ivana, and I like to tell you, what I have in
        

    mind. Look at the following example:
        

        

    <scope name="scopeFlow">
        

      ...
        

      <flow>
        

        <link name="linkA"/>
        

        <link name="linkB"/>
        

        

        <scope name="scopeA">
        

          ...
        

          <invoke name="A" ...>
        

            <source linkName="linkA" ...>
        

          </invoke>
        

        </scope>
        

        

        <scope name="scopeB">
        

          ...
        

          <invoke name="B" ...>
        

            <source linkName="linkB" ...>
        

          </invoke>
        

        </scope>
        

        

        <throw name="C" faultName="bpws:forcedCompletion"
        

               joinCondition="linkA OR linkB"
        

    joinEvaluation="immediate">
        

            <target linkName="linkA" ...>
        

            <target linkName="linkB" ...>
        

        </throw>
        

        

      </flow>
        

    </scope>
        

        

    First, I explain the situation: In the example above, activity C
        

    will be executed if one of the two activities A and B was
        

    successfully completed. Activity C throws the fault
        

    "forcedCompletion". Like each other fault, this forces the scope
        

    "scopeFlow" to terminate still running activities. Assume, there
        

    was a fault handler defined in this scope which catches the fault
        

    "forcedCompletion" (omitted in here), the process continues after
        

    scope "scopeFlow". A problem arises, if scope "scopeFlow" should
        

    be compensated. Because it was exited from a fault handler, no
        

    compensation handler was installed.
        

        

    Now, I explain my solution: In the example, I have chosen a new
        

    "standard" fault name: "forcedCompletion". The only necessary
        

    change is to allow a fault handler that catches this fault to
        

    install a compensation handler for the same scope, i.e. to mark
        

    the scope "scopeFlow" as "completed" instead of "exited".
        

        

    The standard compensation mechanism will only undo those
        

    ("scoped") activities within the scope, which actually have been
        

    successfully completed, i.e. scopeA or scopeB or may be both.
        

        

    Axel.
        

    ----------------------------------------
        

    Axel Martens
        

        

    Post Doc Researcher
        

    Component Systems Group
        

    IBM TJ Watson Research Center
        

    Hawthorne, NY (USA)
        

    Phone: (914) 784-7480
        

    E-mail:  <mailto:>
        

        

        

    *Alex Yiu <>
<mailto:>*
        

        

    09/10/2004 12:10 AM
        

        

        

    To
        

        Alex Yiu <>
<mailto:>
        

    cc
        

        "Trickovic, Ivana" <>
        

    <mailto:>, Axel
Martens/Watson/IBM@IBMUS,
        

    "''" <mailto:%%27>
        

    <> <mailto:>,
        

    "''"
<mailto:%%27>
        

    <> <mailto:>,
        

    "''"
        

    <mailto:%%27>
        

    <>
        

    <mailto:>, Alex Yiu
        

    <> <mailto:>
        

    Subject
        

        Re: [wsbpel] Issue 6 - Rough draft of proposal for vote
        

        

        

        

        

        

        

        

        

        

        

    Hi,
        

        

    Here are some examples how to use completeCondition to express
        

    similar business logic in Axel's previous email:
        

        

    (A) "Select one out of three" example:
        

    <flow>
        

       <completeCondition *branch="1"* />
        

       <invoke name="CheckAirlineA" ... />
        

       <invoke name="CheckAirlineB" ... />
        

       <invoke name="CheckAirlineC" ... />
        

    </flow>
        

        

        

    (B) "Select two out of three" example:
        

    <flow>
        

       <completeCondition *branch="2"* />
        

       <invoke name="AskRefereeA" ... />
        

       <invoke name="AskRefereeB" ... />
        

       <invoke name="AskRefereeC" ... />
        

    </flow>
        

        

    As you guys can see, the completeCondition declaration is very
        

    straight forward and simple. No complicated links and
        

    joinCondition usage.
        

        

    (C) "(Plane or Train) and Hotel" example: It would become two
        

    flow constructed (nested).
        

        

        

    <assign> ... <to variable="planeResult"></assign>
        

      <!-- initialize "planeResult" with NOT-OK value -->
        

    <assign> ... <to variable="trainResult"></assign>
        

      <!-- initialize "trainResult" with NOT-OK value --> *
        

    <flow name="checkIterinary">*
        

       *<flow name="PlaneOrPlane">*
        

          <completeCondition>
        

               fn:planeOK(planeResult) *or* fn:trainOK(trainResult)
        

          </completeCondition>
        

          <invoke name="CheckPlane" outputVariable="planeResult" ...
/>
        

          <invoke name="CheckTrain" outputVariable="trainResult" ...
/>
        

       *</flow> *
        

       <invoke name="checkHotel" /> *
        

    </flow>
        

    <switch name="bookingSwitch">*
        

       <case>
        

           <condition>
        

           (fn:planeOK(planeResult) *or* fn:trainOK(trainResult))
        

    *and* fn:hotelOK(hotelResult)
        

           </condition>
        

           <invoke name="invokeBooking" ... />
        

       </case>
        

       <otherwise>
        

             <invoke name="writeInformation" ... />
        

       </otherwise> *
        

    </switch>*
        

        

        

    Please note that regardless whether we pick a link-oriented
        

    approach or completeCondition approach:
        

        

        * The initialization of result variables are needed because
        

          of potential cancellation of one of the invoke between
        

          train and plane
        

        * The "fn:*()" represents the logic to determine whether a
        

          traveling resource is available. They are used in either
        

          the transitionCondition of links or the condition of
        

          switch/case.
        

        

    As you guys see, we don't need declare to six links. The
        

    completeCondition and case-condition are much simpler and easier
        

    to understand.
        

        

    I attach a diagram to illustrate the above flows.
        

        

    I guess we can still more time in terms of refiniment of
        

    joinCondition evaluation. However, I don't think that should be
        

    the only approach to achieve complete condition related logic.
        

        

        

    Thanks!!!
        

        

    Regards,
        

    Alex Yiu
        

        

        

        

        

    Alex Yiu wrote:
        

        

    Hi,
        

        

    +1 to what Ivana said in general.
        

        

    Few points to add:
        

        

        * Axel's proposed enhancement to control links evaluation
        

          works to an extent for static parallelism  (e.g.
<flow>).
        

          However, control links do not work well in dynamic
        

          parallelism (e.g. "parallel forEach" or "bundle"). I think
        

          the notion of completeCondition (borrowed from Ivana and
        

          DK) is general enough and it should be applied to both
        

          static and dynamic parallelism. A general completeCondition
        

          mechanism will be easier for BPEL users to learn.
        

        * Even in a pure static parallelism case, completeCondition
        

          has much better code clarity. It is more declarative and
        

          easier for BPEL users to understand. It will eliminate
        

          significant amount of joinCondition programming, which may
        

          be error prone. (I will send another email later to show
        

          how completeCondition can be used to express the same
        

          semantics of Axel's example).
        

        * In one of my previous emails, I also tried to use a "macro"
        

          way to illustrate how outstanding running flows can be
        

          cancelled by throwing a fault within a scope. The
        

          illustration has the same compensation handler installation
        

          problem that Ivana has pointed out. The "illustraction
        

          macro" does NOT carry a desirable and intended semantics.
        

          We need to create / describe a new mechanism to cancel
        

          parallel flow without throwing a fault. (That was discussed
        

          briefly between Edwin and me at Oracle).
        

        

        

    Thanks!
        

        

        

    Regards,
        

    Alex Yiu
        

        

        

        

    Trickovic, Ivana wrote:
        

    Axel,
        

         I find the idea interesting. In fact, I was discussing the
        

    completion condition issue with Dieter Koenig during the last f2f
        

    meeting and his suggestion was also to try to resolve this issue
        

    using links. And we identified that several changes need to be
        

    done, including removing restriction for jonCondition, that "the
        

    join condition is evaluated as soon as all incoming links of the
        

    activity are determined" - so definitely "immediate" semantics
        

    needs to be introduced.
        

         I have the following comments on your proposal.
        

    1. In your proposal you are using a fault
        

    (bpws:forcedTermination) to terminate all active parallel
        

    branches. But this changes the outcome of the flow activity. It
        

    will always end abnormally and compensation handler (if it is
        

    defined) will never be installed. Although completion condition
        

    has evaluated to true and needed activities have completed the
        

    enclosing flow activity will end abnormally. Is this really
        

    intended semantics?
        

         2. Your proposal does not address some pain points. For
example,
        

    in case of "N out of M", N<M there many possible "variations":
        

    (A) One enclosed activity may experience problems but the
<flow>
        

    activity may succeed
        

    (B) One of enclosed activities may experience a severe error,
        

    which may have impact on the <flow> activity
        

    The question is what to do with running activities? In the latter
        

    case, reasonable behavior would be: if one enclosed activity does
        

    not succeed other running activities should be cancelled and the
        

    flow activity should try to recover. In the former case, we
        

    should allow active parallel activities to complete their work.
        

    This is not supported in your proposal.
        

         Regards,
        

     

    Ivana
        

        

      
    [stuff deleted]