UNPKG

@rushstack/operation-graph

Version:

Library for managing and executing operations in a directed acyclic graph.

157 lines 6.53 kB
import type { ITerminal } from '@rushstack/terminal'; import type { IOperationRunner, IOperationRunnerContext, IOperationState, IOperationStates } from './IOperationRunner'; import { OperationStatus } from './OperationStatus'; /** * Options for constructing a new Operation. * @beta */ export interface IOperationOptions { /** * The name of this operation, for logging. */ name?: string | undefined; /** * The group that this operation belongs to. Will be used for logging and duration tracking. */ groupName?: string | undefined; /** * When the scheduler is ready to process this `Operation`, the `runner` implements the actual work of * running the operation. */ runner?: IOperationRunner | undefined; /** * The weight used by the scheduler to determine order of execution. */ weight?: number | undefined; } /** * Information provided to `executeAsync` by the `OperationExecutionManager`. * * @beta */ export interface IExecuteOperationContext extends Omit<IOperationRunnerContext, 'isFirstRun' | 'requestRun'> { /** * Function to invoke before execution of an operation, for logging. */ beforeExecute(operation: Operation, state: IOperationState): void; /** * Function to invoke after execution of an operation, for logging. */ afterExecute(operation: Operation, state: IOperationState): void; /** * Function used to schedule the concurrency-limited execution of an operation. * * Will return OperationStatus.Aborted if execution is aborted before the task executes. */ queueWork(workFn: () => Promise<OperationStatus>, priority: number): Promise<OperationStatus>; /** * A callback to the overarching orchestrator to request that the operation be invoked again. * Used in watch mode to signal that inputs have changed. */ requestRun?: (requestor?: string) => void; /** * Terminal to write output to. */ terminal: ITerminal; } /** * The `Operation` class is a node in the dependency graph of work that needs to be scheduled by the * `OperationExecutionManager`. Each `Operation` has a `runner` member of type `IOperationRunner`, whose * implementation manages the actual process of running a single operation. * * The graph of `Operation` instances will be cloned into a separate execution graph after processing. * * @beta */ export declare class Operation implements IOperationStates { /** * A set of all dependencies which must be executed before this operation is complete. */ readonly dependencies: Set<Operation>; /** * A set of all operations that wait for this operation. */ readonly consumers: Set<Operation>; /** * If specified, the name of a grouping to which this Operation belongs, for logging start and end times. */ readonly groupName: string | undefined; /** * The name of this operation, for logging. */ readonly name: string | undefined; /** * When the scheduler is ready to process this `Operation`, the `runner` implements the actual work of * running the operation. */ runner: IOperationRunner | undefined; /** * This number represents how far away this Operation is from the furthest "root" operation (i.e. * an operation with no consumers). This helps us to calculate the critical path (i.e. the * longest chain of projects which must be executed in order, thereby limiting execution speed * of the entire operation tree. * * This number is calculated via a memoized depth-first search, and when choosing the next * operation to execute, the operation with the highest criticalPathLength is chosen. * * Example: * (0) A * \\ * (1) B C (0) (applications) * \\ /|\\ * \\ / | \\ * (2) D | X (1) (utilities) * | / \\ * |/ \\ * (2) Y Z (2) (other utilities) * * All roots (A & C) have a criticalPathLength of 0. * B has a score of 1, since A depends on it. * D has a score of 2, since we look at the longest chain (e.g D-\>B-\>A is longer than D-\>C) * X has a score of 1, since the only package which depends on it is A * Z has a score of 2, since only X depends on it, and X has a score of 1 * Y has a score of 2, since the chain Y-\>X-\>C is longer than Y-\>C * * The algorithm is implemented in AsyncOperationQueue.ts as calculateCriticalPathLength() */ criticalPathLength: number | undefined; /** * The weight for this operation. This scalar is the contribution of this operation to the * `criticalPathLength` calculation above. Modify to indicate the following: * - `weight` === 1: indicates that this operation has an average duration * - `weight` &gt; 1: indicates that this operation takes longer than average and so the scheduler * should try to favor starting it over other, shorter operations. An example might be an operation that * bundles an entire application and runs whole-program optimization. * - `weight` &lt; 1: indicates that this operation takes less time than average and so the scheduler * should favor other, longer operations over it. An example might be an operation to unpack a cached * output, or an operation using NullOperationRunner, which might use a value of 0. */ weight: number; /** * The state of this operation the previous time a manager was invoked. */ lastState: IOperationState | undefined; /** * The current state of this operation */ state: IOperationState | undefined; /** * A cached execution promise for the current OperationExecutionManager invocation of this operation. */ private _promise; /** * If true, then a run of this operation is currently wanted. * This is used to track state from the `requestRun` callback passed to the runner. */ private _runPending; constructor(options?: IOperationOptions); addDependency(dependency: Operation): void; deleteDependency(dependency: Operation): void; reset(): void; /** * @internal */ _executeAsync(context: IExecuteOperationContext): Promise<OperationStatus>; private _executeInnerAsync; } //# sourceMappingURL=Operation.d.ts.map