/// <reference types="node" />
import { InitProps, CallbackFunction, Message, ArgDefinition } from '../shared/sharedApi';
import { ThreadedClassConfig, ThreadedClass, MemUsageReport } from '../api';
import { WorkerPlatformBase } from './workerPlatform/_base';
export declare enum RegisterExitHandlers {
    /**
     * Do a check if any exit handlers have been registered by someone else.
     * If not, will set up exit handlers to ensure child processes are killed on exit signal.
     */
    AUTO = -1,
    /** Set up exit handlers to ensure child processes are killed on exit signal. */
    YES = 1,
    /**
     * Don't set up any exit handlers (depending on your environment and Node version,
     * children might need to be manually killed).
     */
    NO = 0
}
export declare class ThreadedClassManagerClass {
    private _internal;
    constructor(internal: ThreadedClassManagerClassInternal);
    /** Enable debug messages */
    set debug(v: boolean);
    get debug(): boolean;
    /**
     * Enable strict mode.
     * When strict mode is enabled, checks will be done to ensure that best-practices are followed (such as listening to the proper events, etc).
     * Warnings will be output to the console if strict mode is enabled.
     */
    set strict(v: boolean);
    get strict(): boolean;
    /** Whether to register exit handlers. If not, then the application should ensure the threads are aborted on process exit */
    set handleExit(v: RegisterExitHandlers);
    get handleExit(): RegisterExitHandlers;
    /** Destroy a proxy class instance */
    destroy(proxy: ThreadedClass<any>): Promise<void>;
    /** Destroys all proxy instances and closes all threads */
    destroyAll(): Promise<void>;
    /** Returns the number of threads */
    getThreadCount(): number;
    /** Returns memory usage for each thread */
    getThreadsMemoryUsage(): Promise<{
        [childId: string]: MemUsageReport;
    }>;
    onEvent(proxy: ThreadedClass<any>, event: string, cb: Function): {
        stop: () => void;
    };
    /**
     * Restart the thread of the proxy instance
     * @param proxy
     * @param forceRestart If true, will kill the thread and restart it. If false, will only restart the thread if it is already dead.
     */
    restart(proxy: ThreadedClass<any>, forceRestart?: boolean): Promise<void>;
    /**
     * Returns a description of what threading mode the library will use in the current context.
     */
    getThreadMode(): ThreadMode;
}
/**
 * The Child represents a child process, in which the proxy-classes live and run
 */
export interface Child {
    readonly id: string;
    readonly isNamed: boolean;
    readonly pathToWorker: string;
    process: WorkerPlatformBase;
    usage: number;
    instances: {
        [id: string]: ChildInstance;
    };
    methods: {
        [id: string]: {
            methodName: string;
            resolve: (result: any) => void;
            reject: (error: any) => void;
        };
    };
    alive: boolean;
    isClosing: boolean;
    config: ThreadedClassConfig;
    autoRestartFailCount: number;
    autoRestartRetryTimeout: ReturnType<typeof setTimeout> | undefined;
    cmdId: number;
    instanceMessageQueue: {
        [cmdId: string]: InstanceCallbackFunction;
    };
    childMessageQueue: {
        [cmdId: string]: CallbackFunction;
    };
    callbackId: number;
    callbacks: {
        [key: string]: Function;
    };
}
export declare function childName(child: Child): string;
export declare type InstanceCallbackFunction = (instance: ChildInstance, e: Error | string | null, encodedResult?: ArgDefinition) => void;
export declare type InstanceCallbackInitFunction = (instance: ChildInstance, e: Error | string | null, initProps?: InitProps) => boolean;
/**
 * The ChildInstance represents a proxy-instance of a class, running in a child process
 */
