private async Task AddPendingEvent(PendingEventEntity evt) { // Get or create the queue for this event's subscription // MaxDegreeOfParallelism = 1 so messages always get sent in order var sendQueue = _sendQueueDict.GetOrAdd(evt.SubscriptionId, new ActionBlock <PendingEventEntity>(async evt => await SendEvent(evt.Id), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1 })); await sendQueue.SendAsync(evt); }
private async Task ProcessEvent(WebhookEvent evt) { try { using var scope = _scopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService <PlayerContext>(); // The subscriptions to the current event var subscriptions = await context.Webhooks .Include(w => w.EventTypes) .Where(w => w.EventTypes.Any(et => et.EventType == evt.Type)) .ToListAsync(); var pendingEvents = new List <PendingEventEntity>(); foreach (var subscription in subscriptions) { var pendingEvent = new PendingEventEntity { EventType = evt.Type, SubscriptionId = subscription.Id, Timestamp = evt.Timestamp, Payload = JsonSerializer.Serialize(evt) }; pendingEvents.Add(pendingEvent); } await context.PendingEvents.AddRangeAsync(pendingEvents); await context.SaveChangesAsync(); pendingEvents.ForEach(async x => await AddPendingEvent(x)); } catch (Exception ex) { _logger.LogError(ex, $"Exception processing Event with id = {evt?.Id}"); } }