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); } }
/// <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); }
/// <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)); } }
/// <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; }
/// <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); } }
/// <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)); }
/// <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); }
/// <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); }
/// <inheritdoc/> public Task Persist(ScopeId scope, IStreamDefinition streamDefinition, CancellationToken cancellationToken) => _onAllTenants.PerformAsync(_ => _getStreamDefinitions().Persist(scope, streamDefinition, cancellationToken));
/// <inheritdoc/> public async Task <ICanFetchEventTypesFromPartitionedStream> GetPartitionedTypeFetcherFor(ScopeId scopeId, IStreamDefinition streamDefinition, CancellationToken cancellationToken) { return(await GetPartitionedFetcherFor(scopeId, streamDefinition, cancellationToken).ConfigureAwait(false) as ICanFetchEventTypesFromPartitionedStream); }
/// <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}") { }
/// <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}'") { }