Пример #1
0
        private async Task ProcessAsync <TMessage>(Guid?nid, Type sagaType, Type sagaDataType, TMessage message, ISagaAction <TMessage> action, ISagaContext context = null) where TMessage : class
        {
            context = context ?? SagaContext.Empty;

            var saga     = (ISaga)action;
            var id       = nid ?? saga.ResolveId(message, context);
            var sagaData = await _repository.ReadAsync(id, sagaType).ConfigureAwait(false);

            if (sagaData is null)
            {
                if (!(action is ISagaStartAction <TMessage>))
                {
                    return;
                }
                sagaData = SagaData.Create(id, sagaType, SagaStates.Pending, Activator.CreateInstance(sagaDataType));
            }
            else if (sagaData.State == SagaStates.Rejected)
            {
                return;
            }

            saga.Initialize(sagaData.SagaId, sagaData.State, sagaData.Data);

            var isError = false;

            try
            {
                await action.HandleAsync(message, context);
            }
            catch
            {
                isError = true;
            }

            var newSagaData = SagaData.Create(id, sagaType, saga.State, saga.Data);
            var sagaLogData = SagaLogData.Create(id, sagaType, message);

            var persistanceTasks = new Task[2]
            {
                _repository.WriteAsync(newSagaData),
                _sagaLog.SaveAsync(sagaLogData)
            };

            await Task.WhenAll(persistanceTasks).ConfigureAwait(false);

            if (saga.State is SagaStates.Rejected || isError)
            {
                await CompensateAsync(saga, sagaType, context);
            }
        }