[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: Issue - 2 - A subfunction proposal
Here is a very rough, rough draft of a possible solution to Issue 2. This rough draft introduces three new elements into BPEL - subfunction, return and function. The subfunction XML element is used to define a subfunction. It takes parameters as arguments and those parameters can be variables, partnerLinks or correlationSets. subfunctions can return values but only variables, not partnerLinks or correlationSets. If a subfunction returns a value then the return activity is used to specify the value to return. Other than specifying the input parameters and optional return value a subfunction's body looks more or less identical to a scope activity's body. A subfunction can be defined in the global scope, inside of a scope activity or in another file and imported into the global scope. The normal BPEL naming rules apply so you can only call a sub-function you can 'see'. To call a subfunction you would use the function activity. All parameters are passed by reference so any changes to those parameters in the subfunction are reflected back in the host. Returned values however are always passed by value. Subfunctions that return values can only be called inside of expressions. This requires changing expressions to allow elements as arguments but we already have that problem in Issue 13. If a subfunction throws a fault that isn't caught by the subfunction's fault handler then the fault is propagated into the host. If the host starts compensation then the compensation handler on the subfunction is called through the function activity in the same way one calls a compensation handler on a scope. In the example given below a one-way message is received which contains a math problem. The process calls the IsAddOne subfunction which looks at the type of math problem that has been received and determines if it is a request to add one to a value in the input message. If it is then the process calls the AddOne subfunction which will calculate the desired result and send it back to the student using a one-way message. If the request is not to add one then the process will use a one-way to return an error to the student. In either case the process ends when the logger is sent a copy of the message that was sent to the student. Notice that even if the AddOne subfunction was called the final invoke to the logger still sees the value sent to the student because the mathProblem variable was passed by reference to the AddOne subfunction. <process> <partnersLinks> <partnerLink name="mathStudent" partnerLinkType="a:mathStudent"/> <partnerLink name="loggingService" partnerLinkType="b:loggingService"/> </partnerLinks> <variables> <variable name="mathProblem" messageType="a:mathProblem"/> </variables> <subfunction name="IsAddOne"> <parameters> <parameter name="problemType" type="xsd:string"/> <parameters> <returnValue type="xsd:boolean"/> <return expression="getVariableData('problemType') == 'AddOneProblem'"/> </subfunction> <subfunction name="AddOne"> <parameters> <parameter name="MathMessage" messageType="a:mathProblem"/> <parameter name="Student" partnerLinkType="a:mathStudent"/> </parameters> <sequence> <assign> <copy> <from expression="getVariableData('MathMessage','partOne','/TheNumber') + 1"/> <to variable="MathMessage" part="partOne" query="/TheNumber"/> </copy> <assign> <invoke partnerLink="Student" portType="a:AsynchResponse" operation="mathProblemSolution" inputVariable="MathMessage"/> </sequence> </subfunction> <sequence> <receive partnerLink="mathStudent" portType="a:MathProblem" operation="a:AsynchProblemRequest" variable="mathProblem"/> <switch> <case> <condition> <function functionName="IsAddOne"> <parameter variable="mathProblem" property="problemType"/> </function> </condition> <function functionName="AddOne"> <parameter variable="mathProblem"/> <parameter partnerLink="mathStudent"/> </function> </case> <otherwise> <sequence> <assign> <copy> <from> <requestFailedCannotHandleProblemType/> </from> <to variable="mathProblem" part="partTwo"/> </copy> </assign> <invoke partnerLink="mathStudent" portType="a:AsynchResponse" operation="mathProblemSolution" inputVariable="mathProblem"/> </sequence> </otherwise> </switch> <invoke partnerLink="loggingService" portType="b:loggingService" operation="logProblemSolution" inputVariable="mathProblem"/> </sequence> </process>
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]