Beispiel #1
0
        private async Task UpdateSagaAsync <TMessage>(TMessage message, ISaga saga, ISagaState state)
            where TMessage : class
        {
            var sagaType = saga.GetType();

            var updatedSagaData = sagaType.GetProperty(nameof(ISaga <object> .Data))?.GetValue(saga);

            state.Update(saga.State, updatedSagaData);
            var logData = SagaLogData.Create(saga.Id, sagaType, message);

            if (_configuration.AllowConcurrentWrites)
            {
                var persistenceTasks = new[]
                {
                    _repository.WriteAsync(state),
                    _log.WriteAsync(logData)
                };

                await Task.WhenAll(persistenceTasks).ConfigureAwait(false);
            }
            else
            {
                await _repository.WriteAsync(state);

                await _log.WriteAsync(logData);
            }
        }
Beispiel #2
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);
            }
        }