/* * Copyright 2019 Arcus Project * * 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 com.iris.common.scheduler; import java.util.Date; import java.util.concurrent.TimeUnit; import org.eclipse.jdt.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; /** * */ public abstract class BaseScheduler implements Scheduler { private static final Logger logger = LoggerFactory.getLogger(BaseScheduler.class); public BaseScheduler() { } protected abstract ScheduledTask doSchedule(Runnable task, Date time, long delay, TimeUnit unit); /* (non-Javadoc) * @see com.iris.common.scheduler.Scheduler#scheduleDelayed(java.util.function.Consumer, com.google.common.base.Supplier, long, java.util.concurrent.TimeUnit) */ @Override public <I> ScheduledTask scheduleDelayed( Function<I,?> task, Supplier<I> input, long timeout, TimeUnit unit ) { return scheduleDelayed(new ProdConRunner<I>(task, input), timeout, unit); } /* (non-Javadoc) * @see com.iris.common.scheduler.Scheduler#scheduleDelayed(java.util.function.Consumer, java.lang.Object, long, java.util.concurrent.TimeUnit) */ @Override public <I> ScheduledTask scheduleDelayed(Function<I,?> task, @Nullable I input, long timeout, TimeUnit unit) { return scheduleDelayed(new ProdConRunner<I>(task, Suppliers.ofInstance(input)), timeout, unit); } /* (non-Javadoc) * @see com.iris.common.scheduler.Scheduler#scheduleDelayed(java.lang.Runnable, long, java.util.concurrent.TimeUnit) */ @Override public ScheduledTask scheduleDelayed(Runnable task, long delay, TimeUnit unit) { Preconditions.checkNotNull(task, "task may not be null"); Preconditions.checkNotNull(unit, "unit may not be null"); // negative delays are allowed, they just mean run ASAP return doSchedule(task, new Date(System.currentTimeMillis() + unit.toMillis(delay)), delay, unit); } /* (non-Javadoc) * @see com.iris.common.scheduler.Scheduler#scheduleAt(java.lang.Runnable, java.sql.Date) */ @Override public ScheduledTask scheduleAt(Runnable task, Date runAt) { Preconditions.checkNotNull(task, "task may not be null"); Preconditions.checkNotNull(runAt, "runAt may not be null"); return doSchedule(task, runAt, Math.max(0, runAt.getTime() - System.currentTimeMillis()), TimeUnit.MILLISECONDS); } /* (non-Javadoc) * @see com.iris.common.scheduler.Scheduler#scheduleAt(java.util.function.Consumer, com.google.common.base.Supplier, java.sql.Date) */ @Override public <I> ScheduledTask scheduleAt(Function<I,?> task, Supplier<I> input, Date runAt) { return scheduleAt(new ProdConRunner<I>(task, input), runAt); } /* (non-Javadoc) * @see com.iris.common.scheduler.Scheduler#scheduleAt(java.util.function.Consumer, java.lang.Object, java.sql.Date) */ @Override public <I> ScheduledTask scheduleAt(Function<I,? extends Object> task, @Nullable I input, Date runAt) { return scheduleAt(new ProdConRunner<I>(task, Suppliers.ofInstance(input)), runAt); } // TODO uncaught exception handler? private static final class ProdConRunner<I> implements Runnable { private final Function<I,?> consumer; private final Supplier<I> producer; ProdConRunner(Function<I,?> task, Supplier<I> input) { Preconditions.checkNotNull(task, "task may not be null"); Preconditions.checkNotNull(input, "input may not be null"); this.consumer = task; this.producer = input; } @Override public void run() { try { consumer.apply(producer.get()); } catch(Exception e) { logger.debug("Error running scheduled task {}", consumer, e); } } } }