async Task SendToInstance <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, SagaInstance <TSaga> saga, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { await saga.MarkInUse(context.CancellationToken).ConfigureAwait(false); try { if (saga.IsRemoved) { return; } SagaConsumeContext <TSaga, T> sagaConsumeContext = new InMemorySagaConsumeContext <TSaga, T>(context, saga.Instance, () => Remove(saga, context.CancellationToken)); sagaConsumeContext.LogUsed(); await policy.Existing(sagaConsumeContext, next).ConfigureAwait(false); } finally { saga.Release(); } }
public async Task SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { try { List <TSaga> sagaInstances = await _collection.Find(context.Query.FilterExpression).ToListAsync().ConfigureAwait(false); if (!sagaInstances.Any()) { var missingPipe = new MissingPipe <TSaga, T>(_collection, next, _mongoDbSagaConsumeContextFactory); await policy.Missing(context, missingPipe).ConfigureAwait(false); } else { foreach (var instance in sagaInstances) { await SendToInstance(context, policy, next, instance).ConfigureAwait(false); } } } catch (SagaException sex) { context.LogFault(sex); throw; } catch (Exception ex) { context.LogFault(ex); throw new SagaException(ex.Message, typeof(TSaga), typeof(T), Guid.Empty, ex); } }
async Task SendToInstance <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, SagaInstance <TSaga> saga, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { await saga.MarkInUse(context.CancellationToken).ConfigureAwait(false); try { if (saga.IsRemoved) { return; } if (_log.IsDebugEnabled) { _log.DebugFormat("SAGA:{0}:{1} Used {2}", TypeMetadataCache <TSaga> .ShortName, saga.Instance.CorrelationId, TypeMetadataCache <T> .ShortName); } SagaConsumeContext <TSaga, T> sagaConsumeContext = new InMemorySagaConsumeContext <TSaga, T>(context, saga.Instance, () => Remove(saga, context.CancellationToken)); await policy.Existing(sagaConsumeContext, next).ConfigureAwait(false); } finally { saga.Release(); } }
public ISagaQueryScopeContext <TSaga, T> GetQueryScope <T>(SagaQueryConsumeContext <TSaga, T> context) where T : class { if (context.TryGetPayload <IKernel>(out _)) { return(new ExistingSagaQueryScopeContext <TSaga, T>(context)); } var scope = _container.BeginScope(); _container.Register(Component.For <ConsumeContext, ConsumeContext <T> >().Instance(context)); try { var proxy = new SagaQueryConsumeContextProxy <TSaga, T>(context, new PayloadCacheScope(context), context.Query); var consumerContainer = _container; proxy.GetOrAddPayload(() => consumerContainer); foreach (Action <ConsumeContext> scopeAction in _scopeActions) { scopeAction(proxy); } return(new CreatedSagaQueryScopeContext <IDisposable, TSaga, T>(scope, proxy)); } catch { scope.Dispose(); throw; } }
public static void LogFault <TSaga, TMessage>(this SagaQueryConsumeContext <TSaga, TMessage> context, Exception exception, Guid?correlationId = default) where TSaga : class, ISaga where TMessage : class { LogContext.Error?.Log(exception, "SAGA:{SagaType}:{CorrelationId} Fault {MessageType}", TypeMetadataCache <TSaga> .ShortName, correlationId, TypeMetadataCache <TMessage> .ShortName); }
async Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { using (_container.RequireScope()) { await _repository.SendQuery(context, policy, next).ConfigureAwait(false); } }
private static async Task SendToInstance <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, TSaga instance, IPipe <SagaConsumeContext <TSaga, T> > next, IAsyncDocumentSession session) where T : class { try { if (_log.IsDebugEnabled) { _log.DebugFormat("SAGA:{0}:{1} Used {2}", TypeMetadataCache <TSaga> .ShortName, instance.CorrelationId, TypeMetadataCache <T> .ShortName); } var sagaConsumeContext = new RavenDbSagaConsumeContext <TSaga, T>(session, context, instance); await policy.Existing(sagaConsumeContext, next).ConfigureAwait(false); } catch (SagaException) { throw; } catch (Exception ex) { throw new SagaException(ex.Message, typeof(TSaga), typeof(T), instance.CorrelationId, ex); } }
public ISagaQueryScopeContext <TSaga, T> GetQueryScope <T>(SagaQueryConsumeContext <TSaga, T> context) where T : class { if (context.TryGetPayload <IKernel>(out var kernel)) { kernel.UpdateScope(context); return(new ExistingSagaQueryScopeContext <TSaga, T>(context)); } var scope = _kernel.CreateNewOrUseExistingMessageScope(); try { _kernel.UpdateScope(context); var proxy = new SagaQueryConsumeContextProxy <TSaga, T>(context, new PayloadCacheScope(context), context.Query); proxy.UpdatePayload(_kernel); foreach (Action <ConsumeContext> scopeAction in _scopeActions) { scopeAction(proxy); } return(new CreatedSagaQueryScopeContext <IDisposable, TSaga, T>(scope, proxy)); } catch { scope.Dispose(); throw; } }
public ISagaQueryScopeContext <TSaga, T> GetQueryScope <T>(SagaQueryConsumeContext <TSaga, T> context) where T : class { if (context.TryGetPayload <IUnityContainer>(out var existingScope)) { return(new ExistingSagaQueryScopeContext <TSaga, T>(context)); } var scope = _container.CreateChildContainer(); try { var proxy = new SagaQueryConsumeContextProxy <TSaga, T>(context, new PayloadCacheScope(context), context.Query); var sagaScope = scope; proxy.GetOrAddPayload(() => sagaScope); return(new CreatedSagaQueryScopeContext <IUnityContainer, TSaga, T>(sagaScope, proxy)); } catch { scope.Dispose(); throw; } }
public ISagaQueryScopeContext <TSaga, T> GetQueryScope <T>(SagaQueryConsumeContext <TSaga, T> context) where T : class { if (context.TryGetPayload <INestedContainer>(out var existingNestedContainer)) { existingNestedContainer.Inject <ConsumeContext>(context); return(new ExistingSagaQueryScopeContext <TSaga, T>(context)); } var nestedContainer = _container.GetNestedContainer(context); try { var proxy = new SagaQueryConsumeContextScope <TSaga, T>(context, context.Query, nestedContainer); foreach (Action <ConsumeContext> scopeAction in _scopeActions) { scopeAction(proxy); } return(new CreatedSagaQueryScopeContext <INestedContainer, TSaga, T>(nestedContainer, proxy)); } catch { nestedContainer.Dispose(); throw; } }
public Task SendQuery <T>( SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next ) where T : class { throw new NotImplementedByDesignException("Redis saga repository does not support queries"); }
public async Task SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { using (var session = _sessionFactory.OpenSession()) using (var transaction = session.BeginTransaction()) { try { IList <TSaga> instances = await session.QueryOver <TSaga>() .Where(context.Query.FilterExpression) .ListAsync <TSaga>() .ConfigureAwait(false); if (instances.Count == 0) { var missingSagaPipe = new MissingPipe <T>(session, next); await policy.Missing(context, missingSagaPipe).ConfigureAwait(false); } else { await Task.WhenAll(instances.Select(instance => SendToInstance(context, policy, instance, next, session))).ConfigureAwait(false); } // TODO partial failure should not affect them all if (transaction.IsActive) { await transaction.CommitAsync().ConfigureAwait(false); } } catch (SagaException sex) { if (_log.IsErrorEnabled) { _log.Error($"SAGA:{TypeMetadataCache<TSaga>.ShortName} Exception {TypeMetadataCache<T>.ShortName}", sex); } if (transaction.IsActive) { await transaction.RollbackAsync().ConfigureAwait(false); } throw; } catch (Exception ex) { if (_log.IsErrorEnabled) { _log.Error($"SAGA:{TypeMetadataCache<TSaga>.ShortName} Exception {TypeMetadataCache<T>.ShortName}", ex); } if (transaction.IsActive) { await transaction.RollbackAsync().ConfigureAwait(false); } throw new SagaException(ex.Message, typeof(TSaga), typeof(T), Guid.Empty, ex); } } }
public ISagaQueryScopeContext <TSaga, T> GetQueryScope <T>(SagaQueryConsumeContext <TSaga, T> context) where T : class { if (context.TryGetPayload <Scope>(out var existingScope)) { existingScope.UpdateScope(context); return(new ExistingSagaQueryScopeContext <TSaga, T>(context)); } var scope = AsyncScopedLifestyle.BeginScope(_container); try { scope.UpdateScope(context); var proxy = new SagaQueryConsumeContextProxy <TSaga, T>(context, new PayloadCacheScope(context), context.Query); proxy.UpdatePayload(scope); foreach (Action <ConsumeContext> scopeAction in _scopeActions) { scopeAction(proxy); } return(new CreatedSagaQueryScopeContext <Scope, TSaga, T>(scope, proxy)); } catch { scope.Dispose(); throw; } }
public ISagaQueryScopeContext <TSaga, T> GetQueryScope <T>(SagaQueryConsumeContext <TSaga, T> context) where T : class { if (context.TryGetPayload <IContainer>(out var existingContainer)) { return(new ExistingSagaQueryScopeContext <TSaga, T>(context)); } var container = _container?.CreateNestedContainer(context) ?? _context?.CreateNestedContainer(context); try { var proxy = new SagaQueryConsumeContextProxy <TSaga, T>(context, new PayloadCacheScope(context), context.Query); var consumerContainer = container; proxy.GetOrAddPayload(() => consumerContainer); foreach (Action <ConsumeContext> scopeAction in _scopeActions) { scopeAction(proxy); } return(new CreatedSagaQueryScopeContext <IContainer, TSaga, T>(consumerContainer, proxy)); } catch { container.Dispose(); throw; } }
public ISagaQueryScopeContext <TSaga, T> GetQueryScope <T>(SagaQueryConsumeContext <TSaga, T> context) where T : class { if (context.TryGetPayload <IServiceScope>(out var existingServiceScope)) { return(new ExistingSagaQueryScopeContext <TSaga, T>(context)); } var scopeFactory = _serviceProvider.GetRequiredService <IServiceScopeFactory>(); var scope = scopeFactory.CreateScope(); try { var proxy = new SagaQueryConsumeContextProxy <TSaga, T>(context, new PayloadCacheScope(context), context.Query); var sagaScope = scope; proxy.GetOrAddPayload(() => sagaScope); foreach (Action <ConsumeContext> scopeAction in _scopeActions) { scopeAction(proxy); } return(new CreatedSagaQueryScopeContext <IServiceScope, TSaga, T>(sagaScope, proxy)); } catch { scope.Dispose(); throw; } }
public async Task SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { using (_container.GetNestedContainer()) { await _repository.SendQuery(context, policy, next); } }
public async Task SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { using (_container.CreateChildContainer()) { await _repository.SendQuery(context, policy, next).ConfigureAwait(false); } }
async Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { using (var nestedContainer = _container.GetNestedContainer()) { SagaQueryConsumeContext <TSaga, T> proxy = context.CreateQueryScope(nestedContainer); await _repository.SendQuery(proxy, policy, next).ConfigureAwait(false); } }
async Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { using (_scope.BeginLifetimeScope(_name)) { await _repository.SendQuery(context, policy, next); } }
public static SagaQueryConsumeContext <TSaga, T> CreateQueryScope <T, TSaga>(this SagaQueryConsumeContext <TSaga, T> context) where T : class where TSaga : class, ISaga { var proxy = new SagaQueryConsumeContextProxy <TSaga, T>(context, new PayloadCacheScope(context), context.Query); return(proxy); }
async Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { using (ISagaQueryScopeContext <TSaga, T> scope = _scopeProvider.GetQueryScope(context)) { await _repository.SendQuery(scope.Context, policy, next).ConfigureAwait(false); } }
Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { var interceptPipe = new InterceptPipe <T>(_sagas, _received, next); var interceptPolicy = new InterceptPolicy <T>(_created, policy); return(_sagaRepository.SendQuery(context, interceptPolicy, interceptPipe)); }
public async Task SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { using (var scope = this._services.CreateScope()) { SagaQueryConsumeContext <TSaga, T> proxy = context.CreateQueryScope(scope); await this._repository.SendQuery(proxy, policy, next).ConfigureAwait(false); } }
async Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { var outerScope = _registry.GetLifetimeScope(GetScopeId(context)); using (outerScope.BeginLifetimeScope(_name)) { await _repository.SendQuery(context, policy, next).ConfigureAwait(false); } }
public async Task SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { using (var scope = _container.BeginExecutionContextScope()) { SagaQueryConsumeContext <TSaga, T> proxy = context.CreateQueryScope(scope); await _repository.SendQuery(proxy, policy, next).ConfigureAwait(false); } }
async Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { using (var lifetimeScope = _scope.BeginLifetimeScope(_name)) { SagaQueryConsumeContext <TSaga, T> proxy = context.CreateQueryScope(lifetimeScope); await _repository.SendQuery(proxy, policy, next).ConfigureAwait(false); } }
async Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { using (var nestedContainer = _container.GetNestedContainer()) { SagaQueryConsumeContext <TSaga, T> proxy = context.CreateQueryScope(nestedContainer); proxy.GetOrAddPayload <IStateMachineActivityFactory>(() => new StructureMapStateMachineActivityFactory()); await _repository.SendQuery(proxy, policy, next).ConfigureAwait(false); } }
async Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { using (var lifetimeScope = _scope.BeginLifetimeScope(_name)) { SagaQueryConsumeContext <TSaga, T> proxy = context.CreateQueryScope(lifetimeScope); proxy.GetOrAddPayload <IStateMachineActivityFactory>(() => new AutofacStateMachineActivityFactory()); await _repository.SendQuery(proxy, policy, next).ConfigureAwait(false); } }
Task ISagaRepository <TSaga> .SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) { SagaInstance <TSaga>[] existingSagas = _sagas.Where(context.Query).ToArray(); if (existingSagas.Length == 0) { var missingSagaPipe = new MissingPipe <T>(this, next); return(policy.Missing(context, missingSagaPipe)); } return(Task.WhenAll(existingSagas.Select(instance => SendToInstance(context, policy, instance, next)))); }
public async Task SendQuery <T>(SagaQueryConsumeContext <TSaga, T> context, ISagaPolicy <TSaga, T> policy, IPipe <SagaConsumeContext <TSaga, T> > next) where T : class { using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) using (var connection = new SqlConnection(_connectionString)) { try { var tableName = GetTableName <T>(); var(whereStatement, parameters) = WhereStatementHelper.GetWhereStatementAndParametersFromExpression(context.Query.FilterExpression); List <TSaga> instances = (await connection.QueryAsync <TSaga>($"SELECT * FROM {tableName} WITH (UPDLOCK, ROWLOCK) {whereStatement}", parameters).ConfigureAwait(false)).ToList(); if (!instances.Any()) { var missingSagaPipe = new MissingPipe <T>(connection, tableName, next, InsertSagaInstance); await policy.Missing(context, missingSagaPipe); } else { foreach (var instance in instances) { await SendToInstance(context, connection, policy, instance, tableName, next).ConfigureAwait(false); } } transaction.Complete(); } catch (SagaException sex) { if (Log.IsErrorEnabled) { Log.Error($"SAGA:{TypeMetadataCache<TSaga>.ShortName} Exception {TypeMetadataCache<T>.ShortName}", sex); } throw; } catch (Exception ex) { if (Log.IsErrorEnabled) { Log.Error($"SAGA:{TypeMetadataCache<TSaga>.ShortName} Exception {TypeMetadataCache<T>.ShortName}", ex); } throw new SagaException(ex.Message, typeof(TSaga), typeof(T), Guid.Empty, ex); } } }