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
TypeScript
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;