Dear Wiki user, You have subscribed to a wiki page or wiki category on "Ode Wiki" for change notification.
The following page has been changed by MatthieuRiou: http://wiki.apache.org/ode/Jacob The comment on the change is: Added ! in front of classnames to avoid rendering as internal links. ------------------------------------------------------------------------------ == Channels == - As briefly demonstrated above, channels are interfaces used for communication between activities in PXE engine. There are several types of channels like TerminationChannel, ParentScopeChannel or CompensationChannel (their respective purpose should be obvious from their name). Some basic channels are provided to all activities when they're created to allow them to interact with their environment. When an activity wants to notifies its parent that it has terminated for example, it just calls its parent TerminationChannel (see the Empty example above). + As briefly demonstrated above, channels are interfaces used for communication between activities in PXE engine. There are several types of channels like !TerminationChannel, !ParentScopeChannel or !CompensationChannel (their respective purpose should be obvious from their name). Some basic channels are provided to all activities when they're created to allow them to interact with their environment. When an activity wants to notifies its parent that it has terminated for example, it just calls its parent !TerminationChannel (see the Empty example above). - Don't look for channels implementations because there are none. Channels implementation is provided through a dynamic proxy (see [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/vpu/ChannelFactory.java ChannelFactory].createChannel() and [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/vpu/ChannelFactory.java ChannelFactory].ChannelInvocationHandler for more). That's one of the levels of decoupling between invocation and actual execution in Jacob. + Don't look for channels implementations because there are none. Channels implementation is provided through a dynamic proxy (see [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/vpu/ChannelFactory.java ChannelFactory].createChannel() and [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/vpu/ChannelFactory.java ChannelFactory].!ChannelInvocationHandler for more). That's one of the levels of decoupling between invocation and actual execution in Jacob. == JavaClosure / Abstraction == @@ -267, +267 @@ } }}} - The object method here is inherited from JavaClosure and is just a way to hand our ML to Jacob. So that the Jacob runtime can match it with an incoming channel message later on. + The object method here is inherited from !JavaClosure and is just a way to hand our ML to Jacob. So that the Jacob runtime can match it with an incoming channel message later on. == VPU and Soup == - The [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/vpu/JacobVPU.java VPU] is where all the Jacob processing is occuring. When an JavaClosure is injected inside the VPU, it's actually registered as a [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/soup/Reaction.java Reaction], which is just wrapping the closure with the method to call on the closure to execute it (in our case always the self() method as we're only dealing with Abstraction instances). + The [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/vpu/JacobVPU.java VPU] is where all the Jacob processing is occuring. When a !JavaClosure is injected inside the VPU, it's actually registered as a [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/soup/Reaction.java Reaction], which is just wrapping the closure with the method to call on the closure to execute it (in our case always the self() method as we're only dealing with Abstraction instances). The [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/soup/Soup.java Soup] (and its implementation [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/jacob/src/main/java/com/fs/jacob/vpu/FastSoupImpl.java FastSoupImpl]) is just a container for all the artifacts managed by the VPU (mostly channels and reactions) to organize them in queues where artifacts can be pushed and popped. It also records some execution statistics. @@ -288, +288 @@ instance(new SequenceChildRunner(currentChild+1)); }}} - This simple adds a new ChildRunner that will monitor the next child completion. If you browse PXE's activities code you will even find things like instance(this) which directly enqueues a new instance of the same Jacob abstraction. + This simple adds a new !ChildRunner that will monitor the next child completion. If you browse PXE's activities code you will even find things like instance(this) which directly enqueues a new instance of the same Jacob abstraction. = Walking through examples = @@ -347, +347 @@ instance.execute(); }}} - If you check the code executed by BpelRuntimeContextImpl constructor you'll see among other things the following: + If you check the code executed by !BpelRuntimeContextImpl constructor you'll see among other things the following: {{{#!java if (PROCESS != null) { @@ -394, +394 @@ }); }}} - This method just does what a receive needs to do (like variable and correlation initialization) and creates a new child. When dealing with a real pick, this child would be the onMessage activity, however in the case of a receive, this is an empty activity. So when does our receive completes? Well, when the child completes. As you can see on the child constructor, we're passing the same ParentScopeML that we've been provided. So when the child completes, the receive's parent is notified which means to our receive doesn't need to do it itself. And an empty immediately completes: + This method just does what a receive needs to do (like variable and correlation initialization) and creates a new child. When dealing with a real pick, this child would be the onMessage activity, however in the case of a receive, this is an empty activity. So when does our receive completes? Well, when the child completes. As you can see on the child constructor, we're passing the same !ParentScopeML that we've been provided. So when the child completes, the receive's parent is notified which means to our receive doesn't need to do it itself. And an empty immediately completes: {{{#!java _self.parent.completed(null, CompensationHandler.emptySet()); @@ -402, +402 @@ The parent sequence gets notified almost immediately after the onRequestRcvd() methods finishes. - Now how does our sequence gets the control back? Well, once again, let's look at the ML, the other side of the channel. As one of the most important job of the VPU is matching channels invocations and MLs, we'll get to the [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/bpel-runtime/src/main/java/com/fs/pxe/bpel/runtime/SEQUENCE.java sequence] by its ParentScopeML implementation: + Now how does our sequence gets the control back? Well, once again, let's look at the ML, the other side of the channel. As one of the most important job of the VPU is matching channels invocations and MLs, we'll get to the [http://svn.apache.org/repos/asf/incubator/ode/scratch/pxe/bpel-runtime/src/main/java/com/fs/pxe/bpel/runtime/SEQUENCE.java sequence] by its !ParentScopeML implementation: {{{#!java class SEQUENCE extends ACTIVITY {
