Enqueueing jobs
Fire-and-forget method invocation has never been simpler thanks to JobRunr.
Creating a background job with JobRunr is really easy. On this page you will learn how to:
- create a single job using a Java 8 lambda
- create a single job using a JobRequest
- create many jobs using a Java 8 lambda
- create many jobs using a JobRequest
- JobRunr Pro Prevent duplicate jobs by an identifier
- JobRunr Pro Replace existing jobs
Enqueueing a single background job
Enqueueing a job using a Java 8 lambda
As you already know from the 5 minute intro, you only need to pass a lambda with the corresponding method and its arguments to enqueue a background job:
JobId jobId = BackgroundJob.enqueue(() -> myService.doWork());
JobId jobId = BackgroundJob.<MyService>enqueue(x -> x.doWork());
Enqueueing a job using a JobRequest
JobRunr also offers the possibility to enqueue jobs using a JobRequest and a JobRequestHandler.
JobId jobId = BackgroundJobRequest.enqueue(new MyJobRequest());
JobId jobId = BackgroundJob.create(aJob()
.withName("Generate sales report")
.<SalesReportService>withDetails(service -> service.generateSalesReport()));
The methods above do not call the target method immediately but instead run the following steps:
- Either the
JobRequest
is used or the lambda is analyzed to extract the method information and all its arguments. - The method information and all its arguments are serialized to JSON.
- A new background job is created based on the serialized information.
- The background job is saved to the configured
StorageProvider
. - After these steps were performed, the
BackgroundJob.enqueue
orBackgroundJob.create
method immediately returns to the caller. Another JobRunr component, calledBackgroundJobServer
, checks the persistent storage for enqueued background jobs and performs them in a reliable way.
Instead of the static methods on the BackgroundJob
class, you can also use the JobScheduler
bean. It has exactly the same methods as the BackgroundJob
class. To use it, just let your dependency injection framework inject an instance of the JobScheduler
bean and continue as before:
@Inject
private JobScheduler jobScheduler;
jobScheduler.enqueue(() -> myService.doWork());
As before, you also do not need an instance of the myService available if the MyService
class is know by your dependency injection framework.
Enqueueing a job using the JobScheduler and a Java 8 lambda
@Inject
private JobScheduler jobScheduler;
jobScheduler.<MyService>enqueue(x -> x.doWork());
Enqueueing a job using the JobRequestScheduler and a JobRequest
@Inject
private JobRequestScheduler jobRequestScheduler;
jobRequestScheduler.enqueue(new MyJobRequest());
@Inject
private JobScheduler jobScheduler;
@Inject
private SalesReportService salesReportService;
jobScheduler.create(aJob()
.withName("Generate sales report")
.withDetails(() -> salesReportService.generateSalesReport()));
Enqueueing background jobs in bulk
Sometimes you want to enqueue a lot of jobs - for example send an email to all users. JobRunr can process a Java 8 Stream
Enqueueing many jobs using a Java 8 lambda
Stream<User> userStream = userRepository.getAllUsers();
BackgroundJob.enqueue(userStream, (user) -> mailService.send(user.getId(), "mail-template-key"));
Stream<User> userStream = userRepository.getAllUsers();
BackgroundJob.enqueue<MailService, User>(userStream, (service, user) -> service.send(user.getId(), "mail-template-key"));
Enqueueing many jobs using a JobRequest
Stream<SendMailJobRequest> jobStream = userRepository
.getAllUsers()
.map(user -> new SendMailJobRequest(user.getId(), "mail-template-key"));
BackgroundJobRequest.enqueue(jobStream);
Stream<JobBuilder> jobStream = userRepository
.getAllUsers()
.map(user -> aJob().withName("Send email").withJobRequest(new SendMailJobRequest(user.getId(), "mail-template-key")));
BackgroundJobRequest.create(jobStream);
This allows for nice integration with the Spring Data framework which can return Java 8 Streams - this way, items can be processed incrementally and the entire database must not be put into memory.
Of course the above methods to enqueue jobs can also be done using the JobScheduler bean.
Enqueueing many jobs using the JobScheduler and a Java 8 lambda
@Inject
private JobScheduler jobScheduler;
Stream<User> userStream = userRepository.getAllUsers();
jobScheduler.enqueue(userStream, (user) -> mailService.send(user.getId(), "mail-template-key"));
@Inject
private JobScheduler jobScheduler;
Stream<User> userStream = userRepository.getAllUsers();
jobScheduler.enqueue<MailService, User>(userStream, (service, user) -> service.send(user.getId(), "mail-template-key"));
Enqueueing many jobs using the JobRequestScheduler and a JobRequest
Stream<SendMailJobRequest> jobStream = userRepository
.getAllUsers()
.map(user -> new SendMailJobRequest(user.getId(), "mail-template-key"));
jobRequestScheduler.enqueue(jobStream);
Stream<JobBuilder> jobStream = userRepository
.getAllUsers()
.map(user -> aJob()
.withName("Send email")
.withJobRequest(new SendMailJobRequest(user.getId(), "mail-template-key")));
jobRequestScheduler.create(jobStream);
Prevent duplicate jobs thanks to the JobIdentifier
Sometimes you want to limit how many times a job is created. JobRunr Pro helps you with the JobIdentifier
which will only create the job if no job with that identifier exists.
Creating a job only once using a JobIdentifier
@Inject
private JobScheduler jobScheduler;
jobScheduler.<MyService>enqueue(JobId.fromIdentifier("my identifier"), x -> x.doWork());
Replacing an existing job using a JobIdentifier
If you need to replace an existing job with an identifier, this can be done as follows:
@Inject
private JobScheduler jobScheduler;
jobScheduler.<MyService>enqueueOrReplace(JobId.fromIdentifier("my identifier"), x -> x.doWork());
You can learn more about replacing and updating jobs here.
Please also see the best practices for more information.