/// <summary> /// Remaps all the wildcards in an operation to unique identifiers. /// </summary> /// <param name="operation">The operation.</param> /// <returns>The wrapped operation.</returns> public static ReifiedOperation LiftWildcards(this ReifiedOperation operation) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } return(LiftWildcards(operation, WildcardGenerator.Instance)); }
/// <summary> /// Repeat an operation until cancellation is requested. /// </summary> /// <param name="operation">The operation.</param> /// <param name="token">The cancellation token.</param> /// <returns>The wrapped operation.</returns> public static ReifiedOperation RepeatUntil(this ReifiedOperation operation, CancellationToken token) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } return(new RepeatUntil(operation, token)); }
internal Repeat(ReifiedOperation operation, long count) : base(ReifiedOperationKind.Repeat, operation) { if (count <= 0) { throw new ArgumentOutOfRangeException(nameof(count), "Count must be at least 0."); } Count = count; }
/// <summary> /// Starts an operation on a thread pool thread. /// </summary> /// <param name="operation">The operation.</param> /// <param name="onStart"> /// A callback to return the task after the operation has been started. /// </param> /// <param name="token"> /// A cancellation token to give to the task factory. /// </param> /// <returns>The wrapped operation.</returns> public static ReifiedOperation Async(this ReifiedOperation operation, Action <Task> onStart, CancellationToken token) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (onStart == null) { throw new ArgumentNullException(nameof(onStart)); } return(new Async(operation, onStart, token)); }
/// <summary> /// Repeat an operation a given number of times. /// </summary> /// <param name="operation">The operation.</param> /// <param name="count">The number of times to repeat the operation.</param> /// <returns>The wrapped operation.</returns> public static ReifiedOperation Repeat(this ReifiedOperation operation, long count) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (count <= 0) { throw new ArgumentOutOfRangeException(nameof(count), "Count must be at least 0."); } return(new Repeat(operation, count)); }
/// <summary> /// Remaps all the wildcards in an operation to identifiers taken from the wildcard generator. /// </summary> /// <param name="operation">The operation.</param> /// <param name="generator">The wildcard generator.</param> /// <returns>The wrapped operation.</returns> public static ReifiedOperation LiftWildcards(this ReifiedOperation operation, IWildcardGenerator generator) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (generator == null) { throw new ArgumentNullException(nameof(generator)); } return(new LiftWildcards(operation, generator)); }
/// <summary> /// Wraps a sequence of operations as a single, ordered operation. /// </summary> /// <param name="first">The first operation.</param> /// <param name="rest">The rest of the operations.</param> /// <returns>The wrapped operation.</returns> public static ReifiedOperation Chain(this ReifiedOperation first, params ReifiedOperation[] rest) { if (first == null) { throw new ArgumentNullException(nameof(first)); } if (rest == null) { throw new ArgumentNullException(nameof(rest)); } return(new Chain(first, rest)); }
/// <summary> /// Catches any exception thrown by the given operation. /// </summary> /// <param name="operation">The operation.</param> /// <param name="handler">The callback for any exceptions thrown.</param> /// <returns>The wrapped operation.</returns> public static ReifiedOperation Catch(this ReifiedOperation operation, Action <Exception> handler) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (handler == null) { throw new ArgumentNullException(nameof(handler)); } return(new Catch <Exception>(operation, handler)); }
/// <summary> /// Instruments an operation with callbacks that are invoked before and after the operation. /// </summary> /// <param name="operation">The operation.</param> /// <param name="onEnter"> /// Callback to invoke prior to evaluating the operation. /// </param> /// <param name="onExit"> /// Callback to invoke after evaluating the operation. /// </param> /// <returns>The wrapped operation.</returns> public static ReifiedOperation Instrument(this ReifiedOperation operation, Action onEnter, Action onExit) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (onEnter == null) { throw new ArgumentNullException(nameof(onEnter)); } if (onExit == null) { throw new ArgumentNullException(nameof(onExit)); } return(new Instrument(operation, onEnter, onExit)); }
internal Chain(ReifiedOperation first, IEnumerable <ReifiedOperation> rest) : base(ReifiedOperationKind.Chain, first) { if (rest == null) { throw new ArgumentNullException(nameof(rest)); } else if (rest.FirstOrDefault() == null) { throw new ArgumentException("Expected at least one operation in the chain.", nameof(rest)); } else if (rest.Any(o => o == null)) { throw new ArgumentException("Chained operations must not be null.", nameof(rest)); } Rest = rest; }
/// <summary> /// Binds a reified operation to a given environment. /// </summary> /// <typeparam name="TEnvironment">The environment type.</typeparam> /// <param name="operation">The operation to bind.</param> /// <param name="binder">The binder to use.</param> /// <returns> /// A lambda expression to evaluate the reified operation. /// </returns> public static Expression <Action <TEnvironment> > Bind <TEnvironment>(this ReifiedOperation operation, IReificationBinder <TEnvironment> binder) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } if (binder == null) { throw new ArgumentNullException(nameof(binder)); } var flattener = new ReifiedOperationFlattener(); var opBinder = new ReifiedOperationBinder <TEnvironment>(binder); var flattened = flattener.Visit(operation); var bound = opBinder.Visit(flattened); return(binder.Optimize(bound)); }
/// <summary> /// Visits a reified operation. /// </summary> /// <param name="operation">The operation.</param> /// <returns>The result of visiting the operation.</returns> public virtual TResult Visit(ReifiedOperation operation) { if (operation == null) { throw new ArgumentNullException(nameof(operation)); } return(operation.Kind switch { ReifiedOperationKind.Async => VisitAsync((Async)operation), ReifiedOperationKind.Catch => VisitCatch(operation), ReifiedOperationKind.Chain => VisitChain((Chain)operation), ReifiedOperationKind.Instrument => VisitInstrument((Instrument)operation), ReifiedOperationKind.LiftWildcards => VisitLiftWildcards((LiftWildcards)operation), ReifiedOperationKind.QueryEngineOperation => VisitQueryEngineOperation((QueryEngineOperation)operation), ReifiedOperationKind.Repeat => VisitRepeat((Repeat)operation), ReifiedOperationKind.RepeatUntil => VisitRepeatUntil((RepeatUntil)operation), ReifiedOperationKind.ServiceOperation => VisitServiceOperation((ServiceOperation)operation), _ => VisitExtension(operation), });
protected override Expression <Action <TEnvironment> > VisitExtension(ReifiedOperation operation) { throw new NotImplementedException(); }
internal Async(ReifiedOperation operation, Action <Task> onStart, CancellationToken token) : base(ReifiedOperationKind.Async, operation) { Token = token; OnStart = onStart; }
internal LiftWildcards(ReifiedOperation operation, IWildcardGenerator generator) : base(ReifiedOperationKind.LiftWildcards, operation) { Generator = generator ?? throw new ArgumentNullException(nameof(generator)); }
internal RepeatUntil(ReifiedOperation operation, CancellationToken token) : base(ReifiedOperationKind.RepeatUntil, operation) { Token = token; }
internal OperationBase(ReifiedOperationKind kind, ReifiedOperation operation) : base(kind) { Operation = operation ?? throw new ArgumentNullException(nameof(operation)); }
internal Catch(ReifiedOperation operation, Action <T> handler) : base(ReifiedOperationKind.Catch, operation) { Handler = handler ?? throw new ArgumentNullException(nameof(handler)); }
internal Instrument(ReifiedOperation operation, Action onEnter, Action onExit) : base(ReifiedOperationKind.Instrument, operation) { OnEnter = onEnter ?? throw new ArgumentNullException(nameof(onEnter)); OnExit = onExit ?? throw new ArgumentNullException(nameof(onExit)); }