[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