Na minha jornada dpara cobrir todos os recursos do Brighter, já falei sobre Hangfire. Agora quero falar sobre o agendador Quartz.NET com o Brighter.
O que é e por que usar Quartz.NET?
O Quartz.NET é um sistema de agendamento de trabalhos open source completo e poderoso que oferece:
- Armazenamento persistente de jobs: Os jobs sobrevivem a reinicializações da aplicação
- Suporte a cluster: Distribui jobs agendados entre múltiplos nós
- Recuperabilidade: Recuperação automática de jobs falhos
- Triggers sofisticados: Baseados em tempo, calendário e triggers compostos
Embora o Brighter ofereça capacidades de agendamento integradas, o Quartz.NET oferece opções de agendamento mais sofisticadas que são essenciais para aplicações empresariais que exigem controle preciso de tempo e persistência de jobs.
Requisitos
- .NET 8 ou superior (Brighter V10 suporta net8.0, net9.0 e netstandard2.0)
- Um projeto .NET com estes pacotes NuGet:
- Quartz.Extensions.Hosting: Habilita a integração do Quartz.NET com ASP.NET Core.
- Paramore.Brighter.MessageScheduler.Quartz: Integra o Quartz.NET com o sistema de agendamento do Brighter.
- Paramore.Brighter.MessagingGateway.Postgres: Habilita integração com PostgreSQL para fila de mensagens.
- Paramore.Brighter.ServiceActivator.Extensions.DependencyInjection: Permite registrar o Brighter com a DI da Microsoft.
- Paramore.Brighter.ServiceActivator.Extensions.Hosting: Hospeda o Brighter como um serviço em segundo plano.
- Serilog.AspNetCore: Para logging estruturado (opcional, mas recomendado).
Revisão dos Conceitos Básicos do Brighter
Antes de mergulhar na integração com o Quartz.NET, vamos revisar brevemente os conceitos-chave do Brighter:
Request (Command/Event)
Defina mensagens usando IRequest
:
public class Greeting() : Event(Id.Random())
{
public string Name { get; set; } = string.Empty;
}
-
Commands: Operações para um único destinatário (ex:
SendEmail
). -
Events: Notificações de broadcast (ex:
OrderShipped
).
Message Mapper (Opcional)
Traduz entre mensagens do Brighter e objetos da sua aplicação. Por padrão, o Brighter usa serialização JSON.
Request Handler
Processa mensagens recebidas:
public class GreetingHandler(ILogger<GreetingHandler> logger) : RequestHandler<Greeting>
{
public override Greeting Handle(Greeting command)
{
logger.LogInformation("Hello {Name}", command.Name);
return base.Handle(command);
}
}
Configurando o Brighter com o Agendador Quartz.NET
1. Registrando o Quartz.NET na DI da Microsoft
Para desenvolvimento, você pode usar armazenamento em memória, mas para ambientes de produção, sempre use uma solução de armazenamento persistente como PostgreSQL
, SQL Server
:
services
.AddQuartz(q =>
{
q.SchedulerId = "QuartzBrighter";
q.SchedulerName = "QuartzBrighter";
// Configuração para PostgreSQL
q.UsePersistentStore(store =>
{
store.UsePostgres(connectionString);
store.UseJsonSerializer();
});
q.UseDefaultThreadPool(maxConcurrency: 10);
})
.AddQuartzHostedService(options =>
{
options.WaitForJobsToComplete = true;
});
2. Registrando o Quartz.NET no Brighter
Para registrar o agendador Quartz no Brighter, utilize o QuartzMessageSchedulerFactory
fornecido pelo pacote Paramore.Brighter.MessageScheduler.Quartz:
services
.AddServiceActivator(options =>
{
// Configuração do Brighter
options.PipelineBuilder = new PipelineBuilder();
options.LoggerFactory = new SerilogLoggerFactory();
// Configuração do gateway de mensagens
var postgresConnection = new PostgreSqlConfiguration(
connectionString,
"outbox",
"inbox"
);
options.UsePostgreSql(postgresConnection);
})
.UseScheduler(provider =>
{
// Obter a fábrica do Quartz e criar o scheduler
var factory = provider.GetRequiredService<ISchedulerFactory>();
var scheduler = factory.GetScheduler().GetAwaiter().GetResult();
return new QuartzMessageSchedulerFactory(scheduler);
});
// Adicionar o serviço hospedado do Brighter
services.AddHostedService<ServiceActivatorHostedService>();
3. Usando o Agendador
Agende mensagens com controle preciso de tempo usando TimeSpan
(relativo) ou DateTimeOffset
(absoluto):
// Agendar para 1 segundo a partir de agora
await process.PostAsync(TimeSpan.FromSeconds(1), new Greeting { Name = "João" });
// Agendar para 2 segundos a partir de agora
await process.SendAsync(TimeSpan.FromSeconds(2), new Greeting { Name = "Maria" });
// Agendar para exatamente 3 segundos a partir de agora
await process.PublishAsync(DateTimeOffset.UtcNow.AddSeconds(3), new Greeting { Name = "Pedro" });
Conclusão
Integrar o Quartz.NET com o Brighter fornece uma solução de agendamento robusta para aplicações empresariais que exigem controle preciso de tempo e persistência de jobs. Embora o Brighter ofereça capacidades básicas de agendamento, o Quartz.NET adiciona recursos de nível empresarial essenciais para ambientes de produção.
Ao seguir este guia, você pode implementar um sistema de agendamento de mensagens confiável que combina as capacidades de mensageria do Brighter com os recursos sofisticados de agendamento do Quartz.NET, criando uma base poderosa para suas aplicações distribuídas.
Lembre-se de sempre usar armazenamento persistente para o Quartz em ambientes de produção e considere implementar monitoramento adequado para seus jobs agendados para garantir a entrega oportuna de suas mensagens.