constructor(path, options) {
        super();

        this.options = new WorkerNodesOptions(options);
        this.workerOptions = this.options.getWorkerOptions(path);

        this.workersQueue = new Queue({ sizeLimit: this.options.maxWorkers });
        this.pendingTasksQueue = new Queue();
        this.ongoingTasksQueue = new Queue({ sizeLimit: this.options.maxTasks });

        // setup proxying of target module api
        const makeHandleFor = method => (...args) => {
            if (this.ongoingTasksQueue.isFull()) {
                return Promise.reject(new MaxConcurrentCallsError('Too many concurrent calls (' + this.ongoingTasksQueue.length + ')'));
            }

            return new Promise((resolve, reject) => this.enqueue(new Task({ method, args, resolve, reject })));
        };

        this.callHandlers = {};

        /**
         * This exposes the api of a module that the worker nodes are working on. If the module is a function, you
         * can call this directly. If the module exports multiple functions, you can call them as they were properties
         * of this proxy.
         *
         * @type {Proxy}
         */
        this.call = new Proxy(function () {}, {
            get: (target, property) => {
                let callHandler = this.callHandlers[property];

                if (!callHandler) {
                    callHandler = this.callHandlers[property] = makeHandleFor(property);
                }

                return callHandler;
            },

            apply: (target, thisArg, args) => this.call.__module__(...args)
        });

        this.isTerminationStarted = false;
        this.isTerminated = false;
        this.isReady = new Promise(resolve => {
            const checkReadiness = count => {
                if (count >= this.options.minWorkers) {
                    resolve(true);
                    this.removeListener('workers-ready', checkReadiness);
                }
            };

            this.on('workers-ready', checkReadiness);

            if (this.options.autoStart) {
                if (this.options.lazyStart) {
                    for (let i = 0; i < this.options.minWorkers; i++) this.startWorker();
                } else {
                    while (this.canStartWorker()) this.startWorker();
                }
            }

            checkReadiness(0);
        });

        process.once('exit', () => this.terminate());
    }
@param {String} path - An absolute path to the module that will be run in the workers.
@param {Object} [options] - See [WorkerNodesOptions](#WorkerNodesOptions) for a detailed description.