async Task Consume(EventualConsistentEvent eventToConsume) { using (var scope = _rootScope.BeginScope()) { try { eventToConsume.CountHandleAttempt(); await Consume(scope, eventToConsume); } catch (EventHandlerRunnerContextNotFoundException exception) { eventToConsume.Error(exception.ToString()); await UpdateEvent(scope, eventToConsume); throw; } catch (Exception exception) { if (eventToConsume.HandleAttempts < _handleAttemptsLimit) { Process(eventToConsume); } else { eventToConsume.Fail(exception.ToString()); await UpdateEvent(scope, eventToConsume); } throw; } } }
static async Task UpdateEvent(IDependencyScope scope, EventualConsistentEvent eventualConsistent) { var repo = scope.Resolve <IEventRepository>(); await repo.Update(eventualConsistent); await Commit(scope); }
async Task Consume(IDependencyScope scope, EventualConsistentEvent eventualConsistent) { var unitOfWork = scope.Resolve <IUnitOfWork>(); var repository = scope.Resolve <IEventRepository>(); var eventType = eventualConsistent.Event.GetType(); var context = _eventHandlerRunnerCache .Get(eventType) // TODO: change .Get parameter to event's full type name? try to reduce GetType() and reflection calls during events handling .FirstOrDefault(x => x.EventHandlerName == eventualConsistent.EventHandlerName); if (context == null) { throw new EventHandlerRunnerContextNotFoundException(eventType.FullName, eventualConsistent.EventHandlerName); } await context.Runner(scope, eventualConsistent.Event); await repository.Remove(eventualConsistent.Event); await unitOfWork.Commit(); }
async Task DispatchEvent(IEvent @event) { var contexts = _cache.Get(@event.GetType()); foreach (var context in contexts) { if (context.EventualConsistent) { var eventualConsistent = new EventualConsistentEvent(@event, context.EventHandlerName); await _repository.Add(eventualConsistent); _eventualConsistentEvents.Enqueue(eventualConsistent); } else { await RunEventHandler(@event, context); } } }
IEnumerable <EventualConsistentEvent> Feed() { while (!_eventsToConsume.IsCompleted) { EventualConsistentEvent eventToConsume = null; try { // BlockingCollection blocks if _eventsToConsume.Count == 0. eventToConsume = _eventsToConsume.Take(); } catch (InvalidOperationException) { // IOE means that Take() was called on a completed collection. // Some other thread can call CompleteAdding after we pass the // IsCompleted check but before we call Take. yield break; } yield return(eventToConsume); } }
public void Process(EventualConsistentEvent eventualConsistent) { _eventsToConsume.Add(eventualConsistent); }