Exemple #1
0
        // Not thread safe.
        public async Task ManageAsync(CancellationToken cancellationToken)
        {
            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    ResolutionStreamEvent resolutionStreamEvent;
                    while (!cancellationToken.IsCancellationRequested && _resolutionQueue.TryDequeue(out resolutionStreamEvent))
                    {
                        var            streamEvent   = resolutionStreamEvent.StreamEvent;
                        IBusinessEvent businessEvent = null;

                        try
                        {
                            // If unable to resolve event type then subscriber event will still be created but it
                            // will be unresolved.
                            if (_resolver.CanResolve(streamEvent.EventType))
                            {
                                businessEvent = _resolver.Resolve(streamEvent.EventType, streamEvent.Data);
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, "Exception while resolving business event. Subscription event will be created with null business event.");
                        }


                        // Stream events may (and will for subscription streams) have links to original events.
                        // We want the original event as the core event and the subscription event info as secondary.
                        // However, if the event is not a link then we take the event info as both subscription info and original event.
                        var streamId             = streamEvent.StreamId;
                        var position             = streamEvent.Position;
                        var subscriptionStreamId = streamEvent.StreamId;
                        var subscriptionPosition = streamEvent.Position;
                        if (streamEvent.IsLink)
                        {
                            streamId = streamEvent.Link.StreamId;
                            position = streamEvent.Link.Position;
                        }
                        var subscriberEvent = new SubscriberEvent(resolutionStreamEvent.RegionId, streamId, position, subscriptionStreamId, subscriptionPosition, streamEvent.EventType, businessEvent);

                        // Send to the sorting manager.
                        await _sortingManager.ReceiveSubscriberEventAsync(subscriberEvent, cancellationToken);
                    }
                    await Task.WhenAny(new Task[] { _resolutionQueue.AwaitEnqueueSignalAsync(), cancellationToken.WaitHandle.AsTask() });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Exception while managing resolution.");
                throw;
            }
        }
        public async Task TryRunHandlerAsync(SubscriberEvent subscriberEvent, CancellationToken cancellationToken)
        {
            try
            {
                try
                {
                    await _handler.HandleSubscriberEventAsync(subscriberEvent, cancellationToken);

                    await _streamStateRepo.SaveStreamStateAsync(subscriberEvent.StreamId, subscriberEvent.Position, false);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Exception while handling event. Stream will be halted until stream state errors are cleared.");

                    // Save errored stream state.
                    await _streamStateRepo.SaveStreamStateAsync(subscriberEvent.StreamId, subscriberEvent.Position, true);
                }
            }
            finally
            {
                _awaiter.ReleaseThrottle();                 // Make room for other handlers.
                _awaiter.SetHandlerCompletionSignal();
            }
        }
 public async Task ReceiveSubscriberEventAsync(SubscriberEvent subscriberEvent, CancellationToken cancellationToken)
 {
     // Enque when space opens up.
     await _sortingQueue.EnqueueWithWaitAsync(subscriberEvent, cancellationToken);
 }
 public async Task ReceiveSubscriberEventAsync(string parallelKey, SubscriberEvent subscriberEvent, CancellationToken cancellationToken)
 {
     // Enqueue when space available.
     await _handlingQueue.EnqueueWithWaitAsync(parallelKey, subscriberEvent, cancellationToken);
 }