RE: Syntax of links in simPEL
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 sourcessource linkName=first//sources /empty else empty sourcessource 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=firsttransitionCondition=... //source source linkName=secondtransitionCondition=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
Re: Syntax of links in simPEL
On Sat, Jun 7, 2008 at 5:12 AM, Oliver Kopp [EMAIL PROTECTED] wrote: Hi Matthieu, I'm not sure I'm completely following so please forgive me if I'm off base and feel free to correct me. My understanding of what you're saying is that the way one could understand the snippet above is not the way it actually is. Yes, true. Hence it should be fixed because it's ambiguous. Is that right? Yes, that's right! However, when I read your explanation, you're interpreting everything in terms of links, sourcing and targeting. What we have here aren't links, we have a signal construct and a join construct. With the same semantics. Only different names. --cut: http://ode.apache.org/bpel-simplified-syntax-simbpel.html--- The signal and join instructions are here to model links, --end-- Signal says when something is done, join says when we should hold until something is done. This is a semantics different from BPEL! Yes, by design :) We've learned enough from BPEL to know that all constructs aren't necessarily so great. So if make them more usable, why not? I don't think we should keep things we know suck. So if I just change labels in your example: parallel { put-pizza-in-oven; pizza-cooked; signal(diner-ready); } and { join(diner-ready, beer.temperature 10c); get-beer-in-fridge; drink-beer; } [quoting from your other mail] And if I think in terms of signal and join, it only really makes sense if the entire sequence is skipped. And that's what people are used to in most imperative languages (somewhat like a specialized break). Now for the implementation in BPEL (our poor man's bytecode), I can think of a few ways to encode that behavior. How does your example translate to BPEL? And how are you thinking of a mapping from BPEL to simPEL? Ah yes, sorry, I wrote that too quickly, ignore the join condition as I wrote it. I assume the following: (shortened syntax) flow linksl1/links sequence put-pizza-in-oven; pizza-cooked sourcesdiner-ready-to-consumption/sources; /sequence sequence targetsdiner-ready-to-consumption/targets repeatUntil Determine-beer.temperature; conditionbeer.temperature 10c/condition /repeatUntil get-beer-in-fridge; drink-beer; /sequence /flow I could not use a join conditions, since BPEL only allows links as the only variables in join conditions. --cut-- [SA00073] The expression for a join condition MUST be constructed using only Boolean operators and the activity's incoming links' status values. --end-- Correct. If BPEL had to support that, another expression language for the join condition has to be used. Even though, that is still a violation of SA00073. Even BPEL-J does not allow one to put arbitrary Java-code in the join condition: --cut-- BPEL only allows the XPath expressions that are within join conditions to access link status. The XPath cannot access BPEL variables or any other aspect of the process state. The same restriction applies to snippets used within join conditions. The snippets expressions can only access the Boolean parameters that represent the status of incoming links. ---end-- I won't drink my beer as long as the diner's ready and even when it's ready, I still won't drink it if it's not freshed. I don't think one would expect drink-beer to execute if both conditions aren't satisfied. That means, your process is stalled as long as the beer isn't cold enough. That's OK for your example, but it is not in-line with BPEL dead-path-elimination (DPE) semantics. In contrast to your intended join semantics, a join in BPEL is evaluated as soon as the status of the incoming links is clear. If the join evaluates to false, the activity is skipped (suppressJoinFailure=true). If one does NOT want the activity to be skipped, but a fault to be thrown, suppressJoinFailure has to be set to false. I think, you are aware of that. For those, who read my E-Mail to here and want to read more on DPE: Curbera, Francisco; Khalaf, Rania; Leymann, Frank; Weerawarana, Sanjiva: Exception Handling in the BPEL4WS Language. In: BPM 2003 http://www.springerlink.com/content/yhjyaccdf9g4e0q3/ Or did I completely misunderstood what you were saying? We have to runtime semantics in mind: I have pure BPEL semantics in mind. And I assume, you have some BPMN-semantics in mind. Not really, I try to have in mind a language that would be nice by itself, regardless of the bytecode in which it's going to be compiled into. While trying to have the limitations of the bytecode not leak too much in the language, How are you going to implement joins in Apache ODE? How does that affect BPEL processes? Is there a different navigation for simPEL processes? 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); } }
RE: Syntax of links in simPEL
Hi Alex, However, when I read your explanation, you're interpreting everything in terms of links, sourcing and targeting. What we have here aren't links, we have a signal construct and a join construct. Is it fair to say that signal() is like a BPEL empty with a target, and join() is like an empty with a source? I don't think so: --cut-- parallel { put-pizza-in-oven; pizza-cooked; signal(diner-ready); } and { join(diner-ready, beer.temperature 10c); get-beer-in-fridge; drink-beer; }--edn-- The execution path is from pizza-cooked to get-beer-in-fridge and not the other way round. In addition, this doesn't solve the problem of different join semantics. Viele Grüße, Olly
RE: Syntax of links in simPEL
Hi Matthieu, I'm not sure I'm completely following so please forgive me if I'm off base and feel free to correct me. My understanding of what you're saying is that the way one could understand the snippet above is not the way it actually is. Yes, true. Hence it should be fixed because it's ambiguous. Is that right? Yes, that's right! However, when I read your explanation, you're interpreting everything in terms of links, sourcing and targeting. What we have here aren't links, we have a signal construct and a join construct. With the same semantics. Only different names. --cut: http://ode.apache.org/bpel-simplified-syntax-simbpel.html--- The signal and join instructions are here to model links, --end-- Signal says when something is done, join says when we should hold until something is done. This is a semantics different from BPEL! So if I just change labels in your example: parallel { put-pizza-in-oven; pizza-cooked; signal(diner-ready); } and { join(diner-ready, beer.temperature 10c); get-beer-in-fridge; drink-beer; } [quoting from your other mail] And if I think in terms of signal and join, it only really makes sense if the entire sequence is skipped. And that's what people are used to in most imperative languages (somewhat like a specialized break). Now for the implementation in BPEL (our poor man's bytecode), I can think of a few ways to encode that behavior. How does your example translate to BPEL? And how are you thinking of a mapping from BPEL to simPEL? I assume the following: (shortened syntax) flow linksl1/links sequence put-pizza-in-oven; pizza-cooked sourcesdiner-ready-to-consumption/sources; /sequence sequence targetsdiner-ready-to-consumption/targets repeatUntil Determine-beer.temperature; conditionbeer.temperature 10c/condition /repeatUntil get-beer-in-fridge; drink-beer; /sequence /flow I could not use a join conditions, since BPEL only allows links as the only variables in join conditions. --cut-- [SA00073] The expression for a join condition MUST be constructed using only Boolean operators and the activity's incoming links' status values. --end-- If BPEL had to support that, another expression language for the join condition has to be used. Even though, that is still a violation of SA00073. Even BPEL-J does not allow one to put arbitrary Java-code in the join condition: --cut-- BPEL only allows the XPath expressions that are within join conditions to access link status. The XPath cannot access BPEL variables or any other aspect of the process state. The same restriction applies to snippets used within join conditions. The snippets expressions can only access the Boolean parameters that represent the status of incoming links. ---end-- I won't drink my beer as long as the diner's ready and even when it's ready, I still won't drink it if it's not freshed. I don't think one would expect drink-beer to execute if both conditions aren't satisfied. That means, your process is stalled as long as the beer isn't cold enough. That's OK for your example, but it is not in-line with BPEL dead-path-elimination (DPE) semantics. In contrast to your intended join semantics, a join in BPEL is evaluated as soon as the status of the incoming links is clear. If the join evaluates to false, the activity is skipped (suppressJoinFailure=true). If one does NOT want the activity to be skipped, but a fault to be thrown, suppressJoinFailure has to be set to false. I think, you are aware of that. For those, who read my E-Mail to here and want to read more on DPE: Curbera, Francisco; Khalaf, Rania; Leymann, Frank; Weerawarana, Sanjiva: Exception Handling in the BPEL4WS Language. In: BPM 2003 http://www.springerlink.com/content/yhjyaccdf9g4e0q3/ Or did I completely misunderstood what you were saying? We have to runtime semantics in mind: I have pure BPEL semantics in mind. And I assume, you have some BPMN-semantics in mind. How are you going to implement joins in Apache ODE? How does that affect BPEL processes? Is there a different navigation for simPEL processes? Are you afraid of people making too many typos? ;) Ah, you're right :) Actually without writing anything about it we're already number 5 on Google Yesterday, I got the same result. Today it was not on the first hundred results. Maybe I did a typo? ;) Maybe, simBPEL is the language to use for BPEL semantics and simPEL is the language for enhanced joins and different execution semantics. :-)) Cheers, Olly
RE: Syntax of links in simPEL
Hi Assaf, --cut: http://ode.apache.org/bpel-simplified-syntax-simbpel.html--- The signal and join instructions are here to model links, --end-- Signal says when something is done, join says when we should hold until something is done. This is a semantics different from BPEL! So if I just change labels in your example: parallel { put-pizza-in-oven; pizza-cooked; signal(diner-ready); } and { join(diner-ready, beer.temperature 10c); get-beer-in-fridge; drink-beer; } That depends no what the semantics of the beer (or was it speech?) condition is. In terms of blocking, DPEs, etc, there's added complexity in handling anything but boolean join expressions. Joining only when the beer gets cold is a tricky proposition. But joining when dinner is ready, and then reading the variable and deciding what to do next, that's easy. BPEL can do that, but in BPEL you'll have, in addition to the join condition, also an if/else statement. What is put in the else statement? With your reading, the BPEL code of the second sequence of statements in the above example is sequence if targetsdiner-ready/targets condition beer.temperature 10c /condition get-beer-in-fridge; /if drink-beer; /sequence And if that is translated to simPEL (and no pattern-recognition-magic is done), it looks like follows: join(diner-ready); if (beer.temperature 10c) { get-beer-in-fridge; } drink-beer; Or did I get something wrong? One implication is that the signal statement is bound to the activity before and join to the activity after. E.g.: parallel { a; signal(l1); b; join(l1); c; } translates to: flow sequence a sourcesl1/sources /a b c targetsl1/targets /c /sequence /flow The point of Simpel is to make it easier to write processes. If we insist on one-to-one mapping to BPEL syntax, we're limiting how well it can do that, we should be open to syntactic sugars and other simplifications. Syntactic sugar is fine with me. As long as it can be translated to BPEL :). And that BPEL can be fully translated to simPEL. I'm currently thinking of simPEL profiles. Such as strict and lax: strict insits on a (close) 1:1 mapping to BPEL. lax allows all simplifications... (which may generate a bunch of activities / eventhandlers / ... in a mapping to BPEL) So whenever I look at an example like this, my first question is: would anyone want to do that often enough that it should be considered into the syntax? If not, we have better things to worry about. If yes, are we taking existing BPEL semantics and applying them in more interesting ways, or inventing new semantics? Inventing new semantics has the downside that it takes considerable time, and could easily confuse people moving between the two languages. Doing syntactic sugar on top of existing semantics, not that hard. Fully agree. So I'm wondering what part of this is different semantics and what part is just syntactic sugar. Me too. - I think, it depends on whether the usage of arbitrary variables in join conditions have blocking semantics (as in WS-CDL a blocking workunit) or not (as the translation to if suggests). Cheers, Olly
Re: Syntax of links in simPEL
On Thu, Jun 5, 2008 at 7:20 PM, Assaf Arkin [EMAIL PROTECTED] wrote: On Thu, Jun 5, 2008 at 5:12 PM, Matthieu Riou [EMAIL PROTECTED] wrote: On Thu, Jun 5, 2008 at 5:20 AM, Oliver Kopp [EMAIL PROTECTED] wrote: Hi, We have thought about the syntax of links. As we understand, join and signal belong to the previous element. Assume following example: parallel { a; b; signal(b-to-X); } and { join(b-to-X); c; d; } and { e; signal(e-to-f); f; join(e-to-f); } The link b-to-X connects b and the sequence s2, which contains c and d. The link e-to-f connects e and f in the sequence s3, which contains e and f. The link b-to-X is NOT sourcing from sequence s1, which contains a and d. However, it can be understood like that, because it is the last statement in the sequence. The link b-to-X is NOT targeted at c. However, it can be understood as is, because first links are joined and then an activity is executed. I.e., join on b-to-X and then execute c. - In the above example both interpretations lead to the same execution. But if there is a join condition put on the join(b-to-X), then it is not the same semantics: Assume join(b-to-X, false()), then in the above example, c and d are both not executed, since the join condition of the sequence evaluates to false(). If the other interpretation is assumed, c does not get executed, but d: The sequence is enabled and only c joins on the incoming links. I'm not sure I'm completely following so please forgive me if I'm off base and feel free to correct me. My understanding of what you're saying is that the way one could understand the snippet above is not the way it actually is. Hence it should be fixed because it's ambiguous. Is that right? However, when I read your explanation, you're interpreting everything in terms of links, sourcing and targeting. What we have here aren't links, we have a signal construct and a join construct. Signal says when something is done, join says when we should hold until something is done. What happens if it's not done? In BPEL link is set to false and the join condition throws a fault, which would stop the remainder of the sequence from happening. So far no difference. But you can also suppress the fault, so the activity that depends on something happening is skipped, but the rest of the flow continues. Now it matters what's being skipped: the entire sequence or just the first activity in that sequence? And if I think in terms of signal and join, it only really makes sense if the entire sequence is skipped. And that's what people are used to in most imperative languages (somewhat like a specialized break). Now for the implementation in BPEL (our poor man's bytecode), I can think of a few ways to encode that behavior. Matthieu Assaf In that light I don't think one would get mislead. So if I just change labels in your example: parallel { put-pizza-in-oven; pizza-cooked; signal(diner-ready); } and { join(diner-ready, beer.temperature 10c); get-beer-in-fridge; drink-beer; } I won't drink my beer as long as the diner's ready and even when it's ready, I still won't drink it if it's not freshed. I don't think one would expect drink-beer to execute if both conditions aren't satisfied. Or did I completely misunderstood what you were saying? We have following different proposals: The syntax is inspired by LaTeX, where optional arguments can be put in square braces [...]; We do not want to use additional curly braces {...} to have the links distinguishable of real arguments. 1. Proposal: Our favorite. Reflecting the execution order. [join(...)]? activity [signals]?; parallel { a; b [signal(b-to-X)]; } and [join(b-to-X)] { c; d; } and { e [signal(e-to-f)]; [join(e-to-f)] f; } 2. Proposal: Everything before the activity. [join(...)?, signals?]? activity; parallel { a; [signal(b-to-X)] b; } and [join(b-to-X)] { c; d; } and { [signal(e-to-f)] e; [join(e-to-f)] f; } 3. Proposal: Everything after the activity. (As it is now, but with brackets). Activity [join(...)?, signals?]?; parallel { a; b [signal(b-to-X)]; } and { c; d; } [join(b-to-X)] and { e [signal(e-to-f)]; f [join(e-to-f)]; } What do you think? BTW, could we name simPEL simBPEL to enable googling for it? :-) (And doesn't describe sim(B)PEL *B*usiness Processes? :)) Are you afraid of people making too many typos? ;) Actually without writing anything about it we're already number 5 on Google so I'm not too worried about Googleability (I'm so going to get sued for trademark on this one). http://www.google.com/search?hl=enq=simpelbtnG=Google+Search Matthieu Cheers, Olly, Tammo -- CTO, Intalio http://www.intalio.com
Syntax of links in simPEL
Hi, We have thought about the syntax of links. As we understand, join and signal belong to the previous element. Assume following example: parallel { a; b; signal(b-to-X); } and { join(b-to-X); c; d; } and { e; signal(e-to-f); f; join(e-to-f); } The link b-to-X connects b and the sequence s2, which contains c and d. The link e-to-f connects e and f in the sequence s3, which contains e and f. The link b-to-X is NOT sourcing from sequence s1, which contains a and d. However, it can be understood like that, because it is the last statement in the sequence. The link b-to-X is NOT targeted at c. However, it can be understood as is, because first links are joined and then an activity is executed. I.e., join on b-to-X and then execute c. - In the above example both interpretations lead to the same execution. But if there is a join condition put on the join(b-to-X), then it is not the same semantics: Assume join(b-to-X, false()), then in the above example, c and d are both not executed, since the join condition of the sequence evaluates to false(). If the other interpretation is assumed, c does not get executed, but d: The sequence is enabled and only c joins on the incoming links. We have following different proposals: The syntax is inspired by LaTeX, where optional arguments can be put in square braces [...]; We do not want to use additional curly braces {...} to have the links distinguishable of real arguments. 1. Proposal: Our favorite. Reflecting the execution order. [join(...)]? activity [signals]?; parallel { a; b [signal(b-to-X)]; } and [join(b-to-X)] { c; d; } and { e [signal(e-to-f)]; [join(e-to-f)] f; } 2. Proposal: Everything before the activity. [join(...)?, signals?]? activity; parallel { a; [signal(b-to-X)] b; } and [join(b-to-X)] { c; d; } and { [signal(e-to-f)] e; [join(e-to-f)] f; } 3. Proposal: Everything after the activity. (As it is now, but with brackets). Activity [join(...)?, signals?]?; parallel { a; b [signal(b-to-X)]; } and { c; d; } [join(b-to-X)] and { e [signal(e-to-f)]; f [join(e-to-f)]; } What do you think? BTW, could we name simPEL simBPEL to enable googling for it? :-) (And doesn't describe sim(B)PEL *B*usiness Processes? :)) Cheers, Olly, Tammo
Re: Syntax of links in simPEL
On Thu, Jun 5, 2008 at 5:12 PM, Matthieu Riou [EMAIL PROTECTED] wrote: However, when I read your explanation, you're interpreting everything in terms of links, sourcing and targeting. What we have here aren't links, we have a signal construct and a join construct. Is it fair to say that signal() is like a BPEL empty with a target, and join() is like an empty with a source? alex