private static void AssertExpectedTransactionOutcome( IPipelineTransaction t1, IPipelineTransaction t2, List <AssignablePipelineStage <int> > stages, List <TestPipelineStage <int> > tests, IEnumerable <int> transaction, PipelineTransactionResult expectedFirstResult, PipelineTransactionResult expectedSecondResult) { var stagesInTransaction = transaction.Select(i => stages[i]).ToList(); var testsInTransaction = transaction.Select(i => tests[i]).ToList(); var nonTransactionIndices = Enumerable.Range(0, stages.Count).Except(transaction).ToList(); var stagesNotInTransaction = nonTransactionIndices.Select(i => stages[i]).ToList(); var testsNotInTransaction = nonTransactionIndices.Select(i => tests[i]).ToList(); Assert.AreEqual(expectedFirstResult, t1.Commit()); stages.ForEach(a => PipelineAssert.Value(a, 1)); tests.ForEach(t => t.AssertNotInvalidatedNorRetrieved()); Assert.AreEqual(expectedSecondResult, t2.Commit()); stagesInTransaction.ForEach(a => PipelineAssert.Value(a, 2)); testsInTransaction.ForEach(t => t.AssertInvalidations(1)); stagesNotInTransaction.ForEach(a => PipelineAssert.Value(a, 1)); testsNotInTransaction.ForEach(t => t.AssertNotInvalidatedNorRetrieved()); }
private PipelineTransactionResult AggregateTransaction(IPipelineTransaction transaction, List <DeferredTransactionPart> res) { var mustCommitAggregate = DeregisterOngoing(transaction); var mustRollback = res.Any(part => AggregatedTransaction.ContainsKey(part.Stage)); if (mustRollback) { if (mustCommitAggregate) { CommitTransaction(AggregatedTransaction.Values); } return(PipelineTransactionResult.Failed); } else { foreach (var part in res) { AggregatedTransaction.Add(part.Stage, part); } if (mustCommitAggregate) { return(CommitTransaction(AggregatedTransaction.Values)); } else { return(PipelineTransactionResult.PendingSuccess); } } }
private bool DeregisterOngoing(IPipelineTransaction transaction) { if (!OngoingTransactions.Remove(transaction)) { throw new ArgumentException("Transaction is not registered."); } return(OngoingTransactions.Count <= 0); }
/// <summary> /// Adds an update to an <see cref="SourceSelectPipelineStage{TValue}"/>. /// </summary> /// <typeparam name="TValue">The data type.</typeparam> /// <param name="transaction">The transaction.</param> /// <param name="stage">The stage to set value for.</param> /// <param name="newSource">The new source.</param> /// <returns>The same transaction object.</returns> public static IPipelineTransaction Update <TValue>(this IPipelineTransaction transaction, SourceSelectPipelineStage <TValue> stage, IPipelineStage <TValue> newSource) { bool SourceSelectUpdate() => stage.SetSourceWithoutInvalidating(newSource); return(transaction.Update(stage, SourceSelectUpdate)); }
/// <summary> /// Adds an update to an <see cref="AssignablePipelineStage{TValue}"/>. /// </summary> /// <typeparam name="TValue">The data type.</typeparam> /// <param name="transaction">The transaction.</param> /// <param name="stage">The stage to set value for.</param> /// <param name="value">The new value.</param> /// <returns>The same transaction object.</returns> public static IPipelineTransaction Update <TValue>(this IPipelineTransaction transaction, AssignablePipelineStage <TValue> stage, TValue value) { bool AssignableUpdate() => stage.SetValueWithoutInvalidating(value); return(transaction.Update(stage, AssignableUpdate)); }
/// <summary> /// Adds the specified stage to the update, without doing any actual updating. The stage will be invalidated on transaction commit. /// </summary> /// <param name="transaction">The transaction</param> /// <param name="stage">The stage to add for the update.</param> /// <returns>The same update object.</returns> public static IPipelineTransaction Update(this IPipelineTransaction transaction, IPipelineStage stage) => transaction.Update(stage, NoAction);