[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: enableInstanceCompensation and the global compensation handler
I recently had to answer some questions for my devs about enableInstanceCompensation. This experience made me wonder two things: #1 - Did I lie to them? #2 - If I didn't, should we clean up the language in the spec to make these issues clearer? What do y'all think? Thanks, Yaron Here is what I told them: Trick question - how do you call the global compensation handler for a BPEL program from within a BPEL program? The answer is - you can't. The reason is that a compensation handler is only instantiated when the scope it is associated with has successfully exited. This means that the global compensation handler can only be instantiated when the process has successfully exited. If the process has successfully exited then obviously it can't call the global compensation handler. So the only way to call a global compensation handler is if the BPEL process has successfully exited, the platform on which the BPEL process is executing has persisted the BPEL's processes instantiated compensation handlers and associated contexts and then at some later date some platform specific entity (which we will call an instance compensation handler) then calls the BPEL process's global compensation handler which then kicks off the BPEL compensation process. This then begs the question - why do we need an explicit enableInstanceCompensation attribute? After all, if you define an explicit global compensation handler then by definition you are depending on the existence of an instance compensation handler otherwise your global compensation handler code can never be called. In fact, we should probably raise a static analysis warning if a BPEL defines an explicit global compensation handler and does not define enableInstanceCompensation="yes". The reason why the enableInstanceCompensation attribute is important is that not all BPELs will be written to be able to be compensated after the BPEL process has successfully exited. What the enableInstanceCompensation attribute does is allow the BPEL to either say 'Hey, once I exit throw me away, it's over' or 'when I exit, keep me around because you can still compensate me.' BPEL does not have a way to say how long you should keep the process around if enableInstanceCompensation="yes", that is considered to be a deployment issue and so out of scope for BPEL. It is true that, strictly speaking, the enableInstanceCompensation attribute is redundant. Remember, in BPEL, if there is no explicit compensation handler for a scope then there is an implicit compensation handler. The implicit compensation handler will call the compensation handlers of all the scope's child scopes. So even if a BPEL process doesn't contain an explicit global compensation handler, it does contain an implicit one. This is where problems can come from. What happens if an instance compensation handler calls the implicit global compensation handler on a BPEL process that is not designed to be compensated after the BPEL process exits? If there was no enableInstanceCompensation attribute then it would still be possible to prevent compensation from occurring after the process exits. What the programmer can do is write a global compensation handler of the form: <compensationHandler> <empty/> </compensationHandler> This is similar to the trick I proposed we use to garbage collect compensation handlers at run time, e.g. wrap a section of code in a scope which contains an explicit compensation handler that only contains <empty/>. This prevents anyone outside of the scope from ever compensating anything inside the scope and so allows us to garbage collect the compensation handlers inside the scope at run time as soon as execution exits the scope. If someone wrote a global compensation handler that only contained <empty/> then it would then be trivial to do static analysis to determine that the global compensation handler won't ever allow the process to be compensated and so we would know not to keep the process around once it exits. What the enableInstanceCompensation attribute does is make it clearer when a process is not intended to be compensated after it has exited. I like the attribute because I don't like depending on side effects to communicate information.
<<attachment: winmail.dat>>
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]