JobRunr : The ultimate open source library for background processing in Java

Posted in Recipe on January 28, 2023 by Venkatesh S ‐ 3 min read


jobrunr

What is JobRunr?

The ultimate library for background processing in Java. Distributed and backed by persistent storage. Open-source and free for commercial use.

It is an alternative for Spring Batch and Quartz Scheduler. Provies an out of the box CRON scheduler and a Job Runner with an amazing dashboard of its own to monitor the jobs.

JobRunr UseCase

In my general experience, there are many instances where we want garunteed execution of the jobs. Typically any framework that provies these services allow us to

  • Creating background jobs and then schedule them for execution later.
  • Dynamically trigger jobs and then execute them that instance.
  • Dynamically trigger jobs and then schedule them for execution later.

Also we need a system to monitor the jobs. Monitoring involves

  • Viewing the scheduled jobs
  • Checking status of the jobs on the queue
  • Viewing which jobs are in processing or in progress status
  • Checking Successful Executions
  • Checking failed executions

Imagine all these services available to you by just adding a simple library dependency and writing a few lines of code, welcome to JobRunr.

JobRunr Architecture

Architecture

  • When enqueueing a background job, the lambda is decomposed and saved into the storage provider as Json.
  • JobRunr returns immediately to the caller so that it is not blocking
  • One or more background job servers poll the storage provider for new enqueued jobs and process them
  • When finished, it updates the state in the storage provider and fetches the next job to perform

JobRunr Implementation

The process of implemeting JobRunr with spring boot is very simple. It has only 4 steps.

  • Add the spring boot starter dependency as follows
<dependency> 
  <groupId>org.jobrunr</groupId> 
  <artifactId>jobrunr-spring-boot-starter</artifactId> 
  <version>${jobrunr.version}</version> <!-- At this time version is 5.3.3-->
</dependency>
  • Enable the following in application.properties file
org.jobrunr.background-job-server.enabled=true
org.jobrunr.dashboard.enabled=true
  • Configure a datasource where JobRunr will save all the job states and also persist jobs.

The below example shows adding a sqlite dependency

<dependency>
  <groupId>org.xerial</groupId>
  <artifactId>sqlite-jdbc</artifactId>
  <version>${sql-lite.version}</version> <!-- At this time version is 3.40.0.0-->
</dependency>

Also create a new JobRunr storage configuration. You can see that here the jobrunner uses the sqllite data source and creates a jobrunr-example.db file where it persists the state.

import java.nio.file.Paths;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.sqlite.SQLiteDataSource;

@Configuration
@ComponentScan(basePackageClasses = JobRunrStorageConfiguration.class)
public class JobRunrStorageConfiguration {

    @Bean
    public SQLiteDataSource dataSource() {
        final SQLiteDataSource dataSource = new SQLiteDataSource();
        dataSource.setUrl("jdbc:sqlite:" + Paths.get(System.getProperty("java.io.tmpdir"), "jobrunr-example.db"));
        return dataSource;
    }

}
  • Last step you can now add your jobs and trigger them as per your wish
    // schedule a recurring job
    @Recurring(id = "recurring-job", cron = "*/10 * * * * *")
    @Job(name = "My Sample Job")
    public void doRecurringJob() {
        System.out.println("Doing some work without arguments");
    }

    // create a new background job when called
    public void triggerJob() {
        BackgroundJob.enqueue(() -> System.out.println("Enqueing a background job"));
    }

    // create a new background job when called from current instance plus 10 seconds
    public void scheduleJob() {
        BackgroundJob.schedule(Instant.now().plusSeconds(10), () -> System.out.println("Triggering Scheduled Job after 10 seconds"));
    }

    // create a new background job recurrently when called every 15 seconds
    public void recurrentJob() {
        BackgroundJob.scheduleRecurrently(Cron.every15seconds(), () -> System.out.println("Triggering every 15 seconds"));
    }

Complete source code for this example is available at https://github.com/vensr/jobrunr

JobRunr Dashboards

JobRunr provides amazing dashboards to monitor the progress of the jobs, some screens are as shown below.

A complete overview of the amount of jobs that are being processed

Jobs Processed

An overview of all enqueued jobs

Jobs Enqued

When a job failed, you see a detailed message why it did fail

Jobs Failed

A detailed overview of a succeeded job

Jobs Success

An overview of all recurring jobs with the ability to trigger or delete them

Jobs Trigger

An overview of all background job servers processing background jobs

Jobs Background

References