Running Background Jobs via Queue
Jobby allows you to send commands to the queue for one-time execution of their handlers in the background.
Running via IJobbyClient
To add jobs to the queue, you can use the IJobbyClient service. When using Jobby.AspNetCore, an instance of this service can be obtained from the DI container, or from the JobbyBuilder object otherwise (see Installation and Configuration for details).
Running a Single Job
var command = new SendEmailCommand
{
Email = "some@email.com"
};
// Add a job to the queue for execution as soon as possible
await jobbyClient.EnqueueCommandAsync(command);
// Add a job to the queue for execution no earlier than the specified time
await jobbyClient.EnqueueCommandAsync(command, DateTime.UtcNow.AddHours(1));
// Alternatively, you can use synchronous versions of the methods
jobbyClient.EnqueueCommand(command);The above methods optionally accept a JobOpts structure — additional settings with which the background job will be created. The parameters included in this structure are described on the Job Definition page.
JobOpts parameters passed to the EnqueueCommand method have higher priority than parameters defined at the command class level when implementing the IHasDefaultJobOptions interface. Let's look at an example of how parameters defined at different levels are merged:
class SomeCommand : IJobCommand, IHasDefaultJobOptions
{
public static string GetJobName() => "SomeJob";
// Options at the command class level
public JobOpts GetOptionsForEnqueuedJob() => new JobOpts
{
QueueName = "queue_1",
CanBeRestartedIfServerGoesDown = false
}
}
// Adding a job to the queue
// with queue name override
var command = new SomeCommand();
var opts = new JobOpts
{
QueueName = "queue_2",
}
await jobbyClient.EnqueueCommandAsync(command, opts);The resulting background job will be created with the following options:
QueueName="queue_2"because this parameter was overridden in theEnqueuemethodCanBeRestartedIfServerGoesDown=falsebecause this parameter is defined at the command level and was not overridden in theEnqueuemethod
Running Multiple Jobs
To add multiple jobs within a single transaction, prepare a list of JobCreationModel objects using the factory available at jobbyClient.Factory, then call the EnqueueBatchAsync method:
var jobs = new List<JobCreationModel>
{
jobbyClient.Factory
.Create(new SendEmailCommand { Email = "first@email.com" }),
jobbyClient.Factory
.Create(new SendEmailCommand { Email = "second@email.com" }),
}
await jobbyClient.EnqueueBatchAsync(jobs);The Create method, similarly to the Enqueue method, can accept a JobOpts parameter.
When adding multiple jobs, there is an option to enforce a strict execution order:
var sequenceBuilder = jobbyClient.Factory.CreateSequenceBuilder();
// Jobs will be executed in the exact order specified below
sequenceBuilder.Add(jobbyClient.Factory
.Create(new SendEmailCommand { Email = "first@email.com" }));
sequenceBuilder.Add(jobbyClient.Factory
.Create(new SendEmailCommand { Email = "second@email.com" }));
var jobs = sequenceBuilder.GetJobs();
await jobbyClient.EnqueueBatchAsync(jobs);Job Groups with Sequential Execution
When creating a job, you can specify a group identifier, and Jobby will guarantee that no more than one job is executed at any given time within each group.
await jobbyClient.EnqueueCommandAsync(command, new JobOpts
{
SerializableGroupId = "SomeGroupId"
});The next job in the group will start only after the current job completes, whether successfully or unsuccessfully. If you need to block the execution of any jobs from the same group upon unsuccessful completion, set the LockGroupIfFailed flag when creating the job:
await jobbyClient.EnqueueCommandAsync(command, new JobOpts
{
SerializableGroupId = "SomeGroupId",
LockGroupIfFailed = true
});For more details about this feature, see Sequential Execution.
Running via ORM
If your project uses EntityFramework (or another ORM), you can use your DbContext to add jobs. This can be useful when you need to both queue a job and perform an operation on a domain entity within the same transaction.
To do this:
- Add the
JobCreationModelentity to your DbContext - Configure the table name as
jobby_jobsfor this entity and specify theIdfield as the primary key - Apply the appropriate naming convention (snake_case for PostgreSQL)
Now you can create background jobs as follows:
- Create
JobCreationModelobjects usingjobbyClient.Factory - Save them to the database using standard DbContext methods
public class YourDbContext : DbContext
{
// Add a DbSet for the JobCreationModel entity
public DbSet<JobCreationModel> Jobs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<JobCreationModel>()
.ToTable("jobby_jobs");
modelBuilder
.Entity<JobCreationModel>()
.HasKey(x => x.Id);
// Then apply the snake_case naming convention
// ...
}
}
// Queuing a job via EF
var command = new SendEmailCommand { Email = "some@email.com" };
var jobEntity = jobbyClient.Factory.Create(command);
_dbContext.Jobs.Add(job);
await _dbContext.SaveChangesAsync();An example of using EF is available here: Jobby.Samples.AspNet.
Job Cancellation
A task added to the queue can be cancelled if it hasn't been started yet.
var startTime = DateTime.UtcNow.AddHours(1);
// Create a task
// and get its instance id
var jobId = await jobbyClient.EnqueueCommandAsync(command, startTime);
// Cancel the task by instance id
await jobbyClient.CancelJobsByIdsAsync(jobId);