public async Task <ISaga> Publish(ISagaEvent @event, IDictionary <string, object> executionValues) { Type eventType = @event.GetType(); SagaID sagaId = SagaID.From(@event.ID); ISagaModel model = sagaRegistrator. FindModelForEventType(eventType); if (model == null) { throw new SagaEventNotRegisteredException(eventType); } ISaga newSaga = await CreateNewSagaIfRequired(model, sagaId, eventType); try { return(await ExecuteSaga( @event, model, newSaga, SagaID.From(newSaga?.Data?.ID ?? sagaId.Value), executionValues, false)); } catch { //if (newSaga != null) // await sagaPersistance.Remove(newSaga.Data.ID); throw; } }
private async Task <ISaga> CreateNewSaga(ISagaModel model, SagaID id) { if (id == SagaID.Empty()) { id = SagaID.New(); } ISagaData data = (ISagaData)Activator.CreateInstance(model.SagaStateType); data.ID = id; ISaga saga = new Saga { Data = data, ExecutionInfo = new SagaExecutionInfo { ModelName = model.Name, Created = dateTimeProvider.Now, Modified = dateTimeProvider.Now }, ExecutionState = new SagaExecutionState { CurrentState = new SagaStartState().GetStateName(), CurrentStep = null } }; return(saga); }
public AsyncStepCompletedMessage(SagaID sagaID, string currentState, string currentStep, bool isCompensating, ISagaModel model) { SagaID = sagaID; CurrentState = currentState; CurrentStep = currentStep; IsCompensating = isCompensating; Model = model; }
private async Task <ISaga> CreateNewSagaIfRequired(ISagaModel model, SagaID id, Type eventType) { ISaga saga = null; if (eventType != null) { bool isStartEvent = model.Actions.IsStartEvent(eventType); if (isStartEvent) { saga = await CreateNewSaga(model, id); } } return(saga); }
public async Task <ISaga> Publish(ISagaEvent @event, IDictionary <string, object> executionValues, Guid?parentId, SagaRunOptions runOptions) { runOptions = runOptions ?? new SagaRunOptions(); Type eventType = @event.GetType(); SagaID sagaId = SagaID.From(@event.ID); ISagaModel model = sagaRegistrator. FindModelForEventType(eventType); if (model == null) { throw new SagaEventNotRegisteredException(eventType); } SagaID?parentSagaId = parentId == null ? (SagaID?)null : SagaID.From(parentId.Value); ISaga newSaga = await CreateNewSagaIfRequired(model, sagaId, parentSagaId, eventType); var id = SagaID.From(newSaga?.Data?.ID ?? sagaId.Value); try { var createdSaga = await ExecuteSaga( @event, model, newSaga, id, executionValues, false, runOptions); return(createdSaga); } /*catch (SagaStopException ex) * { * return await sagaPersistance.Get(id.Value); * }*/ catch { //if (newSaga != null) // await sagaPersistance.Remove(newSaga.Data.ID); throw; } }
private async Task <ISaga> DispatchStepSync( ExecuteStepCommand command) { using (IServiceScope scope = serviceScopeFactory.CreateScope()) { ExecuteStepCommandHandler stepExecutor = ActivatorUtilities. CreateInstance <ExecuteStepCommandHandler>(scope.ServiceProvider); ISaga saga = await stepExecutor. Handle(command); if (saga == null) { await messageBus.Publish( new ExecutionEndMessage(SagaID.From(command.Saga.Data.ID))); return(null); } else { if (saga.IsIdle()) { await messageBus.Publish( new ExecutionEndMessage(SagaID.From(saga.Data.ID))); if (saga.HasError()) { throw saga.ExecutionState.CurrentError; } return(saga); } else { return(await Handle(new ExecuteActionCommand() { Async = AsyncExecution.False(), Saga = saga, Model = command.Model })); } } } }
private async Task <ISaga> ExecuteSaga( ISagaEvent @event, ISagaModel model, ISaga saga, Guid sagaID, IDictionary <string, object> executionValues, bool resume) { bool sagaStarted = false; try { serviceProvider. GetRequiredService <ObservableRegistrator>(). Initialize(); await messageBus. Publish(new ExecutionStartMessage(SagaID.From(sagaID), model)); sagaStarted = true; if (saga == null) { saga = await sagaPersistance.Get(sagaID); } if (saga == null) { throw new SagaInstanceNotFoundException(); } if (saga.ExecutionState.IsDeleted) { throw new CountNotExecuteDeletedSagaException(sagaID); } if (!resume) { if (saga.IsIdle()) { saga.ExecutionState.CurrentError = null; saga.ExecutionState.ExecutionID = ExecutionID.New(); if (model.HistoryPolicy == ESagaHistoryPolicy.StoreOnlyCurrentStep) { saga.ExecutionState.History.Clear(); } saga.ExecutionValues. Set(executionValues); saga.ExecutionState. CurrentEvent = @event ?? new EmptyEvent(); } else { throw new SagaNeedToBeResumedException(saga.Data.ID); } logger. LogInformation($"Executing saga: {saga.Data.ID}"); } else { logger. LogInformation($"Resuming saga: {saga.Data.ID}"); } ExecuteActionCommandHandler handler = serviceProvider. GetRequiredService <ExecuteActionCommandHandler>(); return(await handler.Handle(new ExecuteActionCommand { Async = AsyncExecution.False(), Saga = saga, Model = model })); } catch (Exception ex) { if (sagaStarted) { await messageBus.Publish( new ExecutionEndMessage(SagaID.From(sagaID))); } if (ex is SagaStepException sagaStepException && sagaStepException?.OriginalException != null) { throw sagaStepException.OriginalException; } throw; } }
public ExecutionEndMessage(SagaID sagaId) { SagaId = sagaId; }
public ExecutionStartMessage(SagaID saga, ISagaModel model) { SagaID = saga; this.Model = model; }