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); } }
public async Task WriteAsync(ISagaState state) { var entity = await _dbContext .Set <EFCoreSagaStateData>() .FirstOrDefaultAsync(sld => sld.SagaId == state.Id.Id && sld.SagaType == state.Type.ToString()); if (entity is {})
public Saga(string id, IConfiguration configuration, ISagaState state, IEventHandlerMappingStrategy eventHandlerMappingStrategy) { Id = id; this.configuration = configuration; this.eventHandlerMappingStrategy = eventHandlerMappingStrategy; this.state = state; InitializeEventHandlers(); }
private void InitializeSaga(ISaga saga, SagaId id, ISagaState state) { if (state.Data is null) { saga.Initialize(id, state.State); } else { saga.InvokeGeneric(nameof(ISaga <object> .Initialize), id, state.State, state.Data); } }
public SagaMessageExecutionResult Run(object message, ISagaState state) { return (SagaMessageExecutionResult) realHandler.GetType().GetMethod("Run", new[] { message.GetType(), state.GetType() }).Invoke(realHandler, new[] { message, state }); }
public ISagaState Apply(object message, ISagaState state) { return (ISagaState) realHandler.GetType().GetMethod("Apply", new[] { message.GetType(), state.GetType() }).Invoke(realHandler, new[] { message, state }); }
public SagaStateProxy(ISagaState internalState, bool isCompleted, DateTime createdDate, int version, string currentState, string nextState, Type sagaDefinitionType) { SagaId = internalState.SagaId; SagaState = internalState; IsCompleted = isCompleted; CreatedDate = createdDate; Version = version; CurrentState = currentState; NextState = nextState; SagaDefinitionType = sagaDefinitionType; }
private static void Update(DbConnection db, ISagaState data, string correlationId) { var old = data.AutoTimestamp; var result=db.Update<SagaRow>() .Set(d => d.Data, data.Serialize().ToByteArray()) .Set(d => d.Version,data.AutoTimestamp) .Set(d => d.LastChangedOn, DateTime.UtcNow) .Set(d => d.IsCompleted, data.IsCompleted) .Where(d => d.SagaId == SagaRow.GetId(correlationId, data.GetType()) && d.Version == old) .Execute(); if (result!=1) throw new SagaConcurrencyException(); }
private static void Update(DbConnection db, ISagaState data, string correlationId) { var old = data.AutoTimestamp; var result = db.Update <SagaRow>() .Set(d => d.Data, data.Serialize().ToByteArray()) .Set(d => d.Version, data.AutoTimestamp) .Set(d => d.LastChangedOn, DateTime.UtcNow) .Set(d => d.IsCompleted, data.IsCompleted) .Where(d => d.SagaId == SagaRow.GetId(correlationId, data.GetType()) && d.Version == old) .Execute(); if (result != 1) { throw new SagaConcurrencyException(); } }
public void Save(ISagaState data, string correlationId, bool isNew) { try { _db.HandleTransientErrors(db => { if (isNew) Insert(db, data, correlationId); else Update(db, data, correlationId); }); } catch (DbException ex) { throw new BusStorageException("", ex); } }
private static void Insert(DbConnection db, ISagaState data, string correlationId) { try { db.Insert(new SagaRow() { SagaId = SagaRow.GetId(correlationId, data.GetType()), Data = data.Serialize().ToByteArray(), IsCompleted = false, LastChangedOn = DateTime.UtcNow, Version = data.AutoTimestamp }); } catch (DbException ex) { if (db.IsUniqueViolation(ex)) throw new SagaExistsException(); } }
private static void Insert(DbConnection db, ISagaState data, string correlationId) { try { db.Insert(new SagaRow() { SagaId = SagaRow.GetId(correlationId, data.GetType()), Data = data.Serialize().ToByteArray(), IsCompleted = false, LastChangedOn = DateTime.UtcNow, Version = data.AutoTimestamp }); } catch (DbException ex) { if (db.IsUniqueViolation(ex)) { throw new SagaExistsException(); } } }
protected ISagaState GetSagaState(IEvent evnt, IResolveDependencies resolver, string correlationId) { evnt.MustNotBeNull(); this.LogDebug($"Loading saga {SagaStateType.Name} ..."); ISagaState res = null; if (UseCustomRepositories) { res = GetSagaStateFromCustom(evnt, resolver); if (res != null) { return(res); } } var grepo = GetSagaRepository(resolver); return(grepo.GetSaga(correlationId, SagaStateType)); }
public void Save(ISagaState data, string correlationId, bool isNew) { try { _db.RetryOnTransientError(db => { if (isNew) { Insert(db.Connection, data, correlationId); } else { Update(db.Connection, data, correlationId); } }); } catch (DbException ex) { throw new BusStorageException("", ex); } }
public async Task ProcessAsync <TMessage>(ISaga saga, TMessage message, ISagaState state, ISagaContext context) where TMessage : class { var action = (ISagaAction <TMessage>)saga; try { await action.HandleAsync(message, context); } catch (Exception e) { context.SagaContextError = new SagaContextError(e); if (!(saga.State is SagaStates.Rejected)) { saga.Reject(); } } finally { await UpdateSagaAsync(message, saga, state); } }
public async Task WriteAsync(ISagaState state) { await SagaUnitOfWork .SagaStateDBRepository .WriteAsync(new EFCoreSagaStateData(state.Id.Id, state.Type.ToString(), state.State, JsonConvert.SerializeObject(state.Data))); }
protected void Onobject(object message) { if (handeledMessages.Any(x => x.Message.Equals(message))) return; var handler = configuration.FindMessageHandler(state, message); if (handler != null) state = handler.Apply(message, state); handeledMessages.Add(new MessageAndState(message, state.Clone())); }
public Saga(string id, IConfiguration configuration, ISagaState state) : this(id, configuration, state, new ConventionalEventHandlerMappingStrategy()) { }
public void Save(ISagaState data, string correlationId, bool isNew) { }
public SagaTransitionException(object message, ISagaState progress, Exception inner) : base("Saga transition raised an error", inner) { SagaData = progress; TransitionMessage = message; }
public Task WriteAsync(ISagaState state) { throw new NotImplementedException(); }
public MessageAndState(object message, ISagaState state) { State = state; Message = message; }