protected override async Task ExecuteIntervalAsync() { var correlationId = CorrelationContext.GetCorrelationId(); // run something async in async method await Task.Run(() => logger.LogInformation($"CorrelationId: {correlationId}")).ConfigureAwait(false); }
private Message CreateMessage(string data, EventProperties properties, DateTime?scheduledEnqueueTimeUtc = null) { Guard.Against(() => properties.EventType == null, () => new ArgumentException("EventType is a required argument")); Guard.Against(() => properties.Topic == null, () => new ArgumentException("Topic is a required argument")); Guard.Against(() => properties.RoutingKey == null, () => new ArgumentException("RoutingKey is a required argument")); properties.MessageId = properties.MessageId ?? Guid.NewGuid().ToString(); // if the correlationId is not set, set one from the current context if (string.IsNullOrEmpty(properties.CorrelationId)) { properties.CorrelationId = CorrelationContext.GetCorrelationId(true); } var message = new Message(data) { Header = new Header { Durable = (Settings.Durable == 2) }, ApplicationProperties = new ApplicationProperties(), MessageAnnotations = new MessageAnnotations(), Properties = new Properties { MessageId = properties.MessageId, GroupId = properties.EventType, CorrelationId = properties.CorrelationId } }; message.ApplicationProperties[Constants.MESSAGE_TYPE_KEY] = properties.EventType; if (scheduledEnqueueTimeUtc.HasValue) { message.MessageAnnotations[new Symbol(Constants.SCHEDULED_ENQUEUE_TIME_UTC)] = scheduledEnqueueTimeUtc; } return(message); }
protected override async Task ExecuteIntervalAsync() { await Task.Yield(); var correlationId = CorrelationContext.GetCorrelationId(); using (var scope = serviceProvider.CreateScope()) { var db = scope.ServiceProvider.GetService <T>(); var isRelational = !db.Database.ProviderName.Contains("InMemory"); var strategy = db.Database.CreateExecutionStrategy(); await strategy.ExecuteAsync(async() => { await using (var tx = isRelational ? await db.Database.BeginTransactionAsync().ConfigureAwait(false) : null) { try { List <Outbox> messages; if (isRelational) { var sql = $";with cte as (select top ({config.Interval}) * from Outbox where LockId is null and Status='{OutboxStatus.Queued}' and ScheduledDate<GETUTCDATE() order by ScheduledDate) update cte WITH (XLOCK) set LockId = '{correlationId}', Status='{OutboxStatus.Publishing}'"; await db.Database.ExecuteSqlRawAsync(sql).ConfigureAwait(false); messages = await db.Set <Outbox>().Where(o => o.LockId == correlationId).ToListAsync().ConfigureAwait(false); } else { messages = await db.Set <Outbox>().ToListAsync().ConfigureAwait(false); } logger.LogInformation($"message count: {messages.Count}"); foreach (var message in messages) { var properties = new EventProperties() { EventType = message.EventType, Topic = message.Topic, RoutingKey = message.RoutingKey, CorrelationId = message.CorrelationId, MessageId = message.MessageId }; var publisher = scope.ServiceProvider.GetService <IDomainEventPublisher>(); await publisher.PublishAsync(message.Body, properties).ConfigureAwait(false); message.Status = OutboxStatus.Published; message.PublishedDate = DateTime.UtcNow; message.LockId = null; } await db.SaveChangesAsync().ConfigureAwait(false); await(tx?.CommitAsync()).ConfigureAwait(false); } catch (Exception ex) { logger.LogError(ex, "Exception attempting to publish from outbox"); await(tx?.RollbackAsync()).ConfigureAwait(false); } } }).ConfigureAwait(false); } }
private async Task IntervalAsync() { var correlationId = CorrelationContext.GetCorrelationId(generateCorrelationId); using (logger.BeginScope(new Dictionary <string, object> { ["CorrelationId"] = correlationId })) { logger.LogDebug($"{this.GetType().Name} is working"); try { await ExecuteIntervalAsync().ConfigureAwait(false); } catch (Exception ex) { logger.LogError(ex, this.GetType().Name); } } }
public async Task <HandlerResult> HandleAsync(DomainEventMessage <TestEvent> @event) { var properties = new Dictionary <string, object> { ["CorrelationId"] = @event.CorrelationId, ["MessageId"] = @event.MessageId, ["MessageType"] = @event.MessageTypeName }; var correlationId = CorrelationContext.GetCorrelationId(); if (@event.Data.IntValue == Int32.MaxValue && correlationId != @event.CorrelationId) { throw new ArgumentException($"CorrelationId {@event.CorrelationId} should equal {correlationId}"); } using (logger.BeginScope(properties)) { TestEvent.Instances.Add(@event.MessageId, @event.Data); if (@event.Data.IntValue == int.MinValue) { var x = 0; _ = 1 / x; } if (@event.Data.IntValue > 0) { return(await Task.FromResult(HandlerResult.Success).ConfigureAwait(false)); } else if (@event.Data.IntValue == 0) { return(await Task.FromResult(HandlerResult.Retry).ConfigureAwait(false)); } else { return(await Task.FromResult(HandlerResult.Failed).ConfigureAwait(false)); } } }
protected override async Task ExecuteIntervalAsync() { await Task.Yield(); var lockId = CorrelationContext.GetCorrelationId(); var sql = $@" declare @rows int select @rows = count(*) from Outbox with (nolock) where (LockId is null and Status='Queued' and ScheduledDate<GETUTCDATE()) or (status='Publishing' and LastModifiedDate<(dateadd(second, -60, GETUTCDATE()))) if (@rows > 0) BEGIN UPDATE Q SET LockId = '{lockId}', Status='Publishing', LastModifiedDate=GETUTCDATE() FROM ( select top ({config.BatchSize}) * from Outbox WITH (ROWLOCK, READPAST) where (LockId is null and Status='Queued' and ScheduledDate<GETUTCDATE()) or (status='Publishing' and LastModifiedDate<(dateadd(second, -60, GETUTCDATE()))) order by ScheduledDate ) Q END "; using (var scope = serviceProvider.CreateScope()) { var db = scope.ServiceProvider.GetService <T>(); var isRelational = !db.Database.ProviderName.Contains("InMemory"); var messageCount = 0; if (isRelational) { messageCount = await db.Database.ExecuteSqlRawAsync(sql).ConfigureAwait(false); } else { var messages = db.Set <Outbox>().Where(o => o.Status == OutboxStatus.Queued && o.ScheduledDate < DateTime.UtcNow).Take(config.BatchSize); foreach (var message in messages) { message.Status = OutboxStatus.Publishing; message.LockId = lockId; message.LastModifiedDate = DateTime.UtcNow; } await db.SaveChangesAsync().ConfigureAwait(false); messageCount = messages.Count(); } logger.LogInformation($"messages to publish: {messageCount}"); try { List <Outbox> messages = await db.Set <Outbox>().Where(x => x.LockId == lockId).ToListAsync().ConfigureAwait(false); logger.LogInformation($"messages claimed: {messages.Count}"); foreach (var message in messages) { var properties = new EventProperties() { EventType = message.EventType, Topic = message.Topic, RoutingKey = message.RoutingKey, CorrelationId = message.CorrelationId, MessageId = message.MessageId }; var publisher = scope.ServiceProvider.GetService <IDomainEventPublisher>(); await publisher.PublishAsync(message.Body, properties).ConfigureAwait(false); message.Status = OutboxStatus.Published; message.PublishedDate = DateTime.UtcNow; message.LockId = null; } await db.SaveChangesAsync().ConfigureAwait(false); } catch (Exception ex) { logger.LogError(ex, "Exception attempting to publish from outbox"); } if (config.PurgePublished) { try { if (isRelational) { var query = $"DELETE TOP ({config.BatchSize}) FROM Outbox Where Status = '{OutboxStatus.Published}'"; await db.Database.ExecuteSqlRawAsync(query).ConfigureAwait(false); } else { db.RemoveRange(db.Set <Outbox>().Where(o => o.Status == OutboxStatus.Published).Take(config.BatchSize)); await db.SaveChangesAsync().ConfigureAwait(false); } } catch (Exception ex) { logger.LogError(ex, "Exception attempting to purge published from outbox"); } } } }
protected override async Task ExecuteIntervalAsync() { var correlationId = CorrelationContext.GetCorrelationId(); logger.LogInformation($"CorrelationId: {correlationId}"); }