josdejong / workerpool

Offload tasks to a pool of workers on node.js and in the browser
Apache License 2.0
2.04k stars 148 forks source link

release idle worker #450

Closed lishchgithub closed 2 months ago

lishchgithub commented 2 months ago

Set option as { minWorkers: 2, maxWorkers: 4, maxQueueSize: 10, }, when execute 10 tasks , the workers will be 4, but when all task finished, workpool still keep 4 totalWorkers.

josdejong commented 2 months ago

That is correct.

Why would you want to "release idle workers"?

lishchgithub commented 2 months ago

Because the worker thread will load large memory package, just as 200MB, so I want release it when pool has idle workers.

lishchgithub commented 2 months ago

I have solve this problem with this function:

function releasePool(pool) {
    let stats = pool.stats();
    if (
        stats.totalWorkers > pool.minWorkers &&
        stats.idleWorkers > 0 &&
        !stats.pendingTasks
    ) {
        console.log(`releasePool: ${JSON.stringify(stats)}`);
        let release_workers = pool.workers.slice(
            Math.max(stats.totalWorkers - stats.idleWorkers, pool.minWorkers),
            stats.totalWorkers
        );

        release_workers.forEach((w) => {
            pool._removeWorker(w);
        });
    }
}
josdejong commented 2 months ago

In general, you need to make sure that you have enough memory available for the max number of workers that you configure, so, if you configure maxWorkers:4, and your workers take 200 MB, you need to make sure you always have at least 800 MB available. If you don't have that memory available, the workers can run out of memory and crash. So, even if you (temprorarily) do not use all your workers and want to kill them, you still need to keep enough memory reserved for them when they are needed again. So, you cannot really use the freed memory even if you would release idle workers, right?

If you really want to do this, you can terminate your current pool via pool.terminate(), and create a new workerpool. When terminating a pool, it will finish all running tasks (unless you pass argument force = true).

But again, please do the maths on your system memory.

lishchgithub commented 2 months ago

I will use this with electron app, the app will be keep alive. so I just want minimize the memory usage when worker be idled. Thank you very much.

josdejong commented 2 months ago

Ah, in case of a desktop application it makes sense 👍. I was having a server application in mind.