示例#1
0
        public bool PreInsertInstance(ConsumeContext <TMessage> context, out TSaga instance)
        {
            if (_insertOnInitial)
            {
                instance = _sagaFactory.Create(context);
                return(true);
            }

            instance = null;
            return(false);
        }
        IOrderFulfillmentSaga GetSaga(IOrder order)
        {
            if (!_sagas.Keys.Exists(k => k == order.Id))
            {
                _sagas.Add(order.Id, _sagaFactory.Create(order));
            }

            var saga = _sagas[order.Id];

            return(saga);
        }
示例#3
0
 public void Register <TMessage>(ISagaFactory <TSaga, TMessage> factory)
 {
     Register(typeof(TMessage), m => factory.Create((TMessage)m));
 }
示例#4
0
        public async Task RunAsync <TM>(IMessageContext <TM> messageContext, CancellationToken cancellationToken = default)
            where TM : IMessage
        {
            var(state, lockId) = await GetStateAsync(messageContext, cancellationToken);

            if (state.IsCompleted())
            {
                _logger.LogWarning($"Stopped processing message '{messageContext.Message.Id}', Saga '{state.Id}' was already marked as completed");
                return;
            }

            if (state.CheckWasProcessed(messageContext.Message))
            {
                _logger.LogWarning($"message '{messageContext.Message.Id}' was already processed by saga '{state.Id}'");
                return;
            }

            var saga = _sagaFactory.Create(state);

            if (null == saga)
            {
                throw new SagaException($"unable to create Saga of type '{typeof(TS).FullName}'");
            }

            if (saga is not IHandleMessage <TM> handler)
            {
                throw new ConsumerNotFoundException(typeof(TM));
            }

            var transaction = await _transactionManager.StartTransactionAsync(cancellationToken);

            try
            {
                var policy = _policyFactory.Create <TM>();
                if (policy is null)
                {
                    await handler.HandleAsync(messageContext, cancellationToken);
                }
                else
                {
                    await policy.WrapAsync(() => handler.HandleAsync(messageContext, cancellationToken));
                }

                state.SetAsProcessed(messageContext.Message);

                await _sagaStateService.SaveAsync(state, lockId, cancellationToken);

                await transaction.CommitAsync(cancellationToken);
            }
            catch (Exception ex)
            {
                await transaction.RollbackAsync(cancellationToken);

                if (saga is not ICompensateMessage <TM> compensatingHandler)
                {
                    throw;
                }

                await ExecuteCompensationAsync(compensatingHandler, messageContext, ex, state, lockId, cancellationToken);
            }
        }