You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ce...@apache.org on 2004/04/20 12:04:04 UTC

cvs commit: logging-log4j/tests/src/java/org/apache/log4j/scheduler SchedulerTest.java

ceki        2004/04/20 03:04:04

  Added:       src/java/org/apache/log4j/scheduler Scheduler.java Job.java
               tests/src/java/org/apache/log4j/scheduler SchedulerTest.java
  Log:
  Started work on a global task scheduler. It will allow multiple watchdogs 
  to share a single scheduler thread. Work in progress.
  
  Revision  Changes    Path
  1.1                  logging-log4j/src/java/org/apache/log4j/scheduler/Scheduler.java
  
  Index: Scheduler.java
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  /*
   * Created on Apr 19, 2004
   *
   * To change the template for this generated file go to
   * Window>Preferences>Java>Code Generation>Code and Comments
   */
  package org.apache.log4j.scheduler;
  
  import java.util.Date;
  import java.util.LinkedList;
  import java.util.List;
  
  
  /**
   * @author ceki
   *
   * To change the template for this generated type comment go to
   * Window>Preferences>Java>Code Generation>Code and Comments
   */
  public class Scheduler extends Thread {
    // 
    List jobList;
    boolean interrupted;
    long key;
    
    public Scheduler() {
      jobList = new LinkedList();
    }
    public synchronized long schedule(Job job, Date date) {
      long timeInMillis = date.getTime();
  
      int size = jobList.size();
  
      // find the index i such that timeInMillis < jobList[i]
      int i = 0;
  
      for (; i < size; i++) {
        ScheduledJobEntry se = (ScheduledJobEntry) jobList.get(i);
  
        if (timeInMillis < se.timeInMillis) {
          break;
        }
      }
      jobList.add(i, new ScheduledJobEntry(key, job, timeInMillis));
      // if the jobList was empty, then notify the scheduler thread
      if(i == 0) {
        this.notify();
      }
      return key++;
    }
  
    public synchronized void run() {
      while (true) {
        if (jobList.isEmpty()) {
          linger();
        } else {
          ScheduledJobEntry se = (ScheduledJobEntry) jobList.get(0);
          long now = System.currentTimeMillis();
          if(now >= se.timeInMillis) {
            se.job.execute();
            jobList.remove(0);
          } else {
            linger(se.timeInMillis - now);
          }
        }
      }
    }
    
    void linger() {
      try {
        this.wait();
       } catch (InterruptedException ie) {
         interrupted = true;
       }
    }
    
     void linger(long timeToLinger) {
      try {
        this.wait(timeToLinger);
       } catch (InterruptedException ie) {
         interrupted = true;
       }
    }
  }
  
  
  
  class ScheduledJobEntry {
    long timeInMillis;
    Job job;
    long key;
    
    ScheduledJobEntry(long key, Job job, long timeInMillis) {
      this.key = key;
      this.timeInMillis = timeInMillis;
      this.job = job;
    }
  }
  
  
  
  1.1                  logging-log4j/src/java/org/apache/log4j/scheduler/Job.java
  
  Index: Job.java
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.scheduler;
  
  
  /**
   * Job is a very simple interface. It only has a single method {@link #execute} 
   * which is called by the {@link Scheduler} when a task is ready for execution.
   * 
   * It is assumed that the execution context are contained within the implementing
   * {@ink Job} itself.
   * 
   * @author Ceki G&uuml;lc&uuml;
   *
   */
  public interface Job {
    public void execute();
  }
  
  
  
  1.1                  logging-log4j/tests/src/java/org/apache/log4j/scheduler/SchedulerTest.java
  
  Index: SchedulerTest.java
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.scheduler;
  
  import java.util.Date;
  import java.util.Iterator;
  import java.util.Vector;
  
  import junit.framework.TestCase;
  
  
  /**
   * @author Ceki Gulcu
   *
   */
  public class SchedulerTest extends TestCase {
    static final long TOLERATED_GAP = 50;
    
    public SchedulerTest(String arg0) {
      super(arg0);
    }
  
    protected void setUp() throws Exception {
      super.setUp();
    }
  
    protected void tearDown() throws Exception {
      super.tearDown();
    }
  
    public void testBasic() {
      Scheduler scheduler = new Scheduler();
      scheduler.start();
      long now = System.currentTimeMillis();
      long expected = now + 100;
      CountingJob cj = new CountingJob(expected);
      scheduler.schedule(cj, new Date(expected));
      sleep(300);
      assertEquals(1, cj.count);
    }
    
    public void testMultipleEvent() {
      Vector jobs = new Vector();
      Scheduler scheduler = new Scheduler();
      scheduler.start();
      long now = System.currentTimeMillis();
      
      for(int i = 0; i < 40; i++) {
        long expected = now + i*100;
        CountingJob cj = new CountingJob(expected);
        jobs.add(cj);
        scheduler.schedule(cj, new Date(expected));
      }
      
      sleep(100*40+200);
      for(Iterator i = jobs.iterator(); i.hasNext();) {
        CountingJob cj = (CountingJob) i.next();
        assertEquals(1, cj.count);
      }  
    }
    
    
    void sleep(long duration) {
      try {
        Thread.sleep(duration);
      } catch(InterruptedException ie) {
     }
    }
  }
  
  
  class CountingJob implements Job {
  
    int count = 0; 
    long scheduledTime;
    CountingJob(long scheduledTime) {
      this.scheduledTime = scheduledTime;
    }
    
    public void execute() {
      long now = System.currentTimeMillis();
      if(now < scheduledTime) {
       throw new IllegalStateException("Job executed too early.");
      } else if((now - scheduledTime) > SchedulerTest.TOLERATED_GAP) {
        throw new IllegalStateException("Job executed too late");    
      }
      count++;    
    }
  }
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org