org.apache.sling.commons.scheduler.Scheduler Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.sling.commons.scheduler;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import java.util.NoSuchElementException;
import org.osgi.annotation.versioning.ProviderType;
/**
* A scheduler to schedule time/cron based jobs.
* A job is an object that is executed/fired by the scheduler. The object
* should either implement the {@link Job} interface or the {@link Runnable}
* interface.
*
* A job can be scheduled either by creating a {@link ScheduleOptions} instance
* through one of the scheduler methods and then calling {@link #schedule(Object, ScheduleOptions)}
* or
* by using the whiteboard pattern and registering a Runnable service with either
* the {@link #PROPERTY_SCHEDULER_EXPRESSION} or {@link #PROPERTY_SCHEDULER_PERIOD}
* property. If both properties are specified, only {@link #PROPERTY_SCHEDULER_PERIOD}
* is considered for scheduling.
*
* Services registered by the whiteboard pattern can by default run concurrently,
* which usually is not wanted. Therefore it is advisable to also set the
* {@link #PROPERTY_SCHEDULER_CONCURRENT} property with Boolean.FALSE.
*
* Jobs started through the scheduler API are not persisted and are not
* restarted after a bundle restart. If the client bundle is stopped, the scheduler
* will stop all jobs started by this bundle as well. However, the client bundle does
* not need to keep a reference to the scheduler service.
*/
@ProviderType
public interface Scheduler {
/** Name of the configuration property to define the period for a job.
* The period is expressed in seconds.
* This property needs to be of type Long.
*/
String PROPERTY_SCHEDULER_PERIOD = "scheduler.period";
/** Name of the configuration property to define if a periodically job
* should be scheduled immediate.
* Default is to not startup immediate, the job is started the first time
* after the period has expired.
* This property needs to be of type Boolean.
* @since 2.2.0 .*/
String PROPERTY_SCHEDULER_IMMEDIATE = "scheduler.immediate";
/** Name of the configuration property to define the cron expression for a job. */
String PROPERTY_SCHEDULER_EXPRESSION = "scheduler.expression";
/** Name of the configuration property to define if the job can be run concurrently. */
String PROPERTY_SCHEDULER_CONCURRENT = "scheduler.concurrent";
/** Name of the configuration property to define the job name. */
String PROPERTY_SCHEDULER_NAME = "scheduler.name";
/** Name of the optional configuration property to define the number of times the job
* should be executed when {@link #PROPERTY_SCHEDULER_PERIOD} is defined.
* This property is of type integer and must have a positive value.
*/
String PROPERTY_SCHEDULER_TIMES = "scheduler.times";
/**
* Name of the configuration property to define the instances this job should run on.
* By default a job is run on all instances where the scheduler has been instructed to
* schedule the job, e.g. if the same code is running on all instances.
* This property can be configured with:
* - constant {@link #VALUE_RUN_ON_LEADER} : the job is only run on the leader
* - constant {@link #VALUE_RUN_ON_SINGLE} : the job is only run on a single instance in a cluster. This is
* basically the same as {@link #VALUE_RUN_ON_LEADER} but it's not further specified which
* single instance is used.
* Default is to start the job on all instances. This property needs to be of type String.
* If no topology information is available (= no Apache Sling Discovery Implementation active)
* this option is ignored, and the job is run on all instances.
* @since 2.3.0
*/
String PROPERTY_SCHEDULER_RUN_ON = "scheduler.runOn";
/** Value for {@link #PROPERTY_SCHEDULER_RUN_ON} to run the job on the leader only.
* @since 2.3.0
*/
String VALUE_RUN_ON_LEADER = "LEADER";
/** Value for {@link #PROPERTY_SCHEDULER_RUN_ON} to run the job on a single instance only.
* @since 2.3.0
*/
String VALUE_RUN_ON_SINGLE = "SINGLE";
/**
* Name of the configuration property to define the thread pool to be used.
* Scheduled jobs can run using different thread pools. By default, the default
* thread pool of the scheduler is used.
* If a thread pool name is specified, it is up to the scheduler to put the job
* in the defined thread pool or any other thread pool.
* This option must be used with special care as it might create new thread pools.
* It should only be used if there is a good reason to not use the default thread
* pool.
* @since 2.5.0
*/
String PROPERTY_SCHEDULER_THREAD_POOL = "scheduler.threadPool";
/**
* Schedule a job based on the options.
*
* Note that if a job with the same name has already been added, the old job is
* cancelled and this new job replaces
* the old job.
*
* The job object needs either to be a {@link Job} or a {@link Runnable}. The
* options have to be created
* by one of the provided methods from this scheduler.
*
* The job is only started on this instance - if it is started at all. The
* options for running on a single instance, on the leader etc. (see
* {@link ScheduleOptions#onInstancesOnly(String[])},
* {@link ScheduleOptions#onLeaderOnly(boolean)},
* and {@link ScheduleOptions#onSingleInstanceOnly(boolean)}) are only useful,
* if the same job is scheduled on all instances in a cluster. In this case this
* extra configuration controls on which instances the job is really started.
* Using the above options might not start the job on the current instance, for
* example if the current instance is not the leader.
*
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param options Required options defining how to schedule the job
* @return true if the job could be added, false otherwise.
* @see #NOW()
* @see #NOW(int, long)
* @see #AT(Date)
* @see #AT(Date, int, long)
* @see #EXPR(String)
* @since 2.3
*/
boolean schedule(Object job, ScheduleOptions options);
/**
* Remove a scheduled job by name.
*
* @param jobName The name of the job.
* @return true
if the job existed and could be stopped, false
otherwise.
* @since 2.3
*/
boolean unschedule(String jobName);
/**
* Create a schedule options to fire a job immediately and only once.
* @return The schedule options.
* @since 2.3
*/
ScheduleOptions NOW();
/**
* Create a schedule options to fire a job immediately more than once.
* @param times The number of times this job should be started (must be higher than 1 or
* -1 for endless)
* @param period Every period seconds this job is started (must be at higher than 0).
* @return The schedule options.
* @since 2.3
*/
ScheduleOptions NOW(int times, long period);
/**
* Create a schedule options to fire a job once at a specific date.
* In case the scheduled time was missed due to the Scheduler not running or no thread being available at that point in time
* the job will be executed only once, as soon as the Scheduler is running again and a thread is available for processing the job.
* @param date The date this job should be run.
* @return The schedule options.
* @since 2.3
*/
ScheduleOptions AT(Date date);
/**
* Create a schedule options to fire a job period starting at a specific date.
* In case the scheduled time was missed due to the Scheduler not running or no thread being available at that point in time
* the behavior depends on the {@code times} parameter:
*
* - If {@code times} is -1 (meaning unlimited repetitions) there will be no immediate action. Instead the scheduler just waits for next scheduled interval.
*
- Otherwise (limited amount of repitions) the job will be executed only once, as soon as the Scheduler is running again and a thread is available for processing the job.
* Then the scheduler waits desired interval and executes all remaining triggers.
* Effectively the first fire time of the misfired trigger is moved to current time with no other changes.
*
*
* @param date The date this job should be run.
* @param times The number of times this job should be started (must be higher than 1 or
* -1 for endless)
* @param period Every period seconds this job is started (must be at higher than 0).
* @return The schedule options.
* @since 2.3
*/
ScheduleOptions AT(Date date, int times, long period);
/**
* Create a schedule options to schedule the job based on the expression.
* In case the scheduled time was missed due to the Scheduler not running or no thread being available at that point in time
* the job will be executed only once, as soon as the Scheduler is running again and a thread is available for processing the job.
* No matter how many trigger executions were missed, only a single immediate execution is performed.
* @param expression The cron exception
* @return The schedule options.
* @since 2.3
*/
ScheduleOptions EXPR(String expression);
/**
/**
* Schedule a time based job.
* Note that if a job with the same name has already been added, the old job is cancelled and this new job replaces
* the old job.
*
* @param name The name of the job - or null. If no name is specified it can't be cancelled.
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @param schedulingExpression The time specification using a scheduling expression.
* @param canRunConcurrently Whether this job can run even if previous scheduled runs are still running.
* @throws IllegalArgumentException If the scheduling expression can't be parsed or if the job has not the correct type.
* @throws Exception If the job can't be scheduled.
* @deprecated Use {@link #schedule(Object, ScheduleOptions)} instead.
*/
@Deprecated
void addJob(String name, Object job, Map config, String schedulingExpression, boolean canRunConcurrently)
throws Exception;
/**
* Schedule a periodic job.
* The job is started the first time when the period has passed.
* Note that if a job with the same name has already been added, the old job is cancelled and this new job replaces
* the old job.
*
* @param name The name of the job - or null. If no name is specified it can't be cancelled.
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @param period Every period seconds this job is started.
* @param canRunConcurrently Whether this job can run even if previous scheduled runs are still running.
* @throws IllegalArgumentException If the job has not the correct type.
* @throws Exception If the job can't be scheduled.
* @deprecated Use {@link #schedule(Object, ScheduleOptions)} instead.
*/
@Deprecated
void addPeriodicJob(String name, Object job, Map config, long period, boolean canRunConcurrently)
throws Exception;
/**
* Schedule a periodic job.
* Note that if a job with the same name has already been added, the old job is cancelled and this new job replaces
* the old job.
*
* @param name The name of the job - or null. If no name is specified it can't be cancelled.
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @param period Every period seconds this job is started.
* @param canRunConcurrently Whether this job can run even if previous scheduled runs are still running.
* @param startImmediate Whether to start the job immediately for the first time or wait for the period to expire.
* @throws IllegalArgumentException If the job has not the correct type.
* @throws Exception If the job can't be scheduled.
* @since 2.2
* @deprecated Use {@link #schedule(Object, ScheduleOptions)} instead.
*/
@Deprecated
void addPeriodicJob(String name, Object job, Map config, long period, boolean canRunConcurrently,
boolean startImmediate)
throws Exception;
/**
* Fire a job immediately and only once.
*
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @throws IllegalArgumentException If the job has not the correct type.
* @throws Exception If the job can't be scheduled.
* @deprecated Use {@link #schedule(Object, ScheduleOptions)} instead.
*/
@Deprecated
void fireJob(Object job, Map config)
throws Exception;
/**
* Fire a job immediately more than once.
*
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @param times The number of times this job should be started (must be higher than 1)
* @param period Every period seconds this job is started.
* @throws IllegalArgumentException If the job has not the correct type.
* @return true if the code could be added, false otherwise.
* @since 2.1
* @deprecated Use {@link #schedule(Object, ScheduleOptions)} instead.
*/
@Deprecated
boolean fireJob(Object job, Map config, int times, long period);
/**
* Fire a job once at a specific date
* Note that if a job with the same name has already been added, the old job is cancelled and this new job replaces
* the old job.
*
* @param name The name of the job - or null. If no name is specified it can't be cancelled.
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @param date The date this job should be run.
* @throws IllegalArgumentException If the job has not the correct type.
* @throws Exception If the job can't be scheduled.
* @deprecated Use {@link #schedule(Object, ScheduleOptions)} instead.
*/
@Deprecated
void fireJobAt(String name, Object job, Map config, Date date)
throws Exception;
/**
* Fire a job once at a specific date, several times with a given interval.
* Note that if a job with the same name has already been added, the old job is cancelled and this new job replaces
* the old job.
*
* @param name The name of the job - or null. If no name is specified it can't be cancelled.
* @param job The job to execute (either {@link Job} or {@link Runnable}).
* @param config An optional configuration object - this configuration is only passed to the job the job implements {@link Job}.
* @param date The date this job should be run.
* @param times The number of times this job should be started (must be higher than 1)
* @param period Every period seconds this job is started.
* @throws IllegalArgumentException If the job has not the correct type.
* @return true if the job could be added, false otherwise.
* @since 2.1
* @deprecated Use {@link #schedule(Object, ScheduleOptions)} instead.
*/
@Deprecated
boolean fireJobAt(String name, Object job, Map config, Date date, int times, long period);
/**
* Remove a scheduled job by name.
*
* @param name The name of the job.
* @throws NoSuchElementException If the job is not scheduled.
* @deprecated Use {@link #unschedule(String)} instead.
*/
@Deprecated
void removeJob(String name)
throws NoSuchElementException;
}