public static async Task RunSessionPreparation <TStepId, TData>(ITransactionSession <TStepId, TData> session) #endif { switch (session.RunSettings.Mode) { case RunMode.Run: #if NET35 || NOASYNC RunSessionPreparationOperation.StartRun(session); #else await RunSessionPreparationOperation.StartRun(session); #endif break; case RunMode.RecoverAndUndoAndRun: #if NET35 || NOASYNC RunSessionPreparationOperation.PrepareToRunFromScratch(session); #else await RunSessionPreparationOperation.PrepareToRunFromScratch(session); #endif break; case RunMode.RecoverAndContinue: #if NET35 || NOASYNC RunSessionPreparationOperation.PrepareToContinue(session); #else await RunSessionPreparationOperation.PrepareToContinue(session); #endif break; default: throw new NotSupportedException(string.Format("RunMode '{0}' is not supported.", session.RunSettings.Mode)); } }
/// <summary> /// Runs the transaction. /// </summary> /// <param name="settings">The action to set settings.</param> /// <returns>The result.</returns> public async Task <ITransactionResult <TData> > Run(Action <IRunSettings <TStepId, TData> > settings) #endif { if (settings == null) { throw new ArgumentNullException(nameof(settings)); } RunSettings <TStepId, TData> runSettings = new RunSettings <TStepId, TData>(); settings(runSettings); runSettings.Validate(this.context); #if NET35 || NOASYNC ITransactionSession <TStepId, TData> session = this.CreateSession(runSettings); #else ITransactionSession <TStepId, TData> session = await this.CreateSession(runSettings); #endif session.Start(); #if NET35 || NOASYNC RunSessionPreparationOperation.RunSessionPreparation(session); #else await RunSessionPreparationOperation.RunSessionPreparation(session); return(await session.WaitForResultAsync()); #endif }
private static async Task PrepareToRunFromScratch <TStepId, TData>(ITransactionSession <TStepId, TData> session) #endif { #if NET35 || NOASYNC RunUndoOperation.RunUndo(new RunUndoContext <TStepId, TData>() #else await RunUndoOperation.RunUndo(new RunUndoContext <TStepId, TData>() #endif { NoSessionEnd = true, Session = session, #if NET35 || NOASYNC UndoFinishAction = () => { session.StepEnumerator.MoveNext(); RunSessionOperation.RunSession(session); } #else UndoFinishAction = async() => { session.StepEnumerator.MoveNext(); await RunSessionOperation.RunSession(session); } #endif });
/// <summary> /// Initializes a new instance of the <see cref="TransactionData<TStepId, TData>"/> class. /// </summary> /// <param name="session">The session.</param> public TransactionData(ITransactionSession <TStepId, TData> session) { this.currentStepIndex = session.StepEnumerator.CurrentStepIndex; this.startTimestamp = session.StartTimestamp; this.sessionId = session.SessionId; this.data = session.RunSettings.Data; }
private static async Task StartSession <TStepId, TData>(ITransactionSession <TStepId, TData> session) #endif { try { session.TransactionContext.Definition.NotifyTransactionStarted(); #if NET35 || NOASYNC session.TransactionContext.SessionStorage.SessionStarted(session); #else await session.TransactionContext.SessionStorage.SessionStarted(session); #endif } catch (Exception e) { session.TransactionContext.Logger.ErrorFormat(e, "An error occurred during starting a session for transaction '{0}'.", session.TransactionContext.Info.Name); #if NET35 || NOASYNC SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #else await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #endif { Session = session, RunPostActions = false, Result = ResultType.Failed } .AddError(e)); } }
public static async Task ProcessPost <TStepId, TData>(SessionEndContext <TStepId, TData> context) #endif { ITransactionStep <TStepId, TData> currentStep = context.Session.StepEnumerator.CurrentStep; ITransactionSession <TStepId, TData> session = context.Session; Stopwatch watch = new Stopwatch(); try { watch.Start(); #if NET35 || NOASYNC currentStep.PostAction(session.StepEnumerator.Data, context.Session); #else if (currentStep.PostAction != null) { currentStep.PostAction(session.StepEnumerator.Data, context.Session); } else { await currentStep.AsyncPostAction(session.StepEnumerator.Data, context.Session); } #endif watch.Stop(); if (session.ShouldLogStepExecution()) { session.TransactionContext .Logger .LogExecutionTime( watch.Elapsed, "Transaction '{0}': execution time for post step action for step '{1}' with id '{2}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, currentStep.Id); } } catch (Exception e) { watch.Stop(); string info = string.Format( "Transaction '{0}': an error occurred during processing post step action for step '{1}' with id '{2}', execution time '{3}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, currentStep.Id, watch.Elapsed); session.TransactionContext.Logger.ErrorFormat(e, info); #if NET35 || NOASYNC SessionEndOperation.EndSession(context.AddError(e)); #else await SessionEndOperation.EndSession(context.AddError(e)); #endif } }
private static async Task MoveToNextStep <TStepId, TData>(ITransactionSession <TStepId, TData> session, bool runSession) #endif { if (session.MoveInfo == null) { session.StepEnumerator.MoveNext(); if (runSession && !session.Ended) { #if NET35 || NOASYNC RunSessionOperation.RunSession(session); #else await RunSessionOperation.RunSession(session); #endif } } else { #if NET35 || NOASYNC MoveToStepOperation.MoveToStep(new MoveToStepContext <TStepId, TData>() #else await MoveToStepOperation.MoveToStep(new MoveToStepContext <TStepId, TData>() #endif { Session = session, #if NET35 || NOASYNC MoveToStepFinishAction = () => #else MoveToStepFinishAction = async() => #endif { if (runSession && !session.Ended) { #if NET35 || NOASYNC RunSessionOperation.RunSession(session); #else await RunSessionOperation.RunSession(session); #endif } } }); } }
public static async Task PrepareStep <TStepId, TData>(this ITransactionSession <TStepId, TData> session) #endif { try { #if NET35 || NOASYNC session.TransactionContext.SessionStorage.StepPrepared(session); #else await session.TransactionContext.SessionStorage.StepPrepared(session); #endif } catch (Exception e) { string info = string.Format("Transaction '{0}': an error occurred during notifying ste prepared.", session.TransactionContext.Info.Name); session.TransactionContext.Logger.ErrorFormat(e, info); session.StepEnumerator.MovePrevious(); #if NET35 || NOASYNC RunUndoOperation.RunUndo(new RunUndoContext <TStepId, TData>() #else await RunUndoOperation.RunUndo(new RunUndoContext <TStepId, TData>() #endif { Session = session, CaughtException = e, Result = ResultType.Failed }); #if NET35 || NOASYNC SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #else await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #endif { Session = session, RunPostActions = false, Result = ResultType.Failed } .AddError(e)); } }
/// <summary> /// Checks if the execution time of the current step should be logged. /// </summary> /// <typeparam name="TStepId">The type of the step id.</typeparam> /// <typeparam name="TData">The type of the transaction data.</typeparam> /// <param name="session">The session.</param> /// <returns><c>True</c> if the execution time of the current step should be logged, otherwise <c>false</c>.</returns> public static bool ShouldLogStepExecution <TStepId, TData>(this ITransactionSession <TStepId, TData> session) { return(session.RunSettings.LogTimeExecutionForAllSteps() || session.StepEnumerator.CurrentStep.Settings.LogExecutionTime()); }
/// <summary> /// Removes the transaction session. /// </summary> /// <typeparam name="TStepId">The type of the step id.</typeparam> /// <typeparam name="TData">The type of the transaction data.</typeparam> /// <param name="storage">The storage.</param> /// <param name="session">the session.</param> #if NET35 || NOASYNC public static void RemoveSession <TStepId, TData>(this ITransactionStorage <TData> storage, ITransactionSession <TStepId, TData> session) { if (storage != null) { storage.RemoveSession(new TransactionData <TStepId, TData>(session)); } }
public static async Task StepReceding <TStepId, TData>(this ITransactionStorage <TData> storage, ITransactionSession <TStepId, TData> session) { if (storage != null) { await storage.StepReceding(new TransactionData <TStepId, TData>(session)); } }
/// <summary> /// Notifies that that a new step was prepared to run. /// </summary> /// <typeparam name="TStepId">The type of the step id.</typeparam> /// <typeparam name="TData">The type of the transaction data.</typeparam> /// <param name="storage">The storage.</param> /// <param name="session">the session.</param> #if NET35 || NOASYNC public static void StepPrepared <TStepId, TData>(this ITransactionStorage <TData> storage, ITransactionSession <TStepId, TData> session) { if (storage != null) { storage.StepPrepared(new TransactionData <TStepId, TData>(session)); } }
public static async Task RunPost <TStepId, TData>(SessionEndContext <TStepId, TData> context) #endif { while (true) { ITransactionStep <TStepId, TData> step = context.Session.StepEnumerator.CurrentStep; if (step == null) { #if NET35 || NOASYNC SessionEndOperation.EndSession(context); #else await SessionEndOperation.EndSession(context); #endif return; } ITransactionSession <TStepId, TData> session = context.Session; if (session.Recovered && step.Settings.NotRunOnRecovered()) { session.TransactionContext .Logger .DebugFormat( "Transaction '{0}': ignoring the post step action for step '{1}' with id '{2}' as the step cannot be executed on a recovered transaction.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, session.StepEnumerator.CurrentStep.Id); session.StepEnumerator.MoveNext(); continue; } #if NET35 || NOASYNC if (step.PostAction == null) #else if (step.PostAction == null && step.AsyncPostAction == null) #endif { session.TransactionContext .Logger .DebugFormat( "Transaction '{0}': no post step action for step '{1}' with id '{2}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, session.StepEnumerator.CurrentStep.Id); session.StepEnumerator.MoveNext(); continue; } IExecutor executor = step.PostActionExecutor != null ? step.PostActionExecutor : step.Settings.SameExecutorForAllActions() ? step.StepActionExecutor : null; if (executor != null && executor.ShouldRun) { #if NET35 || NOASYNC executor.Run(() => { ProcessPostOperation.ProcessPost(context); if (!session.Ended) { session.StepEnumerator.MoveNext(); RunPostOperation.RunPost(context); } }); #else executor.Run(async() => { await ProcessPostOperation.ProcessPost(context); if (!session.Ended) { session.StepEnumerator.MoveNext(); await RunPostOperation.RunPost(context); } }); #endif return; } else { #if NET35 || NOASYNC ProcessPostOperation.ProcessPost(context); #else await ProcessPostOperation.ProcessPost(context); #endif session.StepEnumerator.MoveNext(); } } }
public static void RunSessionPreparation <TStepId, TData>(ITransactionSession <TStepId, TData> session)
private static void MoveToNextStep <TStepId, TData>(ITransactionSession <TStepId, TData> session, bool runSession)
public static void PrepareStep <TStepId, TData>(this ITransactionSession <TStepId, TData> session)
public static async Task RunUndo <TStepId, TData>(RunUndoContext <TStepId, TData> context) #endif { while (context.ProcessStepPredicate(context.Session.StepEnumerator.CurrentStep)) { ITransactionStep <TStepId, TData> step = context.Session.StepEnumerator.CurrentStep; if (step == null) { if (context.NoSessionEnd) { #if NET35 || NOASYNC context.UndoFinishAction(); #else await context.UndoFinishAction(); #endif return; } #if NET35 || NOASYNC SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #else await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #endif { RunPostActions = false, Session = context.Session, Result = context.Result } .AddError(context.CaughtException)); return; } ITransactionSession <TStepId, TData> session = context.Session; if (session.Recovered && step.Settings.NotRunOnRecovered()) { session.TransactionContext .Logger .DebugFormat( "Transaction '{0}': ignoring the undo step action for step '{1}' with id '{2}' as the step cannot be executed on a recovered transaction.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, session.StepEnumerator.CurrentStep.Id); session.StepEnumerator.MovePrevious(); continue; } #if NET35 || NOASYNC if (step.UndoAction == null) #else if (step.UndoAction == null && step.AsyncUndoAction == null) #endif { session.TransactionContext .Logger .DebugFormat( "Transaction '{0}': no undo step action for step '{1}' with id '{2}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, session.StepEnumerator.CurrentStep.Id); session.StepEnumerator.MovePrevious(); continue; } IExecutor executor = step.UndoActionExecutor != null ? step.UndoActionExecutor : step.Settings.SameExecutorForAllActions() ? step.StepActionExecutor : null; if (executor != null && executor.ShouldRun) { #if NET35 || NOASYNC executor.Run(() => { ProcessUndoOperation.ProcessUndo(context); if (!session.Ended) { session.StepEnumerator.MovePrevious(); RunUndoOperation.RunUndo(context); } }); #else executor.Run(async() => { await ProcessUndoOperation.ProcessUndo(context); if (!session.Ended) { session.StepEnumerator.MovePrevious(); await RunUndoOperation.RunUndo(context); } }); #endif return; } else { #if NET35 || NOASYNC ProcessUndoOperation.ProcessUndo(context); #else await ProcessUndoOperation.ProcessUndo(context); #endif session.StepEnumerator.MovePrevious(); } } #if NET35 || NOASYNC context.UndoFinishAction(); #else await context.UndoFinishAction(); #endif }
private static void PrepareToRunFromScratch <TStepId, TData>(ITransactionSession <TStepId, TData> session)
public static async Task ProcessUndo <TStepId, TData>(RunUndoContext <TStepId, TData> context) #endif { ITransactionStep <TStepId, TData> currentStep = context.Session.StepEnumerator.CurrentStep; ITransactionSession <TStepId, TData> session = context.Session; Stopwatch watch = new Stopwatch(); try { watch.Start(); #if NET35 || NOASYNC currentStep.UndoAction(session.StepEnumerator.Data, session); #else if (currentStep.UndoAction != null) { currentStep.UndoAction(session.StepEnumerator.Data, session); } else { await currentStep.AsyncUndoAction(session.StepEnumerator.Data, session); } #endif watch.Stop(); #if NET35 || NOASYNC context.Session.TransactionContext.SessionStorage.StepReceding(session); #else await context.Session.TransactionContext.SessionStorage.StepReceding(session); #endif if (session.ShouldLogStepExecution()) { session.TransactionContext .Logger .LogExecutionTime( watch.Elapsed, "Transaction '{0}': execution time for undo step action for step '{1}' with id '{2}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, currentStep.Id); } } catch (Exception e) { watch.Stop(); string info = string.Format( "Transaction '{0}': an error occurred during processing undo step action for step '{1}' with id '{2}', execution time '{3}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, currentStep.Id, watch.Elapsed); session.TransactionContext.Logger.ErrorFormat(e, info); #if NET35 || NOASYNC SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #else await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #endif { Session = context.Session, RunPostActions = false, Result = ResultType.Failed } .AddError(context.CaughtException) .AddError(e)); } }
/// <summary> /// Initilalizes a new instance of the <see cref="StepEnumerator<TStepId, TData>"/> class. /// </summary> /// <param name="session">The session.</param> public StepEnumerator(ITransactionSession <TStepId, TData> session) { this.session = session; }
public static void RunSession <TStepId, TData>(this ITransactionSession <TStepId, TData> session)
public static async Task RunSession <TStepId, TData>(ITransactionSession <TStepId, TData> session) #endif { while (true) { ITransactionStep <TStepId, TData> step = session.StepEnumerator.CurrentStep; if (step == null) { #if NET35 || NOASYNC SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #else await SessionEndPreparationOperation.PrepareEndSession(new SessionEndContext <TStepId, TData>() #endif { Session = session, RunPostActions = true, Result = ResultType.Success }); return; } #if NET35 || NOASYNC session.PrepareStep(); #else await session.PrepareStep(); #endif if (session.Ended) { return; } if (session.Recovered && step.Settings.NotRunOnRecovered()) { session.TransactionContext .Logger .DebugFormat( "Transaction '{0}': ignoring step '{1}' with id '{2}' as the step cannot be executed on a recovered transaction.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, session.StepEnumerator.CurrentStep.Id); session.StepEnumerator.MoveNext(); continue; } session.TransactionContext .Logger .DebugFormat( "Transaction '{0}: running step '{1}' with id '{2}'.", session.TransactionContext.Info.Name, session.StepEnumerator.CurrentStepIndex, session.StepEnumerator.CurrentStep.Id); IExecutor executor = session.StepEnumerator.CurrentStep.StepActionExecutor; if (executor != null && executor.ShouldRun) { #if NET35 || NOASYNC executor.Run(() => { session.ProcessStep(); if (!session.Ended) { RunSessionOperation.MoveToNextStep(session, true); } }); #else executor.Run(async() => { await session.ProcessStep(); if (!session.Ended) { await RunSessionOperation.MoveToNextStep(session, true); } }); #endif return; } else { #if NET35 || NOASYNC session.ProcessStep(); #else await session.ProcessStep(); #endif if (session.Ended) { return; } #if NET35 || NOASYNC RunSessionOperation.MoveToNextStep(session, false); #else await RunSessionOperation.MoveToNextStep(session, false); #endif } } }
/// <summary> /// Starts the session. /// </summary> /// <param name="session">The session.</param> #if NET35 || NOASYNC private static void StartSession <TStepId, TData>(ITransactionSession <TStepId, TData> session)