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

From
<>
Date
2004-09-13T00:12:54+00:00
ID
Thread
RE: [wsbpel] Issue 6 - Rough draft of proposal for vote
Hello 
Ivana, 

 

Could 
you please clarify the following paragraph:

 

"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."

 

In 
this paragraph when you say "did not complete",  do you mean "did 
not complete successfully". I am assuming the faults will 
be generated ONLY by activities that are actually completed and not 
by activities still in RUNNING state?

 

As 
I understand a BPEL process engine would only evaluate the 
<completeCondition> for a process instance everytime an activity within in 
the <flow> completes (SUCCESSFULLY or with a FAULT). 

 

thanks,

-Vinky 

 

  

  
-----Original Message-----
From: Trickovic, Ivana 
  [mailto:]
Sent: Saturday, September 11, 2004 
  5:10 PM
To: Alex Yiu; Axel Martens
Cc: Frank Leymann; 
  Dieter Roller; Dieter Koenig1; ''; ''; 
  ''
Subject: RE: [wsbpel] Issue 6 - Rough 
  draft of proposal for vote

  

  
 

  
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]