DEV Community

Cover image for Scheduling Messages with Brighter V10 and Hangfire
Rafael Andrade
Rafael Andrade

Posted on

Scheduling Messages with Brighter V10 and Hangfire

In previous articles, I covered Brighter V10 RC1 and using PostgreSQL as a messaging gateway). One of Brighter's key features is message scheduling via Send, Publish, and Post methods using either DateTimeOffset or TimeSpan parameters. While Brighter's default scheduler uses an in-memory Timer, it also supports external schedulers like Hangfire, Quartz.NET, AWS EventBridge Scheduler, and Azure Service Bus.

Why Use Hangfire with Brighter?

Hangfire offers a robust, production-ready scheduling solution with persistent storage, dashboard monitoring, and retry capabilities—making it ideal for enterprise applications where message delivery reliability is critical. Unlike the in-memory scheduler, Hangfire maintains scheduled jobs across application restarts.

Requirement

Brighter Recap

Before diving into the Hangfire integration, let's briefly review key Brighter concepts:

Request (Command/Event)

Define messages using IRequest:

public class Greeting() : Event(Guid.NewGuid())
{
    public string Name { get; set; } = string.Empty;
}
Enter fullscreen mode Exit fullscreen mode
  • Commands: Single-recipient operations (e.g., SendEmail).
  • Events: Broadcast notifications (e.g., OrderShipped).

Message Mapper (Optional)

Translates between Brighter messages and your app objects, by default Brighter will use JSON serialize.

Request Handler

Processes incoming messages:

public class GreetingHandler(ILogger<GreetingHandler> logger) : RequestHandler<Greeting>
{
    public override Greeting Handle(Greeting command)
    {
        logger.LogInformation("Hello {Name}", command.Name);
        return base.Handle(command);
    }
}
Enter fullscreen mode Exit fullscreen mode

Configuring Brighter with Hangfire Scheduler

1. Register Hangfire into Microsoft DI

For development, you can use in-memory storage, but for production environments, always use a persistent storage solution like PostgreSQL, SQL Server, or Redis:

services
    .AddHangfire(opt => opt
        .UseDefaultActivator()
        .UseRecommendedSerializerSettings()
        .UseSimpleAssemblyNameTypeSerializer()
        .UseInMemoryStorage())
    .AddHangfireServer();
Enter fullscreen mode Exit fullscreen mode

2. Register Hangfire on Brighter

Register the Hangfire scheduler factory with Brighter. Since Hangfire needs to be fully initialized before Brighter can use it, we use a factory pattern:

services
    .AddHostedService<ServiceActivatorHostedService>()
    .AddServiceActivator(opt => ... )
    .UseScheduler(_ => new HangfireMessageSchedulerFactory())
Enter fullscreen mode Exit fullscreen mode

3. Using the Scheduler

Schedule messages with precise timing control using either relative (TimeSpan) or absolute (DateTimeOffset) timing:

// Schedule for 1 second from now
await process.PostAsync(TimeSpan.FromSeconds(1), new SchedulerCommand { Name = name, Type = "Post"});

// Schedule for 2 seconds from now
await process.SendAsync(TimeSpan.FromSeconds(2), new SchedulerCommand { Name = name, Type = "Send"});

// Schedule for exactly 3 seconds from now
await process.PublishAsync(DateTimeOffset.UtcNow + TimeSpan.FromSeconds(3), new SchedulerCommand { Name = name, Type = "Publish"});
Enter fullscreen mode Exit fullscreen mode

Important Considerations

  1. Production Deployment: Never use Hangfire.InMemory in production. Configure Hangfire with a persistent storage backend that matches your infrastructure.

  2. Error Handling: Hangfire automatically retries failed jobs according to its configuration. Review Hangfire's retry policies to ensure they align with your message delivery requirements.

  3. Monitoring: Take advantage of Hangfire's dashboard to monitor scheduled jobs, processing history, and potential failures.

Conclusion

Integrating Hangfire with Brighter V10 creates a powerful scheduling solution that combines Brighter's robust messaging patterns with Hangfire's reliable job processing. This combination is particularly valuable for scenarios requiring delayed message processing or guaranteed delivery after system restarts.

The in-memory scheduler is perfect for development and testing, but for production environments, Hangfire provides the durability and monitoring capabilities needed for enterprise applications.

View full implementation on GitHub

Top comments (0)