[jboss-svn-commits] JBL Code SVN: r30519 - in labs/jbossrules/trunk/drools-core/src: test/java/org/drools/time/impl and 1 other directory.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Dec 7 23:33:46 EST 2009
Author: mark.proctor at jboss.com
Date: 2009-12-07 23:33:46 -0500 (Mon, 07 Dec 2009)
New Revision: 30519
Added:
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/time/impl/PseudoClockSchedulerTest.java
Modified:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/DefaultJobHandle.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/PseudoClockScheduler.java
Log:
JBRULES-2366 PseudoClockScheduler should set the timer to the firing trigger's time
JBRULES-2365 PseudoClockScheduler removal does not work
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/DefaultJobHandle.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/DefaultJobHandle.java 2009-12-08 02:10:44 UTC (rev 30518)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/DefaultJobHandle.java 2009-12-08 04:33:46 UTC (rev 30519)
@@ -19,6 +19,7 @@
import org.drools.time.Job;
import org.drools.time.JobHandle;
+import org.drools.time.impl.PseudoClockScheduler.ScheduledJob;
/**
* A default implementation for the JobHandle interface
@@ -31,21 +32,25 @@
private static final long serialVersionUID = 5812005196020575395L;
- private final Job job;
+ private final ScheduledJob scheduledJob;
- public DefaultJobHandle(Job job) {
- this.job = job;
+ public DefaultJobHandle(ScheduledJob scheduledJob) {
+ this.scheduledJob = scheduledJob;
}
public Object getJob() {
- return job;
+ return scheduledJob.getJob();
}
+ public ScheduledJob getScheduledJob() {
+ return this.scheduledJob;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((job == null) ? 0 : job.hashCode());
+ result = prime * result + ((getJob() == null) ? 0 : getJob().hashCode());
return result;
}
@@ -55,9 +60,9 @@
if ( obj == null ) return false;
if ( getClass() != obj.getClass() ) return false;
final DefaultJobHandle other = (DefaultJobHandle) obj;
- if ( job == null ) {
- if ( other.job != null ) return false;
- } else if ( !job.equals( other.job ) ) return false;
+ if ( getJob() == null ) {
+ if ( other.getJob() != null ) return false;
+ } else if ( !getJob().equals( other.getJob() ) ) return false;
return true;
}
}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/PseudoClockScheduler.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/PseudoClockScheduler.java 2009-12-08 02:10:44 UTC (rev 30518)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/time/impl/PseudoClockScheduler.java 2009-12-08 04:33:46 UTC (rev 30519)
@@ -27,6 +27,7 @@
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
+import org.drools.SystemEventListenerFactory;
import org.drools.common.DroolsObjectInputStream;
import org.drools.common.InternalWorkingMemory;
import org.drools.time.Job;
@@ -118,7 +119,7 @@
* @see org.drools.time.TimerService#removeJob(org.drools.time.JobHandle)
*/
public boolean removeJob(JobHandle jobHandle) {
- return this.queue.remove( ((DefaultJobHandle) jobHandle).getJob() );
+ return this.queue.remove( ((DefaultJobHandle) jobHandle).getScheduledJob() );
}
/**
@@ -158,7 +159,8 @@
private void runCallBacks() {
ScheduledJob item = queue.peek();
- while ( item != null && (item.getTrigger().hasNextFireTime().getTime() <= this.timer) ) {
+ long fireTime;
+ while ( item != null && ((fireTime = item.getTrigger().hasNextFireTime().getTime()) <= this.timer) ) {
// remove the head
queue.remove();
@@ -167,17 +169,25 @@
if ( item.getTrigger().hasNextFireTime() != null ) {
// reschedule for the next fire time, if one exists
- queue.add( item );
+ queue.add( item );
}
+ // save the current timer because we are going to override to to the job's trigger time
+ long savedTimer = this.timer;
try {
+ // set the clock back to the trigger's fire time
+ this.timer = fireTime;
// execute the call
item.call();
} catch ( Exception e ) {
- e.printStackTrace();
+ SystemEventListenerFactory.getSystemEventListener().exception( e );
+ } finally {
+ this.timer = savedTimer;
}
// get next head
item = queue.peek();
- }
+ }
+
+
}
public synchronized long getTimeToNextJob() {
@@ -191,7 +201,7 @@
*
* @author etirelli
*/
- private static final class ScheduledJob
+ public static final class ScheduledJob
implements
Comparable<ScheduledJob>,
Callable<Void>,
@@ -239,7 +249,7 @@
}
public JobHandle getHandle() {
- return new DefaultJobHandle( this.job );
+ return new DefaultJobHandle( this );
}
public String toString() {
Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/time/impl/PseudoClockSchedulerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/time/impl/PseudoClockSchedulerTest.java (rev 0)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/time/impl/PseudoClockSchedulerTest.java 2009-12-08 04:33:46 UTC (rev 30519)
@@ -0,0 +1,108 @@
+package org.drools.time.impl;
+
+import org.drools.time.Job;
+import org.drools.time.JobContext;
+import org.drools.time.JobHandle;
+import org.drools.time.Trigger;
+import org.jmock.Mockery;
+import org.jmock.Expectations;
+import org.junit.Test;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class PseudoClockSchedulerTest {
+
+ private Mockery context = new Mockery();
+
+ private Job mockJob_1 = context.mock(Job.class, "mockJob_1");
+ private JobContext mockContext_1 = context.mock(JobContext.class, "mockContext_1");
+ private Trigger mockTrigger_1 = context.mock(Trigger.class, "mockTrigger_1");
+
+ private Job mockJob_2 = context.mock(Job.class, "mockJob_2");
+ private JobContext mockContext_2 = context.mock(JobContext.class, "mockContext_2");
+ private Trigger mockTrigger_2 = context.mock(Trigger.class, "mockTrigger_2");
+
+ private PseudoClockScheduler scheduler = new PseudoClockScheduler();
+
+ @Test public void removeExistingJob() {
+ final Date triggerTime = new Date(1000);
+ context.checking(new Expectations() {{
+ atLeast(1).of(mockTrigger_1).hasNextFireTime(); will(returnValue(triggerTime));
+ }});
+
+ JobHandle jobHandle = scheduler.scheduleJob(mockJob_1, this.mockContext_1, mockTrigger_1);
+ assertThat(scheduler.getTimeToNextJob(), is(triggerTime.getTime()));
+
+ scheduler.removeJob(jobHandle);
+ assertThat(scheduler.getTimeToNextJob(), is(-1L));
+ }
+
+
+ @Test public void removeExistingJobWhenMultipleQueued() {
+ final Date triggerTime_1 = new Date(1000);
+ final Date triggerTime_2 = new Date(2000);
+ context.checking(new Expectations() {{
+ atLeast(1).of(mockTrigger_1).hasNextFireTime(); will(returnValue(triggerTime_1));
+ atLeast(1).of(mockTrigger_2).hasNextFireTime(); will(returnValue(triggerTime_2));
+ }});
+
+ JobHandle jobHandle_1 = scheduler.scheduleJob(mockJob_1, this.mockContext_1, mockTrigger_1);
+ JobHandle jobHandle_2 = scheduler.scheduleJob(mockJob_2, this.mockContext_2, mockTrigger_2);
+ assertThat(scheduler.getTimeToNextJob(), is(triggerTime_1.getTime()));
+
+ scheduler.removeJob(jobHandle_1);
+ assertThat(scheduler.getTimeToNextJob(), is(triggerTime_2.getTime()));
+
+ scheduler.removeJob(jobHandle_2);
+ assertThat(scheduler.getTimeToNextJob(), is(-1L));
+ }
+
+ @Test public void timerIsSetToJobTriggerTimeForExecution() {
+ final Date triggerTime = new Date(1000);
+ context.checking(new Expectations() {{
+ exactly(2).of(mockTrigger_1).hasNextFireTime(); will(returnValue(triggerTime));
+ oneOf(mockTrigger_1).nextFireTime(); will(returnValue(triggerTime));
+ allowing(mockTrigger_1).hasNextFireTime(); will(returnValue(null));
+ }});
+ Job job = new Job() {
+ public void execute(JobContext ctx) {
+ // Even though the clock has been advanced to 5000, the job should run
+ // with the time set its trigger time.
+ assertThat(scheduler.getCurrentTime(), is(1000L));
+ }
+ };
+
+ scheduler.scheduleJob(job, this.mockContext_1, mockTrigger_1);
+
+ scheduler.advanceTime(5000, TimeUnit.MILLISECONDS);
+
+ // Now, after the job has been executed the time should be what it was advanced to
+ assertThat(scheduler.getCurrentTime(), is(5000L));
+ }
+
+ @Test public void timerIsResetWhenJobThrowsExceptions() {
+ final Date triggerTime = new Date(1000);
+ context.checking(new Expectations() {{
+ exactly(2).of(mockTrigger_1).hasNextFireTime(); will(returnValue(triggerTime));
+ oneOf(mockTrigger_1).nextFireTime(); will(returnValue(triggerTime));
+ allowing(mockTrigger_1).hasNextFireTime(); will(returnValue(null));
+ }});
+ Job job = new Job() {
+ public void execute(JobContext ctx) {
+ assertThat(scheduler.getCurrentTime(), is(1000L));
+ throw new RuntimeException("for test");
+ }
+ };
+
+ scheduler.scheduleJob(job, this.mockContext_1, mockTrigger_1);
+
+ scheduler.advanceTime(5000, TimeUnit.MILLISECONDS);
+
+ // The time must be advanced correctly even when the job throws an exception
+ assertThat(scheduler.getCurrentTime(), is(5000L));
+ }
+}
\ No newline at end of file
More information about the jboss-svn-commits
mailing list