public async Task Handle(PublishExpiredTasksCommand command) { DateTime after = DateTime.Now.AddMinutes(-1); IQueryable <PublishedTask> query = from task in Databases.Snittlistan.PublishedTasks.Include(x => x.Tenant) where task.PublishDate < after && task.HandledDate == null select task; PublishedTask[] expiredTasks = await query.ToArrayAsync(); if (expiredTasks.Length == 0) { return; } using MsmqGateway msmqGateway = MsmqFactory.Create(); using MsmqGateway.MsmqTransactionScope scope = msmqGateway.Create(); foreach (PublishedTask publishedTask in expiredTasks) { MessageEnvelope message = new( publishedTask.Task, publishedTask.TenantId, publishedTask.Tenant.Hostname, publishedTask.CorrelationId, publishedTask.CausationId, publishedTask.MessageId); scope.Send(message); } scope.Commit(); Logger.InfoFormat("published {length} expired messages", expiredTasks.Length); }
public void Run(string[] args) { bool force = args.Length == 2 && args[1] == "--force"; using (MsmqGateway.MsmqTransactionScope scope = MsmqGateway.AutoCommitScope()) { foreach (System.Uri apiUrl in CommandLineTaskHelper.AllApiUrls()) { scope.PublishMessage(new MessageEnvelope(new VerifyMatchesMessage(force), apiUrl)); } scope.Commit(); } }
public void PublishTask(TaskBase task, string createdBy) { Logger.Info("{createdBy} publish task {@task}", createdBy, task); PublishedTask publishedTask = databases.Snittlistan.PublishedTasks.Add( PublishedTask.CreateImmediate( task, currentTenant.TenantId, correlationId, causationId, createdBy)); try { HostingEnvironment.QueueBackgroundWorkItem(ct => PublishMessage(currentTenant, publishedTask.MessageId, ct)); } catch (Exception ex) { Logger.Error( ex, "QueueBackgroundWorkItem failed, using fallback (publish immediately)"); try { DoPublishMessage(currentTenant, publishedTask); } catch (Exception ex2) { Logger.Error(ex2); } } async void PublishMessage(Tenant tenant, Guid messageId, CancellationToken ct) { const int MaxTries = 10; using IDisposable logScope = NestedDiagnosticsLogicalContext.Push("QueueBackgroundWork"); using SnittlistanContext context = new(); try { for (int i = 0; i < MaxTries; i++) { Logger.Info("try #{try}", i); PublishedTask?publishedTask = await context.PublishedTasks.SingleOrDefaultAsync(x => x.MessageId == messageId); if (publishedTask == null) { Logger.Warn("message not found: {messageId}", messageId); await Task.Delay(300); } else { DoPublishMessage(tenant, publishedTask); return; } } throw new Exception($"max tries reached: {MaxTries}"); } catch (Exception ex) { Logger.Error(ex, "failed to publish message"); } } void DoPublishMessage(Tenant tenant, PublishedTask publishedTask) { using MsmqGateway msmqGateway = msmqFactory.Create(); using MsmqGateway.MsmqTransactionScope scope = msmqGateway.Create(); MessageEnvelope message = new( publishedTask.Task, publishedTask.TenantId, tenant.Hostname, publishedTask.CorrelationId, publishedTask.CausationId, publishedTask.MessageId); scope.Send(message); scope.Commit(); Logger.Info("published message {@message}", message); } }