package com.intrbiz.bergamot.scheduler;
import java.util.UUID;
import com.intrbiz.bergamot.data.BergamotDB;
import com.intrbiz.bergamot.model.ActiveCheck;
import com.intrbiz.bergamot.model.message.check.ExecuteCheck;
import com.intrbiz.bergamot.model.message.scheduler.DisableCheck;
import com.intrbiz.bergamot.model.message.scheduler.EnableCheck;
import com.intrbiz.bergamot.model.message.scheduler.PauseScheduler;
import com.intrbiz.bergamot.model.message.scheduler.RescheduleCheck;
import com.intrbiz.bergamot.model.message.scheduler.ResumeScheduler;
import com.intrbiz.bergamot.model.message.scheduler.ScheduleCheck;
import com.intrbiz.bergamot.model.message.scheduler.SchedulerAction;
import com.intrbiz.bergamot.model.message.scheduler.UnscheduleCheck;
import com.intrbiz.bergamot.queue.SchedulerQueue;
import com.intrbiz.bergamot.queue.WorkerQueue;
import com.intrbiz.bergamot.queue.key.SchedulerKey;
import com.intrbiz.bergamot.queue.key.WorkerKey;
import com.intrbiz.queue.Consumer;
import com.intrbiz.queue.QueueException;
import com.intrbiz.queue.RoutedProducer;
public abstract class AbstractScheduler implements Scheduler
{
private WorkerQueue workerQueue;
private RoutedProducer<ExecuteCheck, WorkerKey> executeCheckProducer;
private SchedulerQueue schedulerQueue;
private Consumer<SchedulerAction, SchedulerKey> schedulerActionConsumer;
public AbstractScheduler()
{
super();
}
protected void startQueues() throws Exception
{
this.workerQueue = WorkerQueue.open();
this.executeCheckProducer = this.workerQueue.publishChecks();
this.schedulerQueue = SchedulerQueue.open();
// TODO scheduler names
this.schedulerActionConsumer = this.schedulerQueue.consumeSchedulerActions((h, a) -> { executeAction(a); });
}
public void start() throws Exception
{
this.startQueues();
}
protected void shutdownQueues()
{
this.schedulerActionConsumer.close();
this.schedulerQueue.close();
this.executeCheckProducer.close();
this.workerQueue.close();
}
public void shutdown()
{
this.shutdownQueues();
}
@Override
public void ownPool(UUID site, int pool)
{
// bind any queues for the given pool
this.schedulerActionConsumer.addBinding(new SchedulerKey(site, pool));
}
@Override
public void disownPool(UUID site, int pool)
{
// unbind any queues for the given pool
try
{
this.schedulerActionConsumer.removeBinding(new SchedulerKey(site, pool));
}
catch (QueueException e)
{
}
// remove the jobs in the given pool
this.removeJobsInPool(site, pool);
}
protected abstract void removeJobsInPool(UUID site, int pool);
protected void publishExecuteCheck(ExecuteCheck check, WorkerKey routingKey, long ttl)
{
this.executeCheckProducer.publish(routingKey, check, ttl);
}
protected void executeAction(SchedulerAction action)
{
if (action instanceof PauseScheduler)
{
this.pause();
}
else if (action instanceof ResumeScheduler)
{
this.resume();
}
else if (action instanceof ScheduleCheck)
{
try (BergamotDB db = BergamotDB.connect())
{
ActiveCheck<?,?> check = (ActiveCheck<?,?>) db.getCheck(((ScheduleCheck) action).getCheck());
if (check != null)
{
this.schedule(check);
}
}
}
else if (action instanceof RescheduleCheck)
{
try (BergamotDB db = BergamotDB.connect())
{
ActiveCheck<?,?> check = (ActiveCheck<?,?>) db.getCheck(((RescheduleCheck) action).getCheck());
if (check != null)
{
this.reschedule(check, ((RescheduleCheck) action).getInterval());
}
}
}
else if (action instanceof EnableCheck)
{
this.enable(((EnableCheck) action).getCheck());
}
else if (action instanceof DisableCheck)
{
this.disable(((DisableCheck) action).getCheck());
}
else if (action instanceof UnscheduleCheck)
{
this.unschedule(((UnscheduleCheck) action).getCheck());
}
}
}