UNPKG

metaapi.cloud-sdk

Version:

SDK for MetaApi, a professional cloud forex API which includes MetaTrader REST API and MetaTrader websocket API. Supports both MetaTrader 5 (MT5) and MetaTrader 4 (MT4). CopyFactory copy trading API included. (https://metaapi.cloud)

282 lines (281 loc) 11.5 kB
import AsyncProcess from './asyncProcess'; import EventEmitter from '../../../../tools/eventEmitter'; /** * Starts, stops, restarts and provides long-running background processes (running functions within node process) * resolving race conditions and including process failovers until process canceled */ declare class AsyncProcessPool<Provider, Process extends AsyncProcess> { protected _logger: import("../../../../logger").Logger; private _processProvider; private _scheduledProcesses; private _runtimeProcesses; private _processRuntimes; private _options?; private _events; private _label; private _stopped; private _usages; private _dependencies; /** * Constructs instance * @param provider process provider * @param options additional options */ constructor(provider: Provider, options: AsyncProcessPool.Options<Process>); /** * Returns label for logging * @returns label */ get label(): string; /** * Event emitter related to this pool * @returns event emitter * @internal */ get events(): EventEmitter<AsyncProcessPool.Events<Process>>; /** * Returns whether the scheduler was given command to stop * @returns whether stopped */ get stopped(): boolean; /** * Schedules a process. After the process has scheduled, it is immediately available in synchronous way. But it may * not be started fully yet (its `start` method not completed yet), or currently running process may be an old one, * which is going to stop. The latest actual and fully started process can be awaited with `waitProcess` method * @param id process ID. If a process with same ID is already scheduled, the call will be ignored * @param options process options * @throws if the pool is stopped and the `throwIfStopped` option is enabled */ scheduleProcess(id: string, options: AsyncProcessPool.ScheduleProcessOptions<Provider>): void; /** * Restarts a process if it is scheduled, otherwise the call will be ignored. If the process is waiting for throttle * delay to failover after error or unexpected stop, this method will force the failover * @param process process ID or process itself. If the process instance is specified, it will be restarted only if it * is still actual running process and not scheduled to be restarted yet */ restartProcess(process: string | Process): void; /** * Cancels a process * @param id process ID * @param options additional options * @returns promise resolving when currently running process stopped */ cancelProcess(id: string, options?: AsyncProcessPool.CancelProcessOptions): Promise<void>; private _cancelProcess; /** * Returns scheduled process IDs * @returns process IDs */ getScheduledIds(): string[]; /** * Returns running at this moment process IDs. It will always include scheduled IDs + some processes that was canceled * but may be still running or stopping * @returns process IDs */ getRunningIds(): string[]; /** * Returns whether has scheduled process * @param id process ID * @returns true if scheduled */ hasScheduled(id: string): boolean; /** * Returns whether has a process, scheduled by specific usage * @param id process ID * @param usage usage * @returns true if scheduled by */ hasScheduledBy(id: string, usage: any): boolean; /** * Returns process IDs which are scheduled by specific usage * @param usage usage * @returns process IDs */ getScheduledBy(usage: any): string[]; /** * Returns process schedulement * @param id process ID * @returns schedulement or undefined if not scheduled */ getSchedulement(id: string): AsyncProcessPool.Schedulement<Provider> | undefined; /** * Returns current process in its running state which can be not started yet, starting, running, stopping or stopped * @param id process ID * @returns process in its state or undefined if there is no such process scheduled */ getProcess(id: string): Process | undefined; /** * Waits for running started process instance. If the process was rescheduled/restarted and an old process instance is * still running, the method will wait for the new process instance to start only. Note, that a process can become * stopped or canceled till the method resolves after `await` in the calling code. So this method only increases * probability the returned process will be running * @param id process ID * @param options additional options * @returns promise resolving with process or `undefined`, depending on specified options * @throws if process is not scheduled or becomes unscheduled during waiting due to `throwIfNotScheduled` option * @throws `TimeoutError` if timed out waiting for the process due to timeout options */ waitProcess(id: string, options?: AsyncProcessPool.WaitProcessOptions): Promise<Process>; /** * Cancels all currently scheduled processes and waits until they stop * @returns promise resolving when stopped */ cancelAll(): Promise<void>; /** * Stops all processes * @returns promise resolving when stopped */ stop(): Promise<void>; private _run; private _handleControlSignal; private _getThrottleDelay; private _stopProcess; } declare namespace AsyncProcessPool { /** Process provider */ type ProcessProvider<Process extends AsyncProcess> = (context: Context, args: any[]) => ConstructedProcess<Process>; /** Constructed process */ type ConstructedProcess<Process extends AsyncProcess> = { /** Process */ process: Process; /** Process context */ context: ProcessContext; /** Mapped process args */ args: any[]; }; /** Basic process context */ type Context = { /** Process ID */ processId: string; /** Current pool */ pool: AsyncProcessPool<any, any>; /** Process stage */ stage: ProcessContext.ProcessStage; /** Whether the process was scheduled to cancel by external command (cancel or restart) */ canceled?: boolean; }; /** Constructing options */ type Options<Process> = { /** Logging label. Defaults to `default` */ label?: string; /** * Process run attempt throttle delay in case of failover. May be overriden by processes when scheduling, * Defaults to 30 seconds */ processFailoverThrottleDelayInMs?: number; /** Dependencies shared across all processes */ dependencies: AsyncProcess.Dependencies<Process>; }; /** Method options */ type ScheduleProcessOptions<Provider> = { /** Process constructor parameters */ args: ProcessArgs<Provider>; /** Whether to throw an error if the pool is already stopped. Defaults to `true` */ throwIfStopped?: boolean; /** * Usage to track to make it possible to cancel process only when all usages are canceled. * Defaults to `default` */ usage?: any; /** Overriden failover throttle delay to use */ failoverThrottleDelay?: ThrottleDelay; }; /** Throttle delay */ type ThrottleDelay = FixedDelay | ExponentialDelay; /** Fixed delay */ type FixedDelay = { /** Mode */ mode: 'fixed'; /** Delay value */ delayInMs: number; /** Delay randomization factor in range [0; 1]. Defaults to `0` */ randomizationFactor?: number; }; /** Exponential delay */ type ExponentialDelay = { /** Mode */ mode: 'exponential'; /** Minimum (start) delay */ minDelayInMs: number; /** Maximum (end) delay */ maxDelayInMs: number; /** * Delay to wait after successful connection to reset current exponential delay to its minimum value. If the process * should be throttled again and this delay has not timed out yet, the throttle delay will increase exponentially. * Otherwise, the throttle delay will start from beginning. Defaults to `0` */ resetDelayInMs?: number; /** Delay randomization factor in range [0; 1]. Defaults to `0` */ randomizationFactor?: number; }; /** Method options */ type CancelProcessOptions = { /** Usage to actually cancel process only when last usage is canceled. Defaults to `default` */ usage?: any; /** Whether to cancel all usages */ allUsages?: boolean; }; /** Latest schedulement data */ type Schedulement<Provider> = { /** Options with which the account was scheduled */ options: { /** Process constructor parameters */ args: ProcessArgs<Provider>; }; /** Usages */ usages: Set<any>; }; /** Method options */ type WaitProcessOptions = { /** Waiting timeout */ timeoutInMs?: number; /** * Promise signalizing when waiting should be stopped. Makes the method return `undefined` if resolved or rejects * with the promise's error */ stopPromise?: Promise<void>; /** * Whether to throw error if process is not scheduled or becomes canceled during waiting. If `false` and process is * not scheduled, `undefined` will be returned. The error won't be thrown if the process was canceled and then * immediately scheduled again in synchronous way */ throwIfNotScheduled?: boolean; /** Whether to throw `TimeoutError` error if waiting timeout exceeded */ throwOnTimeout?: boolean; }; /** Wait process attempt options */ type WaitAttemptOptions = { /** One attempt timeout */ timeoutInMsPerAttempt?: number; /** Whether to throw `TimeoutError` error if waiting attempts exceeded */ throwIfExceeded?: boolean; /** * Max attempts to wait. If the attempts exceeded, then eithier: * - if the process has still been scheduled, `undefined` will be returned * - otherwise, depends on `throwIfNotScheduled` option * @default Infinity */ maxAmount?: number; /** * Predicate to check if new waiting attempt should be performed. * If specified, has larger priority than `maxAmount` */ waitIf?: (attempt: number) => boolean; }; /** Event emitter events */ type Events<Process extends AsyncProcess> = { /** Called when a specific process created */ [event: `created:${ProcessId}`]: () => void; /** Called when a specific process fully successfully started */ [event: `started:${ProcessId}`]: (process: Process) => void; /** Called when a specific process canceled */ [event: `canceled:${ProcessId}`]: () => void; /** Called when any process fully successfully started */ started: (process: Process) => void; }; /** Process ID */ type ProcessId = string; } export default AsyncProcessPool; import ProcessContext from './processContext'; type ProcessArgs<Provider> = Provider extends AsyncProcessPool.ProcessProvider<any> ? Parameters<Provider>[1] : never;