/**
* Process Manager
* Pokemon Showdown - http://pokemonshowdown.com/
*
* This file abstract out multiprocess logic involved in several tasks.
*
* Child processes can be queried.
*
* @license MIT
*/
///
///
///
import * as child_process from 'child_process';
import * as cluster from 'cluster';
import * as Streams from './streams';
type ChildProcess = child_process.ChildProcess;
type Worker = cluster.Worker;
export declare const processManagers: ProcessManager[];
export declare function exec(args: string, execOptions?: child_process.ExecOptions): Promise<{
stderr: string;
stdout: string;
}>;
export declare function exec(args: [string, ...string[]], execOptions?: child_process.ExecFileOptions): Promise<{
stderr: string;
stdout: string;
}>;
declare class SubprocessStream extends Streams.ObjectReadWriteStream {
process: StreamProcessWrapper;
taskId: number;
constructor(process: StreamProcessWrapper, taskId: number);
_write(message: string): void;
_writeEnd(): void;
_destroy(): void;
}
declare class RawSubprocessStream extends Streams.ObjectReadWriteStream {
process: RawProcessWrapper;
constructor(process: RawProcessWrapper);
_write(message: string): void;
}
export interface ProcessWrapper {
getLoad: () => number;
process: ChildProcess | Worker;
release: () => Promise;
getProcess: () => ChildProcess;
}
/** Wraps the process object in the PARENT process. */
export declare class QueryProcessWrapper implements ProcessWrapper {
process: ChildProcess;
taskId: number;
pendingTasks: Map void>;
messageCallback: ((message: string) => any) | null;
pendingRelease: Promise | null;
resolveRelease: (() => void) | null;
debug?: string;
file: string;
constructor(file: string, messageCallback?: (message: string) => any);
safeJSON(obj: string): any;
getProcess(): child_process.ChildProcess;
getLoad(): number;
query(input: T): Promise;
release(): Promise;
destroy(): void;
}
/** Wraps the process object in the PARENT process. */
export declare class StreamProcessWrapper implements ProcessWrapper {
process: ChildProcess;
taskId: number;
activeStreams: Map;
pendingRelease: Promise | null;
resolveRelease: (() => void) | null;
debug?: string;
setDebug(message: string): void;
messageCallback?: (message: string) => any;
constructor(file: string, messageCallback?: (message: string) => any);
getLoad(): number;
getProcess(): child_process.ChildProcess;
deleteStream(taskId: number): void;
createStream(): SubprocessStream;
release(): Promise;
destroy(): Promise | undefined;
}
/**
* A container for a RawProcessManager stream. This is usually the
* RawProcessWrapper, but it can also be a fake RawProcessWrapper if the PM is
* told to spawn 0 worker processes.
*/
export declare class StreamWorker {
load: number;
workerid: number;
stream: Streams.ObjectReadWriteStream;
constructor(stream: Streams.ObjectReadWriteStream);
}
/** Wraps the process object in the PARENT process. */
export declare class RawProcessWrapper implements ProcessWrapper, StreamWorker {
process: ChildProcess & {
process: undefined;
} | Worker;
taskId: number;
stream: RawSubprocessStream;
pendingRelease: Promise | null;
resolveRelease: (() => void) | null;
debug?: string;
workerid: number;
/** Not managed by RawProcessWrapper itself */
load: number;
setDebug(message: string): void;
constructor(file: string, isCluster?: boolean, env?: AnyObject);
getLoad(): number;
getProcess(): child_process.ChildProcess;
release(): Promise;
destroy(): void;
}
/**
* A ProcessManager wraps a query function: A function that takes a
* string and returns a string or Promise.
*/
export declare abstract class ProcessManager {
static disabled: boolean;
processes: T[];
releasingProcesses: T[];
crashedProcesses: T[];
readonly module: NodeJS.Module;
readonly filename: string;
readonly basename: string;
readonly isParentProcess: boolean;
crashTime: number;
crashRespawnCount: number;
constructor(module: NodeJS.Module);
acquire(): T | null;
releaseCrashed(process: T): void;
unspawn(): Promise;
unspawnOne(process: T | null): Promise;
spawn(count?: number, force?: boolean): void;
spawnOne(force?: boolean): T | null;
respawn(count?: number | null): Promise;
abstract listen(): void;
abstract createProcess(...args: any): T;
destroyProcess(process: T): void;
destroy(): Promise;
}
export declare class QueryProcessManager extends ProcessManager> {
_query: (input: T) => U | Promise;
messageCallback?: (message: string) => any;
timeout: number;
/**
* @param timeout The number of milliseconds to wait before terminating a query. Defaults to 900000 ms (15 minutes).
*/
constructor(module: NodeJS.Module, query: (input: T) => U | Promise, timeout?: number, debugCallback?: (message: string) => any);
query(input: T, process?: QueryProcessWrapper | null): Promise;
queryTemporaryProcess(input: T, force?: boolean): Promise;
createProcess(): QueryProcessWrapper;
listen(): void;
}
export declare class StreamProcessManager extends ProcessManager {
activeStreams: Map>;
_createStream: () => Streams.ObjectReadWriteStream;
messageCallback?: (message: string) => any;
constructor(module: NodeJS.Module, createStream: () => Streams.ObjectReadWriteStream, messageCallback?: (message: string) => any);
createStream(): Streams.ObjectReadWriteStream;
createProcess(): StreamProcessWrapper;
pipeStream(taskId: string, stream: Streams.ObjectReadStream): Promise;
listen(): void;
}
export declare class RawProcessManager extends ProcessManager {
/** full list of processes - parent process only */
workers: StreamWorker[];
/** if spawning 0 worker processes, the worker is instead stored here in the parent process */
masterWorker: StreamWorker | null;
/** stream used only in the child process */
activeStream: Streams.ObjectReadWriteStream | null;
isCluster: boolean;
spawnSubscription: ((worker: StreamWorker) => void) | null;
unspawnSubscription: ((worker: StreamWorker) => void) | null;
_setupChild: () => Streams.ObjectReadWriteStream;
/** worker ID of cluster worker - cluster child process only (0 otherwise) */
readonly workerid: number;
env: AnyObject | undefined;
constructor(options: {
module: NodeJS.Module;
setupChild: () => Streams.ObjectReadWriteStream;
isCluster?: boolean;
env?: AnyObject;
});
subscribeSpawn(callback: (worker: StreamWorker) => void): void;
subscribeUnspawn(callback: (worker: StreamWorker) => void): void;
spawn(count?: number): void;
createProcess(): RawProcessWrapper;
destroyProcess(process: RawProcessWrapper): void;
pipeStream(stream: Streams.ObjectReadStream): Promise;
listen(): void;
}
export {};