multiple timers creating more than one node instance
mdonato Dec 28, 2005 9:01 AMHi all,
I still have problems with timer ... but now ... with multiple timers in diferent nodes, and when one finish, it creates the next node instance more then once!
I dont know what to do .... i know that when using timer, i need to save processinstance ... and it's what i'm doing !
see my process definition:
<process-definition name="controle-teste"> <swimlane name="Supervisor-Cliente"> <assignment class="br.com.glr.jbpm.handlers.SwimlaneAssignmentHandler" config-type="bean"> <swimlaneName>Supervisor-Cliente</swimlaneName> </assignment> </swimlane> <swimlane name="Supervisor-Celula"> <assignment class="br.com.glr.jbpm.handlers.SwimlaneAssignmentHandler" config-type="bean"> <swimlaneName>Supervisor-Celula</swimlaneName> </assignment> </swimlane> <swimlane name="Diretor-Operacional"> <assignment class="br.com.glr.jbpm.handlers.SwimlaneAssignmentHandler" config-type="bean"> <swimlaneName>Diretor-Operacional</swimlaneName> </assignment> </swimlane> <swimlane name="Gerente-Cliente"> <assignment class="br.com.glr.jbpm.handlers.SwimlaneAssignmentHandler" config-type="bean"> <swimlaneName>Gerente-Cliente</swimlaneName> </assignment> </swimlane> <swimlane name="Operador-Celula"> <assignment class="br.com.glr.jbpm.handlers.SwimlaneAssignmentHandler" config-type="bean"> <swimlaneName>Operador-Celula</swimlaneName> </assignment> </swimlane> <swimlane name="Diretor-Geral"> <assignment class="br.com.glr.jbpm.handlers.SwimlaneAssignmentHandler" config-type="bean"> <swimlaneName>Diretor-Geral</swimlaneName> </assignment> </swimlane> <start-state name="inicio"> <transition name="tr1" to="confirma-abertura"/> </start-state> <task-node name="confirma-abertura"> <task name="abertura" description="Confirmar abertura de admissoes" swimlane="Supervisor-Cliente"/> <event type="node-leave"> <action name="notificar" class="br.com.glr.jbpm.handlers.MailToSwimlaneActionHandler" config-type="bean"> <from>admin@glr.com.br</from> <swimlaneNames>Supervisor-Celula;Diretor-Operacional;Diretor-Geral;Gerente-Cliente;Operador-Celula</swimlaneNames> <subject>Confirmada a abertura de admissoes</subject> <message/> </action> </event> <transition name="confirmar" to="aguarda"/> </task-node> <state name="aguarda"> <timer duedate="1 minute" name="wait" transition="confirmar"/> <transition name="confirmar" to="confirma-fechamento"/> </state> <task-node name="confirma-fechamento"> <timer duedate="2 minutes" name="fechamento-timer" transition="nao" /> <event type="node-enter"> <script> <variable name="count" access="read,write"/> <expression>count=0;</expression> </script> </event> <task name="fechamento" description="Confirmar fechamento de admissoes" swimlane="Supervisor-Cliente"> <event type="task-end"> <action name="notificar" class="br.com.glr.jbpm.handlers.MailToSwimlaneActionHandler" config-type="bean"> <from>admin@glr.com.br</from> <swimlaneNames>Supervisor-Celula;Diretor-Operacional;Diretor-Geral;Gerente-Cliente;Operador-Celula</swimlaneNames> <subject>Confirmado o fechamento de admissoes</subject> <message/> </action> </event> </task> <transition name="sim" to="termino"/> <transition name="nao" to="decide"/> </task-node> <decision name="decide"> <event type="node-enter" > <script> <variable name="count" access="read,write"/> <expression>count++;</expression> </script> </event> <transition name="nivel-0" to="Cobranca-Diretor-Geral"> <condition>count > 10</condition> </transition> <transition name="nivel-1" to="Cobranca-Diretor-Geral"> <condition>count > 8</condition> </transition> <transition name="nivel-2" to="Cobranca-Diretor-Geral"> <condition>count > 3</condition> </transition> <transition name="nivel-3" to="Cobranca-Diretor-Geral"> <condition>count > 0</condition> </transition> </decision> <task-node name="Cobranca-Diretor-Geral" > <task name="Cobranca-Diretor-Geral" description="Cobranca de fechamento" swimlane="Diretor-Geral"> <event type="task-create" > <action name="notificar" class="br.com.glr.jbpm.handlers.MailToSwimlaneActionHandler" config-type="bean"> <from>admin@glr.com.br</from> <subject>Cobrar o fechamento de admissoes</subject> <message/> </action> </event> </task> <transition name="cobrado" to="confirma-fechamento"/> </task-node> <end-state name="termino"></end-state> </process-definition>
see my thread execute code:
public long executeTimer() throws IntegrationException { long millisTillNextTimerIsDue = -1; boolean isDueDateInPast = true; JbpmSession session = getJbpmSessionFactory().openJbpmSession(); try { SchedulerSession schedulerSession = session.getSchedulerSession(); logger.debug("checking for timers"); Iterator iter = schedulerSession.findTimersByDueDate(); while ((iter.hasNext()) && (isDueDateInPast)) { Timer timer = (Timer) iter.next(); logger.debug("found timer " + timer); // if this timer is due if (timer.isDue()) { //session.getGraphSession().lockProcessInstance( timer.getToken().getProcessInstance() ); logger.debug("executing timer '" + timer + "'"); // execute timer.execute(); // if there was an exception, just save the timer if (timer.getException() != null) { //schedulerSession.saveTimer(timer); session.getGraphSession().saveProcessInstance( timer.getToken().getProcessInstance() ); // if repeat is specified } else if (timer.getRepeat() != null) { // update timer by adding the repeat duration Date dueDate = timer.getDueDate(); // suppose that it took the timer runner thread a // very long time to execute the timers. // then the repeat action dueDate could already have passed. while (dueDate.getTime() <= System.currentTimeMillis()) { dueDate = businessCalendar.add(dueDate, new Duration(timer.getRepeat())); } timer.setDueDate(dueDate); // save the updated timer in the database logger.debug("saving updated timer for repetition '" + timer + "' in '" + (dueDate.getTime() - System.currentTimeMillis()) + "' millis"); //schedulerSession.saveTimer(timer); session.getGraphSession().saveProcessInstance( timer.getToken().getProcessInstance() ); } else { // delete this timer logger.debug("deleting timer '" + timer + "'"); //schedulerSession.deleteTimer(timer); session.getGraphSession().saveProcessInstance( timer.getToken().getProcessInstance() ); } } else { // this is the first timer that is not yet due isDueDateInPast = false; millisTillNextTimerIsDue = timer.getDueDate().getTime() - System.currentTimeMillis(); } } } finally { //jbpmSession.commitTransactionAndClose(); } return millisTillNextTimerIsDue; }
Please, any suggestions will be very appreciated !!!
thanks