/machinelearning/5.0.x/drools-core/src/main/java/org/drools/process/instance/timer/TimerManager.java

https://github.com/droolsjbpm/droolsjbpm-contributed-experiments · Java · 225 lines · 175 code · 43 blank · 7 comment · 19 complexity · fcfa79039867f4a29cde017f5179c8e8 MD5 · raw file

  1. package org.drools.process.instance.timer;
  2. import java.io.IOException;
  3. import java.io.ObjectInput;
  4. import java.io.ObjectOutput;
  5. import java.util.Collection;
  6. import java.util.Date;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. import org.drools.WorkingMemory;
  10. import org.drools.process.instance.ProcessInstance;
  11. import org.drools.time.Job;
  12. import org.drools.time.JobContext;
  13. import org.drools.time.JobHandle;
  14. import org.drools.time.TimerService;
  15. import org.drools.time.Trigger;
  16. /**
  17. *
  18. * @author <a href="mailto:kris_verlaenen@hotmail.com">Kris Verlaenen</a>
  19. */
  20. public class TimerManager {
  21. private long timerId = 0;
  22. private WorkingMemory workingMemory;
  23. private TimerService timerService;
  24. private Map<Long, TimerInstance> timers = new HashMap<Long, TimerInstance>();
  25. private Job processJob = new ProcessJob();
  26. public TimerManager(WorkingMemory workingMemory, TimerService timerService) {
  27. this.workingMemory = workingMemory;
  28. this.timerService = timerService;
  29. }
  30. public void registerTimer(final TimerInstance timer,
  31. ProcessInstance processInstance) {
  32. timer.setId( ++timerId );
  33. timer.setProcessInstanceId(processInstance.getId());
  34. timer.setActivated(new Date());
  35. ProcessJobContext ctx = new ProcessJobContext( timer,
  36. processInstance.getId(),
  37. this.workingMemory );
  38. JobHandle jobHandle = this.timerService.scheduleJob( processJob,
  39. ctx,
  40. new TimerTrigger( timer.getDelay(),
  41. timer.getPeriod() ) );
  42. timer.setJobHandle( jobHandle );
  43. timers.put(timer.getId(), timer);
  44. }
  45. public void internalAddTimer(final TimerInstance timer) {
  46. ProcessJobContext ctx = new ProcessJobContext(
  47. timer, timer.getProcessInstanceId(), this.workingMemory);
  48. long delay;
  49. Date lastTriggered = timer.getLastTriggered();
  50. if (lastTriggered == null) {
  51. Date activated = timer.getActivated();
  52. Date now = new Date();
  53. long timespan = now.getTime() - activated.getTime();
  54. delay = timer.getDelay() - timespan;
  55. if (delay < 0) {
  56. delay = 0;
  57. }
  58. } else {
  59. Date now = new Date();
  60. long timespan = now.getTime() - lastTriggered.getTime();
  61. delay = timespan - timer.getPeriod();
  62. if (delay < 0) {
  63. delay = 0;
  64. }
  65. }
  66. JobHandle jobHandle = this.timerService.scheduleJob(
  67. processJob, ctx, new TimerTrigger(delay, timer.getPeriod()));
  68. timer.setJobHandle(jobHandle);
  69. timers.put(timer.getId(), timer);
  70. }
  71. public void cancelTimer(long timerId) {
  72. TimerInstance timer = timers.remove(timerId);
  73. if (timer != null) {
  74. timerService.removeJob( timer.getJobHandle() );
  75. }
  76. }
  77. public void dispose() {
  78. for (TimerInstance timer: timers.values()) {
  79. timerService.removeJob( timer.getJobHandle() );
  80. }
  81. }
  82. public TimerService getTimerService() {
  83. return this.timerService;
  84. }
  85. public Collection<TimerInstance> getTimers() {
  86. return timers.values();
  87. }
  88. public long internalGetTimerId() {
  89. return timerId;
  90. }
  91. public void internalSetTimerId(long timerId) {
  92. this.timerId = timerId;
  93. }
  94. public void setTimerService(TimerService timerService) {
  95. this.timerService = timerService;
  96. }
  97. public class ProcessJob implements Job {
  98. public void execute(JobContext c) {
  99. ProcessJobContext ctx = (ProcessJobContext) c;
  100. Long processInstanceId = ctx.getProcessInstanceId();
  101. WorkingMemory workingMemory = ctx.getWorkingMemory();
  102. if ( processInstanceId == null ) {
  103. throw new IllegalArgumentException( "Could not find process instance for timer " );
  104. }
  105. ctx.getTimer().setLastTriggered(new Date());
  106. ProcessInstance processInstance = ( ProcessInstance ) workingMemory.getProcessInstance( processInstanceId );
  107. // process instance may have finished already
  108. if ( processInstance != null ) {
  109. workingMemory.getSignalManager().signalEvent(processInstance, "timerTriggered", ctx.getTimer());
  110. }
  111. if (ctx.getTimer().getPeriod() == 0) {
  112. TimerManager.this.timers.remove(ctx.getTimer().getId());
  113. }
  114. }
  115. }
  116. public static class TimerTrigger
  117. implements
  118. Trigger {
  119. private long delay;
  120. private long period;
  121. private int count;
  122. public TimerTrigger() {
  123. }
  124. public TimerTrigger(long delay,
  125. long period) {
  126. this.delay = delay;
  127. this.period = period;
  128. }
  129. public Date getNextFireTime() {
  130. Date date = null;
  131. if ( count == 0 ) {
  132. // initial delay before first fire
  133. date = new Date( System.currentTimeMillis() + this.delay );
  134. } else if ( this.period != 0 ) {
  135. // repeated fires for the given period
  136. date = new Date( System.currentTimeMillis() + this.period );
  137. }
  138. count++;
  139. return date;
  140. }
  141. public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
  142. this.delay = in.readLong();
  143. this.period = in.readLong();
  144. this.count = in.readInt();
  145. }
  146. public void writeExternal(ObjectOutput out) throws IOException {
  147. out.writeLong( this.delay );
  148. out.writeLong( this.period );
  149. out.writeInt( this.count );
  150. }
  151. }
  152. public static class ProcessJobContext
  153. implements
  154. JobContext {
  155. private Long processInstanceId;
  156. private WorkingMemory workingMemory;
  157. private TimerInstance timer;
  158. private JobHandle jobHandle;
  159. public ProcessJobContext(final TimerInstance timer,
  160. final Long processInstanceId,
  161. final WorkingMemory workingMemory) {
  162. this.timer = timer;
  163. this.processInstanceId = processInstanceId;
  164. this.workingMemory = workingMemory;
  165. }
  166. public Long getProcessInstanceId() {
  167. return processInstanceId;
  168. }
  169. public WorkingMemory getWorkingMemory() {
  170. return workingMemory;
  171. }
  172. public JobHandle getJobHandle() {
  173. return this.jobHandle;
  174. }
  175. public void setJobHandle(JobHandle jobHandle) {
  176. this.jobHandle = jobHandle;
  177. }
  178. public TimerInstance getTimer() {
  179. return timer;
  180. }
  181. }
  182. }