public ExecuteOperationCellIfNecessaryOp <TValue> DeepCloneWithCell(IOperationOutputCell <TValue> cell) { var result = new ExecuteOperationCellIfNecessaryOp <TValue>( cell); return(result); }
/// <summary> /// Gets the outcome of executing an <see cref="IOperationOutputCell{TValue}"/>'s <see cref="IOperationOutputCell{TValue}.Operation"/>. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The outcome of executing an <see cref="IOperationOutputCell{TValue}"/>'s <see cref="IOperationOutputCell{TValue}.Operation"/>. /// </returns> public static CellOpExecutionOutcome GetCellOpExecutionOutcome( this IOperationOutputCell cell) { if (cell == null) { throw new ArgumentNullException(nameof(cell)); } var executionStatus = cell.GetCellOpExecutionStatus(); switch (executionStatus) { case CellOpExecutionStatus.DeemedNotApplicable: return(CellOpExecutionOutcome.NotApplicable); case CellOpExecutionStatus.Aborted: return(CellOpExecutionOutcome.Aborted); case CellOpExecutionStatus.Failed: return(CellOpExecutionOutcome.Failed); case CellOpExecutionStatus.Completed: return(CellOpExecutionOutcome.Completed); default: return(CellOpExecutionOutcome.Unknown); } }
/// <summary> /// Initializes a new instance of the <see cref="ExecuteOperationCellIfNecessaryOp{TValue}"/> class. /// </summary> /// <param name="cell">The cell.</param> public ExecuteOperationCellIfNecessaryOp( IOperationOutputCell <TValue> cell) { if (cell == null) { throw new ArgumentNullException(nameof(cell)); } this.Cell = cell; }
/// <summary> /// Gets the status of the execution of an <see cref="IOperationOutputCell{TValue}"/>'s <see cref="IOperationOutputCell{TValue}.Operation"/>. /// </summary> /// <param name="cell">The cell.</param> /// <returns> /// The status of the execution of an <see cref="IOperationOutputCell{TValue}"/>'s <see cref="IOperationOutputCell{TValue}.Operation"/>. /// </returns> public static CellOpExecutionStatus GetCellOpExecutionStatus( this IOperationOutputCell cell) { if (cell == null) { throw new ArgumentNullException(nameof(cell)); } CellOpExecutionStatus result; var lastCellOpExecutionEvent = cell.OperationExecutionEvents?.LastOrDefault(); if (lastCellOpExecutionEvent == null) { result = CellOpExecutionStatus.NotExecuted; } else if (lastCellOpExecutionEvent is CellOpExecutionClearedEvent) { result = CellOpExecutionStatus.NotExecuted; } else if (lastCellOpExecutionEvent is CellOpExecutionAbortedEvent) { result = CellOpExecutionStatus.Aborted; } else if (lastCellOpExecutionEvent is CellOpExecutionDeemedNotApplicableEvent) { result = CellOpExecutionStatus.DeemedNotApplicable; } else if (lastCellOpExecutionEvent is CellOpExecutionFailedEvent) { result = CellOpExecutionStatus.Failed; } else if (lastCellOpExecutionEvent.GetType().GetGenericTypeDefinitionOrSpecifiedType() == typeof(CellOpExecutionCompletedEvent <>)) { result = CellOpExecutionStatus.Completed; } else { throw new InvalidOperationException(Invariant($"Cannot determine the {nameof(CellOpExecutionStatus)} of the specified cell.")); } return(result); }
private static IOperation BuildExecuteOperationCellIfNecessaryOp( this IOperationOutputCell operationCell) { var valueType = operationCell.GetValueTypeOrNull(); if (valueType == null) { throw new InvalidOperationException(Invariant($"This kind of cell is supposed to have a value type: {operationCell.GetType().ToStringReadable()}.")); } if (!CachedTypeToExecuteOperationCellIfNecessaryOpConstructorInfoMap.TryGetValue(valueType, out var executeOperationCellIfNecessaryOpConstructorInfo)) { executeOperationCellIfNecessaryOpConstructorInfo = typeof(ExecuteOperationCellIfNecessaryOp <>).MakeGenericType(valueType).GetConstructors().Single(); CachedTypeToExecuteOperationCellIfNecessaryOpConstructorInfoMap.TryAdd(valueType, executeOperationCellIfNecessaryOpConstructorInfo); } // ReSharper disable once CoVariantArrayConversion var result = (IOperation)executeOperationCellIfNecessaryOpConstructorInfo.Invoke(new[] { operationCell }); return(result); }
private async Task ExecuteOperationCellIfNecessaryAsync( IOperationOutputCell <TValue> cell) { // NOTE: THIS CODE IS A NEAR DUPLICATE OF THE SYNC METHOD ABOVE; NO GOOD WAY TO D.R.Y. IT OUT if (cell.GetCellOpExecutionStatus() == CellOpExecutionStatus.NotExecuted) { CellOpExecutionEventBase operationExecutionEvent; try { var operationResult = await this.protocolFactory.GetProtocolAndExecuteViaReflectionAsync <TValue>(cell.Operation); operationExecutionEvent = new CellOpExecutionCompletedEvent <TValue>(this.timestampUtc, null, operationResult); } catch (OpExecutionAbortedExceptionBase ex) { operationExecutionEvent = new CellOpExecutionAbortedEvent(this.timestampUtc, ex.ToString()); } catch (OpExecutionDeemedNotApplicableExceptionBase ex) { operationExecutionEvent = new CellOpExecutionDeemedNotApplicableEvent(this.timestampUtc, ex.ToString()); } catch (Exception ex) { // The "proper" exception for a protocol to throw is an OpExecutionFailedExceptionBase. // Protocol authors might not comply. operationExecutionEvent = new CellOpExecutionFailedEvent(this.timestampUtc, ex.ToString()); } cell.Record(operationExecutionEvent); } else if (cell.OperationExecutionEvents.Last().TimestampUtc != this.timestampUtc) { throw new InvalidOperationException("Something went wrong. The operation was executed, but the recorded timestamp doesn't match this timestamp."); } }