@Override public Object execute(Context context) { KieSession kieSession = ((KnowledgeCommandContext) context).getKieSession(); TimerManager tm = getTimerManager(kieSession); RuleFlowProcessInstance wfp = (RuleFlowProcessInstance) kieSession.getProcessInstance(processInstanceId); for (NodeInstance nodeInstance : wfp.getNodeInstances()) { if (nodeInstance instanceof TimerNodeInstance) { TimerNodeInstance tni = (TimerNodeInstance) nodeInstance; if (tni.getNodeName().equals(timerName)) { TimerInstance timer = tm.getTimerMap().get(tni.getTimerId()); tm.cancelTimer(timer.getTimerId()); TimerInstance newTimer = new TimerInstance(); if (delay != 0) { long diff = System.currentTimeMillis() - timer.getActivated().getTime(); newTimer.setDelay(delay * 1000 - diff); } newTimer.setPeriod(period); newTimer.setRepeatLimit(repeatLimit); newTimer.setTimerId(timer.getTimerId()); tm.registerTimer(newTimer, wfp); tni.internalSetTimerId(newTimer.getId()); break; } } } return null; }
private void cancelTimers() { // deactivate still active timers if (timerInstances != null) { TimerManager timerManager = ((InternalProcessRuntime) getProcessInstance().getKnowledgeRuntime().getProcessRuntime()) .getTimerManager(); for (Long id : timerInstances) { timerManager.cancelTimer(id); } } }
@Test @Ignore public void testTimer() { // AbstractRuleBase ruleBase = (AbstractRuleBase) RuleBaseFactory.newRuleBase(); // ExecutorService executorService = new DefaultExecutorService(); // final StatefulSession workingMemory = new ReteooStatefulSession(1, ruleBase, // executorService); // executorService.setCommandExecutor( new CommandExecutor( workingMemory ) ); KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); final StatefulKnowledgeSession workingMemory = kbase.newStatefulKnowledgeSession(); RuleFlowProcessInstance processInstance = new RuleFlowProcessInstance() { private static final long serialVersionUID = 510l; public void signalEvent(String type, Object event) { if ("timerTriggered".equals(type)) { TimerInstance timer = (TimerInstance) event; logger.info("Timer {} triggered", timer.getId()); counter++; } } }; processInstance.setKnowledgeRuntime( ((InternalWorkingMemory) workingMemory).getKnowledgeRuntime()); processInstance.setId(1234); InternalProcessRuntime processRuntime = ((InternalProcessRuntime) ((InternalWorkingMemory) workingMemory).getProcessRuntime()); processRuntime.getProcessInstanceManager().internalAddProcessInstance(processInstance); new Thread( new Runnable() { public void run() { workingMemory.fireUntilHalt(); } }) .start(); TimerManager timerManager = ((InternalProcessRuntime) ((InternalWorkingMemory) workingMemory).getProcessRuntime()) .getTimerManager(); TimerInstance timer = new TimerInstance(); timerManager.registerTimer(timer, processInstance); try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing } assertEquals(1, counter); counter = 0; timer = new TimerInstance(); timer.setDelay(500); timerManager.registerTimer(timer, processInstance); assertEquals(0, counter); try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing } assertEquals(1, counter); counter = 0; timer = new TimerInstance(); timer.setDelay(500); timer.setPeriod(300); timerManager.registerTimer(timer, processInstance); assertEquals(0, counter); try { Thread.sleep(700); } catch (InterruptedException e) { // do nothing } assertEquals(1, counter); try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing } // we can't know exactly how many times this will fire as timers are not precise, but should be // atleast 4 assertTrue(counter >= 4); timerManager.cancelTimer(timer.getId()); int lastCount = counter; try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing } assertEquals(lastCount, counter); }