# Scheduling
Time is important, particularly in distributed applications. Sophisticated systems need to schedule things, and MassTransit has extensive scheduling support.
MassTransit supports two different methods of message scheduling:
- Scheduler-based, using either Quartz.NET or Hangfire, where the scheduler runs in a service and schedules messages using a queue.
- Transport-based, using the transports built-in message scheduling/delay capabilities. In some cases, such as RabbitMQ, this requires an additional plug-in to be installed and configured.
Recurring schedules are only supported by scheduler-based solutions (Option 1).
# Configuration
Depending upon the scheduling method used, the bus must be configured to use the appropriate scheduler.
# Quartz.NET / Hangfire
To configure the bus to use either Quartz.NET or Hangfire for message scheduling, add the UseMessageScheduler method as shown below.
namespace SchedulingEndpoint
{
using System;
using MassTransit;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main()
{
var services = new ServiceCollection();
Uri schedulerEndpoint = new Uri("queue:scheduler");
services.AddMassTransit(x =>
{
x.AddMessageScheduler(schedulerEndpoint);
x.UsingRabbitMq((context, cfg) =>
{
cfg.UseMessageScheduler(schedulerEndpoint);
cfg.ConfigureEndpoints(context);
});
});
}
}
}
The UseMessageScheduler configures the bus to use the scheduler endpoint. The AddMessageScheduler adds IMessageScheduler to the container, which will use the same scheduler endpoint.
Quartz.NET Docker Image
MassTransit provides a Docker Image (opens new window) with Quartz.NET ready-to-run using SQL Server. A complementary SQL Server Image (opens new window) configured to run with Quartz.NET is also available. Combined, these images make getting started with Quartz easy.
Quartz.NET can also be configured in-memory, which is great for unit testing.
namespace SchedulingInMemory
{
using System;
using MassTransit;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main()
{
var services = new ServiceCollection();
services.AddMassTransit(x =>
{
x.AddMessageScheduler(new Uri("queue:scheduler"));
x.UsingRabbitMq((context, cfg) =>
{
cfg.UseInMemoryScheduler("scheduler");
cfg.ConfigureEndpoints(context);
});
});
}
}
}
The UseInMemoryScheduler method initializes Quartz.NET for standalone in-memory operation, and configures a receive endpoint named scheduler
. The AddMessageScheduler adds IMessageScheduler to the container, which will use the same scheduler endpoint.
WARNING
Using the in-memory scheduler uses non-durable storage. If the process terminates, any scheduled messages will be lost, immediately, never to be found again. For any production system, using a standalone service is recommended with persistent storage.
# Transport-based
To configure transport-based message scheduling, refer to the transport-specific section for details.