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
- .NET 8 or superior (Brighter V10 supports net8.0, net9.0 and netstandard2.0)
- A .NET project with these NuGet packages
- Hangfire.AspNetCore: Enables Hangfire integration with ASP.NET Core.
- Hangfire.InMemory: Provides an in-memory storage option for development (use database-backed storage in production)
- Paramore.Brighter.MessageScheduler.Hangfire: Integrates Hangfire with Brighter's scheduling system.
- Paramore.Brighter.MessagingGateway.Postgres: Enables Postgres integration for message queuing.
- Paramore.Brighter.ServiceActivator.Extensions.DependencyInjection: Enable register Brighter with Microsoft DI.
- Paramore.Brighter.ServiceActivator.Extensions.Hosting: Hosts Brighter as a background service.
- Serilog.AspNetCore: For structured logging (optional but recommended).
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;
}
- 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);
}
}
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();
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())
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"});
Important Considerations
Production Deployment: Never use Hangfire.InMemory in production. Configure Hangfire with a persistent storage backend that matches your infrastructure.
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.
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.
Top comments (0)