Beispiel #1
0
        Try <StreamProcessor> TryRegisterEventProcessorStreamProcessor(
            ScopeId scopeId,
            EventProcessorId eventHandlerId,
            IStreamDefinition streamDefinition,
            Func <IEventProcessor> getEventProcessor,
            CancellationToken cancellationToken)
        {
            _logger.Debug("Registering stream processor for Event Processor '{EventProcessor}' on Stream '{SourceStream}'", eventHandlerId, streamDefinition.StreamId);
            try
            {
                return(_streamProcessors.TryRegister(
                           scopeId,
                           eventHandlerId,
                           streamDefinition,
                           getEventProcessor,
                           cancellationToken,
                           out var outputtedEventProcessorStreamProcessor), outputtedEventProcessorStreamProcessor);
            }
            catch (Exception ex)
            {
                if (!cancellationToken.IsCancellationRequested)
                {
                    _logger.Warning(
                        ex,
                        "Error occurred while trying to register stream processor for Event Processor '{EventProcessor}'",
                        eventHandlerId);
                }

                return(ex);
            }
        }
 void NotifyStream(ScopeId scopeId, IStreamDefinition streamDefinition, StreamPosition position)
 {
     if (position == StreamPosition.Start)
     {
         return;
     }
     if (streamDefinition.Public)
     {
         _streamWatcher.NotifyForEvent(streamDefinition.StreamId, position - 1);
     }
     else
     {
         _streamWatcher.NotifyForEvent(scopeId, streamDefinition.StreamId, position - 1);
     }
 }
Beispiel #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ScopedStreamProcessor"/> class.
 /// </summary>
 /// <param name="tenantId">The <see cref="TenantId"/>.</param>
 /// <param name="streamProcessorId">The <see cref="IStreamProcessorId" />.</param>
 /// <param name="sourceStreamDefinition">The source stream <see cref="IStreamDefinition" />.</param>
 /// <param name="initialState">The <see cref="StreamProcessorState" />.</param>
 /// <param name="processor">An <see cref="IEventProcessor" /> to process the event.</param>
 /// <param name="streamProcessorStates">The <see cref="IResilientStreamProcessorStateRepository" />.</param>
 /// <param name="eventsFromStreamsFetcher">The<see cref="ICanFetchEventsFromStream" />.</param>
 /// <param name="executionContext">The <see cref="ExecutionContext"/> of the stream processor.</param>
 /// <param name="eventFetcherPolicies">The policies to use while fetching events.</param>
 /// <param name="eventWatcher">The <see cref="IStreamEventWatcher" /> to wait for events to be available in stream.</param>
 /// <param name="timeToRetryGetter">The <see cref="ICanGetTimeToRetryFor{T}" /> <see cref="StreamProcessorState" />.</param>
 /// <param name="logger">An <see cref="ILogger" /> to log messages.</param>
 public ScopedStreamProcessor(
     TenantId tenantId,
     IStreamProcessorId streamProcessorId,
     IStreamDefinition sourceStreamDefinition,
     StreamProcessorState initialState,
     IEventProcessor processor,
     IResilientStreamProcessorStateRepository streamProcessorStates,
     ICanFetchEventsFromStream eventsFromStreamsFetcher,
     ExecutionContext executionContext,
     IEventFetcherPolicies eventFetcherPolicies,
     IStreamEventWatcher eventWatcher,
     ICanGetTimeToRetryFor <StreamProcessorState> timeToRetryGetter,
     ILogger logger)
     : base(tenantId, streamProcessorId, sourceStreamDefinition, initialState, processor, eventsFromStreamsFetcher, executionContext, eventFetcherPolicies, eventWatcher, logger)
 {
     _streamProcessorStates = streamProcessorStates;
     _timeToRetryGetter     = timeToRetryGetter;
 }
    /// <inheritdoc />
    public async Task <AbstractScopedStreamProcessor> Create(
        IStreamDefinition streamDefinition,
        IStreamProcessorId streamProcessorId,
        IEventProcessor eventProcessor,
        ExecutionContext executionContext,
        CancellationToken cancellationToken)
    {
        var processorState = await GetOrCreateStreamProcessorState(
            streamProcessorId,
            streamDefinition.Partitioned
            ?Partitioned.StreamProcessorState.New
            : StreamProcessorState.New,
            cancellationToken)
                             .ConfigureAwait(false);

        AbstractScopedStreamProcessor streamProcessor;

        if (streamDefinition.Partitioned)
        {
            if (processorState is not Partitioned.StreamProcessorState partitionedProcessorState)
            {
                throw new ExpectedPartitionedStreamProcessorState(streamProcessorId);
            }

            var eventFetcher = await _eventFetchers.GetPartitionedFetcherFor(eventProcessor.Scope, streamDefinition, cancellationToken).ConfigureAwait(false);

            streamProcessor = _createPartitionedStreamProcessor(streamDefinition, streamProcessorId, eventFetcher, eventProcessor, partitionedProcessorState, executionContext);
        }
        else
        {
            if (processorState is not StreamProcessorState unpartitionedProcessorState)
            {
                throw new ExpectedUnpartitionedStreamProcessorState(streamProcessorId);
            }

            var eventFetcher = await _eventFetchers.GetFetcherFor(eventProcessor.Scope, streamDefinition, cancellationToken).ConfigureAwait(false);

            streamProcessor = _createUnpartitionedStreamProcessor(streamDefinition, streamProcessorId, eventFetcher, eventProcessor, unpartitionedProcessorState, executionContext);
        }

        NotifyStream(streamProcessorId.ScopeId, streamDefinition, processorState.Position);

        return(streamProcessor);
    }
