コード例 #1
0
        /// <inheritdoc />
        public EventHubContentLocationEventStore(
            EventHubContentLocationEventStoreConfiguration configuration,
            IContentLocationEventHandler eventHandler,
            string localMachineName,
            CentralStorage centralStorage,
            Interfaces.FileSystem.AbsolutePath workingDirectory)
            : base(configuration, nameof(EventHubContentLocationEventStore), eventHandler, centralStorage, workingDirectory)
        {
            Contract.Requires(configuration.MaxEventProcessingConcurrency >= 1);
            _configuration    = configuration;
            _localMachineName = localMachineName;

            if (configuration.MaxEventProcessingConcurrency > 1)
            {
                _eventProcessingBlocks =
                    Enumerable.Range(1, configuration.MaxEventProcessingConcurrency)
                    .Select(
                        _ =>
                {
                    var serializer = new ContentLocationEventDataSerializer(configuration.SelfCheckSerialization ? ValidationMode.Trace : ValidationMode.Off);
                    return(new ActionBlock <ProcessEventsInput>(
                               t => ProcessEventsCoreAsync(t, serializer),
                               new ExecutionDataflowBlockOptions()
                    {
                        MaxDegreeOfParallelism = 1,
                        BoundedCapacity = configuration.EventProcessingMaxQueueSize,
                    }));
                })
                    .ToArray();
            }
        }
コード例 #2
0
        private async Task ProcessEventsCoreAsync(ProcessEventsInput input, ContentLocationEventDataSerializer eventDataSerializer)
        {
            var context  = input.Context;
            var counters = input.EventStoreCounters;

            await context.PerformOperationAsync(
                Tracer,
                async() =>
            {
                int filteredEvents = 0;
                foreach (var message in input.Messages)
                {
                    // Extracting information from the message
                    var foundEventFilter = message.Properties.TryGetValue(EventFilterKey, out var eventFilter);

                    message.Properties.TryGetValue(OperationIdKey, out var operationId);

                    var sender = TryGetMessageSender(message) ?? "Unknown sender";

                    var eventTimeUtc         = message.SystemProperties.EnqueuedTimeUtc;
                    var eventProcessingDelay = DateTime.UtcNow - eventTimeUtc;

                    // Creating nested context with operationId as a guid. This helps to correlate operations on a worker and a master machines.
                    context = CreateNestedContext(context, operationId?.ToString());

                    Tracer.Debug(context, $"{Tracer.Name}.ReceivedEvent: ProcessingDelay={eventProcessingDelay}, Sender={sender}, OpId={operationId}, SeqNo={message.SystemProperties.SequenceNumber}, EQT={eventTimeUtc}, Filter={eventFilter}, Size={message.Body.Count}.");

                    Tracer.TrackMetric(context, EventProcessingDelayInSecondsMetricName, (long)eventProcessingDelay.TotalSeconds);

                    counters[ReceivedMessagesTotalSize].Add(message.Body.Count);
                    counters[ReceivedEventBatchCount].Increment();

                    if (!foundEventFilter || !string.Equals(eventFilter as string, _configuration.Epoch))
                    {
                        counters[FilteredEvents].Increment();
                        filteredEvents++;
                        continue;
                    }

                    // Deserializing a message
                    IReadOnlyList <ContentLocationEventData> eventDatas;

                    using (counters[Deserialization].Start())
                    {
                        eventDatas = eventDataSerializer.DeserializeEvents(message);
                    }

                    counters[ReceivedEventsCount].Add(eventDatas.Count);

                    // Dispatching deserialized events data
                    using (counters[DispatchEvents].Start())
                    {
                        foreach (var eventData in eventDatas)
                        {
                            // An event processor may fail to process the event, but we will save the sequence point anyway.
                            await DispatchAsync(context, eventData, counters);
                        }
                    }

                    _lastProcessedSequencePoint = new EventSequencePoint(message.SystemProperties.SequenceNumber);
                }

                Counters.Append(counters);

                return(BoolResult.Success);
            },