-
1. Re: replication of task at runtime
csplrj1 Jun 5, 2008 2:03 AM (in response to waltertaus)Does it involves different actors or same actors? I am just asking as I have a same problem. but i require that the task to be associated with different actors
Thanks in advance
CSJakharia -
2. Re: replication of task at runtime
kukeltje Jun 5, 2008 2:11 AM (in response to waltertaus)look in the wiki... there is a 'dynamic fork' example
-
3. Re: replication of task at runtime
waltertaus Jun 5, 2008 3:19 AM (in response to waltertaus)Hi,
in my example the same actors are involved.
I looked in Wiki and found a MultiChoiceForkAH and a ForEachForkAh. Is this what you are referring to as "Dynamic Fork" ?
Thanks,
Walter -
-
5. Re: replication of task at runtime
waltertaus Jun 6, 2008 11:11 AM (in response to waltertaus)Hi,
I have now implemented this ForEachForkHandler and it works. However, I have now come up with an extended scenario.
In my ForEachForkHandler I create 4 tasks. However, in specific situations I want already to continue when the first two tasks are completed. Therefore, I have tried to implement a kind of housekeeping handler which I call from the join to get rid of the "unnecessary" tasks.
My process consists of
1) fork
2) 4 activities which have been generated by the ForEachForkHandler
3) join
When entering the join I call setNOutOfM with an appropriate value. Secondly I invoke the handler listed below:ublic class MultiinstanceHouseKeepingHandler implements ActionHandler { @Override public void execute(ExecutionContext ctx) throws Exception { // TODO Auto-generated method stub Token t = ctx.getToken(); Collection til = ctx.getTaskMgmtInstance().getTaskInstances(); Map childTokenList = t.getParent().getChildren(); Set ks = childTokenList.keySet(); Iterator it = ks.iterator(); while (it.hasNext()) { Token ct = (Token)childTokenList.get(it.next()); if (ct == t) continue; Iterator itil = til.iterator(); while (itil.hasNext()) { TaskInstance ti = (TaskInstance)itil.next(); if (ti.getToken() == ct) { ti.cancel(); ct.end(); break; } } } } }
The process continues correctly with the task following the join. However, I cannot get rid of the other unwanted tasks and they stay forever on my worklist.
What am I doing wrong here?
Thanks,
Walter -
6. Re: replication of task at runtime
kukeltje Jun 9, 2008 2:02 AM (in response to waltertaus)you mean the ti.cancel() and ct.end() do not get called because the 'itil' is is empty or do they get called but do not work?
-
7. Re: replication of task at runtime
waltertaus Jun 9, 2008 6:55 AM (in response to waltertaus)Hi,
I was not aware that the call to ti.cancel also invokes my MultiinstanceHouseKeepingHandler. ANd in this second (i.e. nested) call to my Handler it blew up and hence did not eliminate anything from my worklist. I am now setting an indication that I am within a nested call so that my handler knows what to do.
Thanks,
Walter -
8. Re: replication of task at runtime
waltertaus Jun 9, 2008 7:01 AM (in response to waltertaus)Hi,
for the sake of completeness, here is now my complete code.public class MultiinstanceLoopForkHandler implements ActionHandler { private String loopMaxValue; private String loopId; private int loopType; @Override public void execute(ExecutionContext ctx) throws Exception { // TODO Auto-generated method stub Token token = ctx.getToken(); Fork fork = (Fork)ctx.getNode(); int i; try { i = Integer.parseInt(loopMaxValue); } catch (Exception e) { try { if (ctx.getVariable(loopMaxValue) != null) i = (Integer)ctx.getVariable(loopMaxValue); else i = 1; } catch(Exception e1) { e1.printStackTrace(); i = 1; } } if (loopType == 1) ctx.setVariable(loopId + "MaxCount", 1); else ctx.setVariable(loopId + "MaxCount", i); Transition leavingTrans = (Transition)fork.getLeavingTransitions().get(0); for (int j = 1; j<i; j++) { String newTokenName = loopId + j; String transitionName = leavingTrans.getName(); Token newToken = new Token(token, newTokenName); ctx.getJbpmContext().getSession().save(newToken); fork.leave(new ExecutionContext(newToken), transitionName); } } }
public class MultiinstanceLoopJoinHandler implements ActionHandler { private String loopId; @Override public void execute(ExecutionContext ctx) throws Exception { // TODO Auto-generated method stub if (ctx.getVariable(loopId + "Housekeeping") != null) return; ctx.setVariable(loopId + "Housekeeping", 1); Token t = ctx.getToken(); Collection til = ctx.getTaskMgmtInstance().getTaskInstances(); Map childTokenList = t.getParent().getChildren(); Set ks = childTokenList.keySet(); Iterator it = ks.iterator(); while (it.hasNext()) { Token ct = (Token)childTokenList.get(it.next()); if (ct.getName().equals(t.getName()) && ct.getId() == t.getId()) continue; if (ct.getName() != null && !ct.getName().startsWith(loopId)) continue; Iterator itil = til.iterator(); while (itil.hasNext()) { TaskInstance ti = (TaskInstance)itil.next(); if (ti.getToken() == ct) { ti.cancel(); ct.end(); break; } } } } }
And here is an example process.<fork name="ForkOne"> <event type="node-enter"> <action class="com.pi.bpm.workflow.jbpm.MultiinstanceLoopForkHandler"> <loopMaxValue>3</loopMaxValue> <loopId>MultinstanceOne</loopId> <loopType>1</loopType> </action> </event> <transition name="MultinstanceOne" to="MultinstanceOne"></transition> </fork> <task-node name="MultinstanceOne"> <transition name="ToJoinOne" to="JoinOne"></transition> <task name="MultinstanceOne"></task> </task-node> <join name="JoinOne"> <event type="node-enter"> <script><expression> if (executionContext.getVariable("MultinstanceOneMaxCount") > 1) executionContext.getNode().setNOutOfM(executionContext.getVariable("MultinstanceOneMaxCount")); else executionContext.getNode().setDiscriminator(true); </expression></script> <action class="com.pi.bpm.workflow.jbpm.MultiinstanceLoopJoinHandler"> <loopId>MultinstanceOne</loopId> </action> </event> <transition name="To_cF5fADE6Ed2C6L5mprqn1w" to="../UserTask5/UserTask5"> </transition> </join> </super-state>
BTW with this sequence I can handle the BPMN constructs of Multiinstance Loop All and Multiinstance Loop One.
ANy suggestions and improvements are highly welcome.
Walter -
9. Re: replication of task at runtime
kukeltje Jun 9, 2008 8:43 AM (in response to waltertaus)nice, congratulations... on a sidenote, could you make a wiki page for this. I'm sure others are interested.