
class ThreadPool {
    #tasks = [];
    #activeTask = 0;
    #maxTasks = 1;

    constructor(maxTasksInPool) {
        this.#maxTasks = maxTasksInPool;
    }

    #runNextTask() {
        if (this.#activeTask >= this.#maxTasks || this.#tasks.length === 0)
            return;
        const activeTask = (this.#tasks.shift());
        this.#activeTask++;
        let taskResult = null;
        try {
            taskResult = activeTask.fnc();
        }
        catch (err) {
            taskResult = Promise.reject(err);
        }
        if (!(taskResult instanceof Promise))
            taskResult = Promise.resolve(activeTask);
        taskResult
            .then(result => {
                let ok = activeTask.ok;
                this.#activeTask--;
                ok(result);
            })
            .catch(err => {
                let ko = activeTask.ko;
                this.#activeTask--;
                ko(err);
            })
            .finally(() => {
                this.#runNextTask();
            });
    };

    pushTask(task) {
        return new Promise((ok, ko) => {
            this.#tasks.push({ fnc: task, ok: ok, ko: ko });
            this.#runNextTask();
        });
    }
}

module.exports = ThreadPool;