export interface ChildInstance {
    readonly id: string;
    readonly proxy: ThreadedClass<any>;
    readonly usage?: number;
    /** When to consider the process is frozen */
    readonly freezeLimit?: number;
    readonly onMessageCallback: (instance: ChildInstance, message: Message.From.Instance.Any) => void;
    readonly pathToModule: string;
    readonly exportName: string;
    readonly constructorArgs: any[];
    readonly config: ThreadedClassConfig;
    initialized: boolean;
    child: Child;
}
export declare class ThreadedClassManagerClassInternal {
    /** Set to true if you want to handle the exiting of child process yourselt */
    handleExit: RegisterExitHandlers;
    private isInitialized;
    private _threadId;
    private _instanceId;
    private _methodId;
    private _children;
    private _pinging;
    debug: boolean;
    strict: boolean;
    /** Pseudo-unique id to identify the parent ThreadedClass (for debugging) */
    private uniqueId;
    /** Two-dimensional map, which maps Proxy -> event -> listener functions */
    private _proxyEventListeners;
    /** Contains a map of listeners, used to wait for a child to have been initialized */
    private _childInitializedListeners;
    findNextAvailableChild(config: ThreadedClassConfig, pathToWorker: string): Child;
    /**
     * Attach a proxy-instance to a child
     * @param child
     * @param proxy
     * @param onInstanceMessage
     */
    attachInstanceToChild(config: ThreadedClassConfig, child: Child, proxy: ThreadedClass<any>, pathToModule: string, exportName: string, constructorArgs: any[], onInstanceMessage: (instance: ChildInstance, message: Message.From.Instance.Any) => void): ChildInstance;
    killProxy(proxy: ThreadedClass<any>): Promise<void>;
    sendMessageToInstance(instance: ChildInstance, messageConstr: Message.To.Instance.AnyConstr, cb?: any | InstanceCallbackFunction | InstanceCallbackInitFunction): void;
    sendMessageToChild(child: Child, messageConstr: Message.To.Child.AnyConstr, cb?: CallbackFunction): void;
    getChildrenCount(): number;
    getMemoryUsage(): Promise<{
        [childId: string]: MemUsageReport;
    }>;
    killAllChildren(): Promise<void>;
    /** Restart the thread of a proxy instance */
    restart(proxy: ThreadedClass<any>, forceRestart?: boolean): Promise<void>;
    restartChild(child: Child, onlyInstances?: ChildInstance[], forceRestart?: boolean): Promise<void>;
    private canRetryRestart;
    sendInit(child: Child, instance: ChildInstance, config: ThreadedClassConfig, cb?: InstanceCallbackInitFunction): void;
    startMonitoringChild(instance: ChildInstance): void;
    doMethod<T>(child: Child, methodName: string, cb: (resolve: (result: T | PromiseLike<T>) => void, reject: (error: any) => void) => void): Promise<T>;
    getChildDescriptor(child: Child): string;
    checkInstance(instance: ChildInstance, errStack: Error): void;
    onProxyEvent(proxy: ThreadedClass<any>, event: string, cb: Function): {
        stop: () => void;
    };
    private _emitProxyEvent;
    /** Called before using internally */
    private _init;
    private _pingChild;
    private _childHasCrashed;
    private clearRestartTimeout;
    private _createFork;
    private _setupChildProcess;
    private _onMessageFromChild;
    private _findFreeChild;
    private killChild;
    private rejectChildMethods;
    /** trace to console.error if debugging is enabled */
    debugLogError(...args: any[]): void;
    /** trace to console.error if debugging is enabled */
    debugLog(...args: any[]): void;
    /** trace to console.error */
    private consoleError;
    /** trace to console.log */
    private consoleLog;
    /** Look up which instance contains a proxy, and return its instanceId */
    private findProxyInstanceOfChild;
}
export declare enum ThreadMode {
    /** Web-workers, in browser */
    WEB_WORKER = "web_worker",
    /** Nothing, Web-workers not supported */
    NOT_SUPPORTED = "not_supported",
    /** Worker threads */
    WORKER_THREADS = "worker_threads",
    /** Child process */
    CHILD_PROCESS = "child_process"
}
export declare const ThreadedClassManagerInternal: ThreadedClassManagerClassInternal;
export declare const ThreadedClassManager: ThreadedClassManagerClass;
