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ülcü
*
*/
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