private async Task <ISaga> ProcessSagaAsync( IDomainEvent domainEvent, ISagaId sagaId, SagaDetails details, CancellationToken cancellationToken) { try { _log.Verbose(() => $"Loading saga '{details.SagaType.PrettyPrint()}' with ID '{sagaId}'"); return(await _sagaStore.UpdateAsync <ISaga>( sagaId, details, domainEvent.Metadata.SourceId, (s, c) => UpdateSagaAsync(s, domainEvent, details, c), cancellationToken) .ConfigureAwait(false)); } catch (Exception e) { var handled = await _sagaErrorHandler.HandleAsync( sagaId, details, e, cancellationToken) .ConfigureAwait(false); if (handled) { return(null); } _log.Error(e, $"Failed to process domain event '{domainEvent.EventType}' for saga '{details.SagaType.PrettyPrint()}'"); throw; } }
public async Task <TSaga> UpdateAsync <TSaga>( ISagaId sagaId, SagaDetails sagaDetails, ISourceId sourceId, Func <TSaga, CancellationToken, Task> updateSaga, CancellationToken cancellationToken) where TSaga : ISaga { var saga = default(TSaga); var storeAggregateSagaAsync = await GetUpdateAsync( sagaDetails.SagaType, cancellationToken) .ConfigureAwait(false); var domainEvents = await storeAggregateSagaAsync( sagaId, sourceId, async (s, c) => { var specificSaga = (TSaga)s; await updateSaga(specificSaga, c).ConfigureAwait(false); saga = specificSaga; }, cancellationToken) .ConfigureAwait(false); return(domainEvents.Any() ? saga : default(TSaga)); }
public override async Task <ISaga> UpdateAsync( ISagaId sagaId, Type sagaType, ISourceId sourceId, Func <ISaga, CancellationToken, Task> updateSaga, CancellationToken cancellationToken) { var commandBus = _serviceProvider.GetRequiredService <ICommandBus>(); ISaga saga; using (await _asyncLock.WaitAsync(cancellationToken).ConfigureAwait(false)) { _hasUpdateBeenCalled = true; if (!_sagas.TryGetValue(sagaId, out var obj)) { obj = Activator.CreateInstance(sagaType, sagaId); _sagas[sagaId] = obj; } saga = (ISaga)obj; await updateSaga(saga, cancellationToken).ConfigureAwait(false); } await saga.PublishAsync(commandBus, cancellationToken).ConfigureAwait(false); return(saga); }
public async Task <TSaga> UpdateAsync <TSaga>( ISagaId sagaId, SagaDetails sagaDetails, ISourceId sourceId, Func <TSaga, CancellationToken, Task> updateSaga, CancellationToken cancellationToken) where TSaga : ISaga { using (await _asyncLock.WaitAsync(cancellationToken).ConfigureAwait(false)) { _hasUpdateBeenCalled = true; if (!_sagas.TryGetValue(sagaId, out var obj)) { obj = Activator.CreateInstance(sagaDetails.SagaType, sagaId); _sagas[sagaId] = obj; } var saga = (TSaga)obj; await updateSaga(saga, cancellationToken).ConfigureAwait(false); return(saga); } }
public Task <bool> HandleAsync( ISagaId sagaId, SagaDetails sagaDetails, Exception exception, CancellationToken cancellationToken) { // The default handler cannot handle anything! return(Task.FromResult(false)); }
public async Task <TSaga> UpdateAsync <TSaga>( ISagaId sagaId, ISourceId sourceId, Func <TSaga, CancellationToken, Task> updateSaga, CancellationToken cancellationToken) where TSaga : ISaga { return((TSaga) await UpdateAsync( sagaId, typeof(TSaga), sourceId, (s, c) => updateSaga((TSaga)s, c), cancellationToken) .ConfigureAwait(false)); }
private async Task ProcessSagaAsync( IDomainEvent domainEvent, ISagaId sagaId, SagaDetails details, CancellationToken cancellationToken) { try { _logger.LogTrace( "Loading saga {SagaType} with ID {Id}", details.SagaType.PrettyPrint(), sagaId); await _sagaStore.UpdateAsync( sagaId, details.SagaType, domainEvent.Metadata.EventId, (s, c) => UpdateSagaAsync(s, domainEvent, details, c), cancellationToken) .ConfigureAwait(false); } catch (Exception e) { var handled = await _sagaErrorHandler.HandleAsync( sagaId, details, e, cancellationToken) .ConfigureAwait(false); if (handled) { return; } _logger.LogError( "Failed to process domain event {DomainEventType} for saga {SagaType}", domainEvent.EventType, details.SagaType.PrettyPrint()); throw; } }
public override async Task <ISaga> UpdateAsync( ISagaId sagaId, Type sagaType, ISourceId sourceId, Func <ISaga, CancellationToken, Task> updateSaga, CancellationToken cancellationToken) { var saga = null as ISaga; var storeAggregateSagaAsync = await GetUpdateAsync( sagaType, cancellationToken) .ConfigureAwait(false); var domainEvents = await storeAggregateSagaAsync( this, sagaId, sourceId, async (s, c) => { await updateSaga(s, c).ConfigureAwait(false); saga = s; }, cancellationToken) .ConfigureAwait(false); if (!domainEvents.Any()) { return(null); } var commandBus = _resolver.Resolve <ICommandBus>(); await saga.PublishAsync(commandBus, cancellationToken).ConfigureAwait(false); return(saga); }
private async Task ProcessSagaAsync( IDomainEvent domainEvent, ISagaId sagaId, SagaDetails details, CancellationToken cancellationToken) { try { _log.Verbose(() => $"Loading saga '{details.SagaType.PrettyPrint()}' with ID '{sagaId}'"); await _sagaStore.UpdateAsync( sagaId, details.SagaType, domainEvent.Metadata.EventId, (s, c) => UpdateSagaAsync(s, domainEvent, details, c), cancellationToken) .ConfigureAwait(false); } catch (Exception e) { // Search for a specific SagaErrorHandler<Saga> based on saga type ISagaErrorHandler specificSagaErrorHandler = _sagaErrorHandlerFactory(details.SagaType); bool handled = specificSagaErrorHandler != null ? await specificSagaErrorHandler.HandleAsync(sagaId, details, e, cancellationToken).ConfigureAwait(false) : await _sagaErrorHandler.HandleAsync(sagaId, details, e, cancellationToken).ConfigureAwait(false); if (handled) { return; } _log.Error(e, $"Failed to process domain event '{domainEvent.EventType}' for saga '{details.SagaType.PrettyPrint()}'"); throw; } }
public override async Task <ISaga> UpdateAsync( ISagaId sagaId, Type sagaType, ISourceId sourceId, Func <ISaga, CancellationToken, Task> updateSaga, CancellationToken cancellationToken) { var saga = null as ISaga; var storeAggregateSagaAsync = await GetUpdateAsync( sagaType, cancellationToken) .ConfigureAwait(false); await storeAggregateSagaAsync( this, sagaId, sourceId, async (s, c) => { await updateSaga(s, c).ConfigureAwait(false); saga = s; }, cancellationToken) .ConfigureAwait(false); if (saga is null) { return(null); } var commandBus = _serviceProvider.GetRequiredService <ICommandBus>(); await saga.PublishAsync(commandBus, cancellationToken).ConfigureAwait(false); return(saga); }
public abstract Task <ISaga> UpdateAsync( ISagaId sagaId, Type sagaType, ISourceId sourceId, Func <ISaga, CancellationToken, Task> updateSaga, CancellationToken cancellationToken);
public Task <bool> HandleAsync(ISagaId sagaId, SagaDetails sagaDetails, Exception exception, CancellationToken cancellationToken) { return(Task.FromResult(true)); }