Beispiel #5
0
        /// <inheritdoc />
        public async Task <AbstractScopedStreamProcessor> Create(
            IStreamDefinition streamDefinition,
            IStreamProcessorId streamProcessorId,
            IEventProcessor eventProcessor,
            CancellationToken cancellationToken)
        {
            if (streamDefinition.Partitioned)
            {
                var eventFetcher = await _eventFetchers.GetPartitionedFetcherFor(eventProcessor.Scope, streamDefinition, cancellationToken).ConfigureAwait(false);

                return(await CreatePartitionedScopedStreamProcessor(streamProcessorId, eventProcessor, eventFetcher, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                var eventFetcher = await _eventFetchers.GetFetcherFor(eventProcessor.Scope, streamDefinition, cancellationToken).ConfigureAwait(false);

                return(await CreateUnpartitionedScopedStreamProcessor(streamProcessorId, eventProcessor, eventFetcher, cancellationToken).ConfigureAwait(false));
            }
        }
Beispiel #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ScopedStreamProcessor"/> class.
 /// </summary>
 /// <param name="tenantId">The <see cref="TenantId"/>.</param>
 /// <param name="streamProcessorId">The <see cref="IStreamProcessorId" />.</param>
 /// <param name="sourceStreamDefinition">The source stream <see cref="StreamDefinition" />.</param>
 /// <param name="initialState">The <see cref="StreamProcessorState" />.</param>
 /// <param name="processor">An <see cref="IEventProcessor" /> to process the event.</param>
 /// <param name="streamProcessorStates">The <see cref="IResilientStreamProcessorStateRepository" />.</param>
 /// <param name="eventsFromStreamsFetcher">The<see cref="ICanFetchEventsFromStream" />.</param>
 /// <param name="executionContext">The <see cref="ExecutionContext"/> of the stream processor.</param>
 /// <param name="failingPartitionsFactory">The factory to use to create the <see cref="IFailingPartitions" />.</param>
 /// <param name="eventFetcherPolicies">The policies to use while fetching events.</param>
 /// <param name="streamWatcher">The <see cref="IStreamEventWatcher" />.</param>
 /// <param name="timeToRetryGetter">The <see cref="ICanGetTimeToRetryFor{T}" /> <see cref="StreamProcessorState" />.</param>
 /// <param name="logger">An <see cref="ILogger" /> to log messages.</param>
 public ScopedStreamProcessor(
     TenantId tenantId,
     IStreamProcessorId streamProcessorId,
     IStreamDefinition sourceStreamDefinition,
     StreamProcessorState initialState,
     IEventProcessor processor,
     IResilientStreamProcessorStateRepository streamProcessorStates,
     ICanFetchEventsFromPartitionedStream eventsFromStreamsFetcher,
     ExecutionContext executionContext,
     Func <IEventProcessor, ICanFetchEventsFromPartitionedStream, Func <StreamEvent, ExecutionContext>, IFailingPartitions> failingPartitionsFactory,
     IEventFetcherPolicies eventFetcherPolicies,
     IStreamEventWatcher streamWatcher,
     ICanGetTimeToRetryFor <StreamProcessorState> timeToRetryGetter,
     ILogger logger)
     : base(tenantId, streamProcessorId, sourceStreamDefinition, initialState, processor, eventsFromStreamsFetcher, executionContext, eventFetcherPolicies, streamWatcher, logger)
 {
     _streamProcessorStates = streamProcessorStates;
     _failingPartitions     = failingPartitionsFactory(processor, eventsFromStreamsFetcher, GetExecutionContextForEvent);
     _timeToRetryGetter     = timeToRetryGetter;
 }
Beispiel #7
0
        /// <inheritdoc/>
        public async Task <ICanFetchEventsFromStream> GetFetcherFor(ScopeId scopeId, IStreamDefinition streamDefinition, CancellationToken cancellationToken)
        {
            if (streamDefinition.StreamId == StreamId.EventLog)
            {
                return(await CreateStreamFetcherForEventLog(scopeId, cancellationToken).ConfigureAwait(false));
            }

            if (streamDefinition.Public)
            {
                return(CreateStreamFetcherForStreamEventCollection(
                           await _streams.GetPublic(streamDefinition.StreamId, cancellationToken).ConfigureAwait(false),
                           streamDefinition.StreamId,
                           streamDefinition.Partitioned));
            }

            return(CreateStreamFetcherForStreamEventCollection(
                       await _streams.Get(scopeId, streamDefinition.StreamId, cancellationToken).ConfigureAwait(false),
                       streamDefinition.StreamId,
                       streamDefinition.Partitioned));
        }
        /// <inheritdoc/>
        public async Task Persist(ScopeId scope, IStreamDefinition streamDefinition, CancellationToken cancellationToken)
        {
            try
            {
                var streamDefinitions = await _streams.GetDefinitions(scope, cancellationToken).ConfigureAwait(false);

                await streamDefinitions.ReplaceOneAsync(
                    Builders <StreamDefinition> .Filter.Eq(_ => _.StreamId, streamDefinition.StreamId.Value),
                    new StreamDefinition(
                        streamDefinition.StreamId,
                        streamDefinition.FilterDefinition.ToStoreRepresentation(),
                        streamDefinition.Partitioned,
                        streamDefinition.Public),
                    new ReplaceOptions { IsUpsert = true }).ConfigureAwait(false);
            }
            catch (MongoWaitQueueFullException ex)
            {
                throw new EventStoreUnavailable("Mongo wait queue is full", ex);
            }
        }
Beispiel #9
0
        /// <inheritdoc/>
        public async Task <Try <IStreamDefinition> > TryGet(ScopeId scope, StreamId streamId, CancellationToken cancellationToken)
        {
            IStreamDefinition result = default;

            await _onAllTenants.PerformAsync(async _ =>
            {
                var tryGetStreamDefinition = await _getStreamDefinitions().TryGet(scope, streamId, cancellationToken).ConfigureAwait(false);
                if (tryGetStreamDefinition.Success)
                {
                    var streamDefinition = tryGetStreamDefinition.Result;
                    if (result == default)
                    {
                        result = streamDefinition;
                    }
                    else if (tryGetStreamDefinition.Result != result)
                    {
                        throw new StreamDefinitionNotTheSameForAllTenants(scope, streamId);
                    }
                }
            }).ConfigureAwait(false);

            return(new Try <IStreamDefinition>(result != default, result));
        }
Beispiel #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="StreamProcessor"/> class.
 /// </summary>
 /// <param name="streamProcessorId">The <see cref="StreamProcessorId" />.</param>
 /// <param name="onAllTenants">The <see cref="IPerformActionOnAllTenants" />.</param>
 /// <param name="streamDefinition">The <see cref="IStreamDefinition" />.</param>
 /// <param name="getEventProcessor">The <see cref="Func{TResult}" /> that returns an <see cref="IEventProcessor" />.</param>
 /// <param name="unregister">An <see cref="Action" /> that unregisters the <see cref="ScopedStreamProcessor" />.</param>
 /// <param name="getScopedStreamProcessorsCreator">The <see cref="ICreateScopedStreamProcessors" />.</param>
 /// <param name="executionContextManager">The <see cref="IExecutionContextManager" />.</param>
 /// <param name="logger">The <see cref="ILogger" />.</param>
 /// <param name="cancellationToken">The <see cref="CancellationToken" />.</param>
 public StreamProcessor(
     StreamProcessorId streamProcessorId,
     IPerformActionOnAllTenants onAllTenants,
     IStreamDefinition streamDefinition,
     Func <IEventProcessor> getEventProcessor,
     Action unregister,
     FactoryFor <ICreateScopedStreamProcessors> getScopedStreamProcessorsCreator,
     IExecutionContextManager executionContextManager,
     ILogger <StreamProcessor> logger,
     CancellationToken cancellationToken)
 {
     _identifier        = streamProcessorId;
     _onAllTenants      = onAllTenants;
     _streamDefinition  = streamDefinition;
     _getEventProcessor = getEventProcessor;
     _unregister        = unregister;
     _getScopedStreamProcessorsCreator = getScopedStreamProcessorsCreator;
     _executionContextManager          = executionContextManager;
     _logger = logger;
     _internalCancellationTokenSource = new CancellationTokenSource();
     _externalCancellationToken       = cancellationToken;
     _unregisterTokenRegistration     = _externalCancellationToken.Register(_unregister);
 }
Beispiel #11
0
        /// <inheritdoc />
        public bool TryRegister(
            ScopeId scopeId,
            EventProcessorId eventProcessorId,
            IStreamDefinition streamDefinition,
            Func <IEventProcessor> getEventProcessor,
            CancellationToken cancellationToken,
            out StreamProcessor streamProcessor)
        {
            streamProcessor = default;
            var streamProcessorId = new StreamProcessorId(scopeId, eventProcessorId, streamDefinition.StreamId);

            if (_streamProcessors.ContainsKey(streamProcessorId))
            {
                _logger.Warning("Stream Processor with Id: '{streamProcessorId}' already registered", streamProcessorId);
                return(false);
            }

            streamProcessor = new StreamProcessor(
                streamProcessorId,
                _onAllTenants,
                streamDefinition,
                getEventProcessor,
                () => Unregister(streamProcessorId),
                _getScopedStreamProcessorsCreator,
                _executionContextManager,
                _loggerManager.CreateLogger <StreamProcessor>(),
                cancellationToken);
            if (!_streamProcessors.TryAdd(streamProcessorId, streamProcessor))
            {
                _logger.Warning("Stream Processor with Id: '{StreamProcessorId}' already registered", streamProcessorId);
                streamProcessor = default;
                return(false);
            }

            _logger.Trace("Stream Processor with Id: '{StreamProcessorId}' registered", streamProcessorId);
            return(true);
        }
Beispiel #12
0
 /// <inheritdoc/>
 public Task Persist(ScopeId scope, IStreamDefinition streamDefinition, CancellationToken cancellationToken) =>
 _onAllTenants.PerformAsync(_ => _getStreamDefinitions().Persist(scope, streamDefinition, cancellationToken));
Beispiel #13
0
 /// <inheritdoc/>
 public async Task <ICanFetchEventTypesFromPartitionedStream> GetPartitionedTypeFetcherFor(ScopeId scopeId, IStreamDefinition streamDefinition, CancellationToken cancellationToken)
 {
     return(await GetPartitionedFetcherFor(scopeId, streamDefinition, cancellationToken).ConfigureAwait(false) as ICanFetchEventTypesFromPartitionedStream);
 }
Beispiel #14
0
 /// <inheritdoc/>
 public async Task <ICanFetchRangeOfEventsFromStream> GetRangeFetcherFor(ScopeId scopeId, IStreamDefinition streamDefinition, CancellationToken cancellationToken)
 {
     return(await GetFetcherFor(scopeId, streamDefinition, cancellationToken).ConfigureAwait(false) as ICanFetchRangeOfEventsFromStream);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="NoEventFetcherForStream"/> class.
 /// </summary>
 /// <param name="streamDefinition">The <see cref="IStreamDefinition" />.</param>
 public NoEventFetcherForStream(IStreamDefinition streamDefinition)
     : base($"Could not find an events fetcher for Stream: {streamDefinition}")
 {
 }
Beispiel #16
0
 /// <inheritdoc/>
 public Task Persist(ScopeId scope, IStreamDefinition streamDefinition, CancellationToken cancellationToken)
 => _performer.PerformAsyncOn <IStreamDefinitionRepository>(_ => _.Persist(scope, streamDefinition, cancellationToken));
 /// <summary>
 /// Initializes a new instance of the <see cref="CannotGetPartitionedFetcherForUnpartitionedStream"/> class.
 /// </summary>
 /// <param name="streamDefinition">The <see cref="IStreamDefinition" />.</param>
 public CannotGetPartitionedFetcherForUnpartitionedStream(IStreamDefinition streamDefinition)
     : base($"Cannot get partitioned Fetcher from unpartitioned Stream Definition: '{streamDefinition}'")
 {
 }