Recurring jobs

Schedule recurring jobs with a single line of code using any CRON expression.

Creating a recurring job is just as simple as creating a background job – you only need to write a single line of code (and it is even less if you use the jobrunr-spring-boot-starter, jobrunr-micronaut-feature or the jobrunr-quarkus-extension):

BackgroundJob.scheduleRecurrently(Cron.daily(), () -> System.out.println("Easy!"));

This line creates a new recurring job entry in the StorageProvider. A special component in BackgroundJobServer checks the recurring jobs on a minute-based interval and then enqueues them as fire-and-forget jobs. This enables you to track them as usual.

Remark: for recurring methods to work, at least one BackgroundJobServer should be running all the time and the jobs should be registered on startup of your application. Also note that the smallest possible cron interval for your recurring jobs is every 5 seconds. JobRunr prevents to create recurring jobs every with cron values less than 5 seconds (e.g. every second) as it would generate too much load on your StorageProvider (SQL or noSQL database).

The Cron class contains different methods and overloads to run jobs on a minute, hourly, daily, weekly, monthly and yearly basis. You can also use standard CRON expressions to specify a more complex schedule:

BackgroundJob.scheduleRecurrently("0 12 * */2", () -> System.out.println("Powerful!"));

All these methods are also available on the JobScheduler and JobRequestScheduler bean:

@Inject
private JobScheduler jobScheduler;

jobScheduler.scheduleRecurrently(Cron.daily(), () -> System.out.println("Easy!"));
@Inject
private JobRequestScheduler jobRequestScheduler;

jobRequestScheduler.scheduleRecurrently(Cron.daily(), new SysOutJobRequest("Easy!"));

Specifying identifiers

Each recurring job has its own unique identifier. In the previous examples it was generated implicitly, using the type and method names of the given call expression (resulting in “System.out.println” as the identifier). The BackgroundJob and JobScheduler class contains overloads that take an explicitly defined job identifier. This way, you can refer to the job later on.

BackgroundJob.scheduleRecurrently("some-id", "0 12 * */2",
  () -> System.out.println("Powerful!"));

The call to the scheduleRecurrently method will create a new recurring job if no recurring job with that id exists or else update the existing job with that identifier.

Identifiers should be unique - use unique identifiers for each recurring job, otherwise you’ll end with a single job.

Manipulating recurring jobs

You can remove an existing recurring job by calling the BackgroundJob.delete method. It does not throw an exception when there is no such recurring job.

Registering your recurring jobs

To make sure that your recurring jobs are properly registered, you need to make sure that the code to register these jobs (e.g. the examples above), is run when your application starts (which can either be a webapp, a console app, …). This is different for each application/environment. The easiest way to do so is via the @Recurring annotation that ships with the jobrunr-spring-boot-starter, the quarkus-jobrunr extension or the jobrunr-micronaut-feature. Here are some examples on how it could be done:

Spring Framework

Using JobRunr’s @Recurring annotation

@Service
public class SampleService {

    @Recurring(id = "my-recurring-job", cron = "*/5 * * * *")
    @Job(name = "My recurring job")
    public void executeSampleJob() {
        // your business logic here
        // you can also conditionally enqueue a new job - better visibility in the dashboard
    }
}
Micronaut

Using JobRunr’s @Recurring annotation

@Singleton
public class SampleService {

    @Recurring(id = "my-recurring-job", cron = "*/5 * * * *")
    @Job(name = "My recurring job")
    public void executeSampleJob() {
        // your business logic here
        // you can also conditionally enqueue a new job - better visibility in the dashboard
    }
}
Quarkus

Using JobRunr’s @Recurring annotation

@ApplicationScoped
@RegisterForReflection
public class SampleService {

    @Recurring(id = "my-recurring-job", cron = "*/5 * * * *")
    @Job(name = "My recurring job")
    public void executeSampleJob() {
        // your business logic here
        // you can also conditionally enqueue a new job - better visibility in the dashboard
    }
}
Other ways

If you are not using an integration with a certain framework, you will need to register these scheduled jobs yourselves using Container Startup Event listeners.