Skip to content

Commit

Permalink
Merge branch 'newgen' of https://github.com/d3scomp/JDEECo.git into
Browse files Browse the repository at this point in the history
newgen

Conflicts:
	jdeeco-core/test/cz/cuni/mff/d3s/deeco/scheduler/LocalTimeSchedulerTest.java
	jdeeco-core/test/cz/cuni/mff/d3s/deeco/scheduler/SchedulerTest.java
  • Loading branch information
Michał Kit committed Nov 6, 2013
2 parents 99fa831 + 01c1481 commit 7815c52
Show file tree
Hide file tree
Showing 4 changed files with 341 additions and 329 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
/**
*/
package cz.cuni.mff.d3s.deeco.scheduler;


import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Timer;
import java.util.TimerTask;

import cz.cuni.mff.d3s.deeco.executor.Executor;
import cz.cuni.mff.d3s.deeco.knowledge.TriggerListener;
import cz.cuni.mff.d3s.deeco.model.runtime.api.Trigger;
import cz.cuni.mff.d3s.deeco.task.Task;
import cz.cuni.mff.d3s.deeco.task.TaskTriggerListener;

//FIXME TB: The class does not have the header stating the author

public class LocalTimeScheduler implements Scheduler {
/**
* Implementation of the Scheduler as LocalTimeScheduler
*
* @author Jaroslav Keznikl <keznikl@d3s.mff.cuni.cz>
* @author Andranik Muradyan <muradian@d3s.mff.cuni.cz>
*
*/
public class LocalTimeScheduler implements Scheduler, TaskTriggerListener {
Map<Task, TaskInfo> tasks;
Executor executor;
private States state;
Expand All @@ -36,36 +34,24 @@ public TaskInfo(){

private enum States{
RUNNING,
FAILED,
STOPPED
}

public LocalTimeScheduler(){
public LocalTimeScheduler( ){
tasks = new HashMap<>();
}

@Override
public void setExecutor(Executor executor) {
this.executor = executor;

}

@Override
public synchronized void executionCompleted(Task task) {
public void executionCompleted(Task task) {
tasks.get(task).state = States.STOPPED;
}

@Override
public synchronized void executionFailed(Task task, Exception e) {
tasks.get(task).state = States.STOPPED;
}

@Override
public synchronized void start () {
if( state == States.RUNNING )
return;

Iterator<Entry<Task, TaskInfo>> it = tasks.entrySet().iterator();

for(Task task: tasks.keySet()){
startTask(task);
}
Expand All @@ -78,13 +64,20 @@ public synchronized void stop() {
if( state == States.STOPPED )
return;

if(tasks != null && tasks.size() > 0)
for (Task t : tasks.keySet()) {
stopTask(t);
}

state = States.STOPPED;
}

@Override
public synchronized void addTask(Task task) {
if( !tasks.containsKey(task) )
tasks.put(task, new TaskInfo());
if( task == null || tasks.containsKey(task) )
return;

tasks.put(task, new TaskInfo());

if( state == States.RUNNING )
startTask(task);
Expand All @@ -99,35 +92,32 @@ public synchronized void removeTask(Task task) {
}

private void startTask(final Task task) {
if( task == null )
return;

TaskInfo ti = tasks.get(task);
task.setTriggerListener(new TaskTriggerListener() {
// FIXME TB: Since we can get the task from the triggered method, we don't need the instance of this anonymous class. However, I'm relatively indifferent
// whether to keep instantiation of the anonymous class and remove the task parameter or whether to have one handler per scheduler (well, I would
// vote for one handler per scheduler, but it's just a matter of taste).
@Override
public void triggered(Task task) {
taskTriggerFired(task);
}
});

ti.timer.scheduleAtFixedRate(new TimerTask() {
if( ti != null && ti.state != States.RUNNING ){
task.setTriggerListener(this);

@Override
public void run() {
taskTimerFired(task);
}
}, 0, task.getSchedulingPeriod()); // FIXME TB: What about if scheduling period == 0, which probably means that we do not schedule periodically?

taskTimerReset(task, ti);
}
}

private void stopTask(final Task task) {
if( task == null )
return;

TaskInfo ti = tasks.get(task);
ti.timer.cancel();
ti.timer = new Timer();
ti.state = States.STOPPED;

// FIXME TB: Necessary to unset the trigger listener
// task.unsetTriggerListener()
if( ti != null && ti.state != States.RUNNING ){
task.setTriggerListener(null);


ti.timer.cancel();
ti.timer = new Timer();
ti.state = States.STOPPED;
}
}

/**
Expand All @@ -137,38 +127,60 @@ private void stopTask(final Task task) {
* @param task
*/
protected void taskTriggerFired(final Task task) {
if( tasks.get(task).state == States.RUNNING ){
// TODO : Implement error reporting
return;
}
if( state == States.RUNNING && task != null && tasks.containsKey(task)){
if( tasks.get(task).state == States.RUNNING ){
// TODO : Implement error reporting
return;
}

TaskInfo ti = tasks.get(task);
ti.timer.cancel();
ti.timer = new Timer();
TaskInfo ti = tasks.get(task);
ti.timer.cancel();
ti.timer = new Timer();

ti.timer.scheduleAtFixedRate(new TimerTask() {
taskTimerReset(task, ti);

@Override
public void run() {
taskTimerFired(task);
}
}, 0, task.getSchedulingPeriod()); // FIXME TB: What about if scheduling period == 0, which probably means that we do not schedule periodically?

ti.state = States.RUNNING;
executor.execute(task);
ti.state = States.RUNNING;
executor.execute(task);
}
}

private void taskTimerReset(final Task task, TaskInfo ti) {
if( task.getSchedulingPeriod() > 0){
ti.timer.scheduleAtFixedRate(new TimerTask() {

@Override
public void run() {
taskTimerFired(task);
}
}, 0, task.getSchedulingPeriod());
}
}

protected void taskTimerFired(Task task) {
if( task == null )
return;

if( tasks.get(task).state == States.RUNNING ){
// TODO : Implement error reporting
return;
}

tasks.get(task).state = States.RUNNING;
executor.execute(task);
}


@Override
public void executionFailed(Task task, Exception e) {
executionCompleted(task);
}


@Override
public void setExecutor(Executor executor) {
this.executor = executor;
}

@Override
public void triggered(Task task) {
taskTimerFired(task);
}
}

44 changes: 23 additions & 21 deletions jdeeco-core/src/cz/cuni/mff/d3s/deeco/scheduler/Scheduler.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
/**
*/
package cz.cuni.mff.d3s.deeco.scheduler;

import java.util.List;

import cz.cuni.mff.d3s.deeco.executor.ExecutionListener;
import cz.cuni.mff.d3s.deeco.executor.Executor;
import cz.cuni.mff.d3s.deeco.task.Task;


//FIXME TB: The class does not have the header stating the author
// test text

public interface Scheduler extends ExecutionListener {
public void start();
public void stop();
public void addTask( Task task );
public void removeTask( Task task );

void setExecutor(Executor executor);
package cz.cuni.mff.d3s.deeco.scheduler;

import cz.cuni.mff.d3s.deeco.executor.ExecutionListener;
import cz.cuni.mff.d3s.deeco.executor.Executor;
import cz.cuni.mff.d3s.deeco.task.Task;


/**
* Interface Scheduler for LocalTimeScheduler(and others if needed)
*
* @author Andranik Muradyan <muradian@d3s.mff.cuni.cz>
*
*/
public interface Scheduler extends ExecutionListener {
public void start();
public void stop();
public void addTask( Task task );
public void removeTask( Task task );

public void executionFailed(Task task, Exception e);
public void executionCompleted( Task task );
public void setExecutor(Executor executor);

}
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
/**
*/
package cz.cuni.mff.d3s.deeco.scheduler;

import static org.mockito.Mockito.mock;

import org.junit.Before;

import cz.cuni.mff.d3s.deeco.executor.Executor;

//FIXME TB: The class is missing a header which states the author
/**
* Factory for Scheduler implementation tests
*
* @author Jaroslav Keznikl <keznikl@d3s.mff.cuni.cz>
*
*/
public class LocalTimeSchedulerTest extends SchedulerTest {

public class LocalTimeSchedulerTest {
LocalTimeScheduler sched;
Executor executor;

@Before
public void setUp() throws Exception{
executor = mock(Executor.class);
sched = new LocalTimeScheduler();
sched.setExecutor(executor);
@Override
protected Scheduler setUpTested(Executor executor) {
Scheduler s = new LocalTimeScheduler();
s.setExecutor(executor);
return s;
}


}
Loading

0 comments on commit 7815c52

Please sign in to comment.