Hi Matthieu,

> Ok, let's see with an example that I hope will be better than the last
> one:
> parrallel {
>   a;
>   if (...) {
>     signal(first);
>   } else {
>     signal(second);
>   }
> } and {
>   c;
>   join(first);
>   d;
> } and {
>   join(second);
>   e;
> } and {
>   join(first, second, "$first or $second");
>   f;
> } and {
>   join(first, second, "$first and $second");
>   g;
> }

> When reading this code, what I expect is the following:

That's what BPEL does with its links.

> The next step is to see which BPEL translation will comply with those
> expectations. I think this one would work:

Why do you put fault handlers? Why do you add "empty" activities?
OK, you hae suppressJoinFailure set to "no". Then your code is right.

I think in terms of graph-oriented programming. I draw a graph using labeled
nodes and labeled edges. In BPEL, the nodes are activities (with join
conditions) and the edges are links (with transition conditions). I know,
that programmers are not used to graph-oriented programming at all.

Maybe that issue can be solved by introducing the "suppressJoinFailure"
attribute in simPEL? To have two different kinds of mapping?

According to implications of the suppressJoinFailure attribute in BPEL, it
is IMHO not a matter of optimizing the code. suppressJoinFailure="yes"
activates dead-path elimination, which has a huge impact on the evaluation
of transition conditions and thrown faults. If there are container
activities, where suppressJoinFailure is "yes" and other activities, where
suppressJoinFailure is set to "no" and links connect activities inside the
container activities, things get even worse. I don't believe that a "smart
compiler" can just optimize to get the same results (or the BPEL code gets
really ugly)... BPEL introduced the attribute by intention and not by
accident. I don't think one can just ignore that fact. Even if I think, such
an idea is nice. But when thinking of a translation of BPEL to simPEL,
things can get really complicated and not manageable. All in all, I think, a
complete mapping from BPEL to simPEL is a must.

The BPEL code I'd expect is follows:

<flow suppressJoinFailure="yes">
  <links>
    <link name="first"/>
    <link name="second"/>
  </links>
  <sequence>
    <a/>
    <if>
      <condition>...</condition>
      <empty>
        <sources><source linkName="first"/></sources>
      </empty>
      <else>
        <empty>
          <sources><source linkName="second"/></sources>
        </empty>
      </else>
    </if>
  </sequence>

(up to here I agree to translate it to empty. - And now your "optimization")

  <sequence>
    <c/>
    <d>
      <targets>
        <joinCondition>$first or $second</joinCondition>
        <target linkName="first" />
        <target linkName="second" />
      </targets>
    </d>
  </sequence>

  <e>
    <targets>
      <joinCondition>$second</joinCondition>
      <target linkName="second" />
    </targets>
  </e>  
      
  <f>
    <targets>
      <joinCondition>$first or $second</joinCondition>
      <target linkName="first " />
      <target linkName="second" />
    </targets>
  </f>  

  <g>
    <targets>
      <joinCondition>$first and $second</joinCondition>
      <target linkName="first " />
      <target linkName="second" />
    </targets>
  </g>  
</flow>


But even that code is bloated.

Having graph-based modeling in mind, I think, the original process should
read as follows:

parrallel {
  a;
  signal(first, "...");
  signal(second, "not ...");
} and {
  c;
  join(first);
  d;
} and {
  join(second);
  e;
} and {
  join(first, second, "$first or $second");
  f;
} and {
  join(first, second, "$first and $second");
  g;
}

And that translates to following code:

<flow suppressJoinFailure="yes">
  <links>
    <link name="first"/>
    <link name="second"/>
  </links>

  <a>
    <sources>
      <source linkName="first"><transitionCondition="..." /></source>
      <source linkName="second"><transitionCondition="not ..." /></source>
    </sources>
  </a>

(continued as in the above BPEL code)

> There are also cases where the links source and target could be carried by
the preceding, following or
> parent activity instead of creating an empty.

I'd ALWAYS put them to the preceding (signal) and the following (join)
activity.

What situations do you have in mind where such "glueing" is not possible? Is
it the beginning of a sequence? 

There, following syntax should be allowed:

and join(l1) {
  join(l2);
  c;
  d;
}

That translates to

<sequence>
  <targets>
    <target linkName="l1" />
  </targets>
  <c>
    <targets>
      <target linkName="l2" />
    </targets>
  </c>
  <d />
</sequence>

Cheers,

Olly



Reply via email to