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

From
Trickovic, Ivana <>
Date
2004-09-13T15:40:53+00:00
ID
Thread
RE: [wsbpel] Issue 6 - Rough draft of proposal for vote
Alex,

 

Regarding 
syntax: 

(1) 
I do not see why not. An expression must evaluate to an integer.

(2) 
Indeed.

(3) 
Agree.

 

Regarding 
function isCompleted():

The 
proposal allows a completionCondition to be based on process variables (see 
attribute expression). The idea of 
function isCompleted('activity_name') is to be able to check 
the state of any activity enclosed with a flow activity. The function does not 
have to be specific to the flow activity. Activity <flow> with completion 
condition is just an example, which motivates to define it. The execution of an 
activity does not necessarily end modifying a process variable. 

 

 

Regarding 
the IgnoreFaults semantics:

I 
agree that element <ignoreFaults> looks quite similar 
to <faultHandlers> but has quite different behavior. It is indeed the 
most controversial part of the proposal. Maybe we should start with the problem 
we are trying to resolve.

 

The 
specification is currently saying (see section 13.4): "... When a fault handler 
is present, it is in charge of handling the fault. It might rethrow the same 
fault or a different one, or it might handle the fault by performing cleanup and 
allowing NORMAL PROCESSING to continue in the enclosing scope.... "

 

Let's 
take a look at the following example - it is a "normal" flow activity (without a 
completion condition).

 

<flow>

 

   <scope name="A">

      
<faultHandlers>

         
<catch name="tns:my_fault">

            
<empty/>

         
</catch>

      
</faultHandlers>

      
<compensationHandler name="C">

      
...

      
</compensationHandler>

      <sequence 
name="X">

      ...

      
</sequence>

   </scope>

 

   <scope name 
="B">

   ...

   </scope>

 

</flow>

 

The 
flow activity will complete as soon as all enclosing activities/scopes complete. 
If fault "tns:my_fault" is thrown within sequence X it will cause the 
termination of the sequence (all active enclosing activities) and will be 
caught by the fault handler defined in the scope A. The fault handler will do 
nothing, the scope A will be deemed as ended abnormally 
and compensation handler C will not be installed. The flow element will 
count that the scope completed and continue with normal processing. 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. So I do not see how we can distinguish the 
case of "N out of N" (current semantics of the flow activity) and "M out of 
N".

 

Maybe 
one way would be to use some process variables, for example (maybe this is also 
your suggestion):

 

<variables>

   <variable name="incompleteA" 
type="xsd:boolean"/>

   <variable name="incompleteB" 
type="xsd:boolean"/>

<variables>

<assign>

   
incompleteA="false"

</assign>

<assign>

   
incompleteB="false"

</assign>

<flow>

   
<completionCondition>

   ...

   
</completionCondition>

   <scope 
name="A">

   
<faultHandlers>

      <catch 
name="tns:my_fault">

         
<assign>

            
incompleteA="true" 

         
</assign> 

         
<empty/>

      
</catch>

   
</faultHandlers>

    <compensationHandler 
name="C">

      
...

    
</compensationHandler>

    <sequence 
name="X">

      
...

     
</sequence>

   
</scope>

   <scope name 
="B">

   ....

   
</scope>

</flow>

 

So, 
if sequence A experience some problem and fault tns:my_fault is thrown, fault 
handler local to scope A will make sure that the flow activity may continue with 
the normal processing and will at the same time identify that the scope A ended 
abnormally. This approach is also possible but it requires a lot of 
"programming" and users have to be aware of this kind of pattern. I prefer more 
declarative approach even if it requires more time to give clear wording. 

 

Regards,

 

Ivana

  
-----Original Message-----
From: Alex Yiu 
  [mailto:]
Sent: Montag, 13. September 2004 
  08:01
To: Trickovic, Ivana
Cc: Axel Martens; Frank 
  Leymann; Dieter Roller; Dieter Koenig1; ''; 
  ''; ''; Alex 
  Yiu
Subject: Re: [wsbpel] Issue 6 - Rough draft of proposal for 
  vote

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: 
    
      
Do we want to allow expression for branch attribute? instead of just a 
      constant integer? 
      
We may need to some minor syntax adjustment for expression attribute 
      because we have passed Isseu 13 already. 
      
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. 
    
      
It turns <flow> into a semi-<scope> like construct 
      
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: 
      ''; Trickovic, 
      Ivana; ''; ''; 
      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:  
        

        
          
          

            Alex Yiu <> 
              
              
09/10/2004 12:10 AM 

            
              
                
                

                  
                    
To

                  Alex Yiu <> 
                  

                

                  
                    
cc

                  "Trickovic, 
                    Ivana" <>, 
                    Axel Martens/Watson/IBM@IBMUS, "''" 
                    <>, 
                    "''" 
                    <>, 
                    "''" 
                    <>, 
                    Alex Yiu <> 
                  

                

                  
                    
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]