Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Support child_process runtime #64

Closed
AriPerkkio opened this issue Jul 7, 2023 · 1 comment · Fixed by #65
Closed

Feature: Support child_process runtime #64

AriPerkkio opened this issue Jul 7, 2023 · 1 comment · Fixed by #65
Labels
enhancement New feature or request

Comments

@AriPerkkio
Copy link
Member

AriPerkkio commented Jul 7, 2023

Description

Currently Tinypool can be used to run tasks in node:worker_threads only. However it seems that various Node ecosystem packages are incompatible with worker_threads, e.g. aws-sdk, @prisma/client, bcrypt. Typically the common feature of these packages is that they utilize NodeJS API's through native addons. I guess there is a reason why Jest does not use worker_threads by default.

Add an option to choose between node:worker_threads and node:child_process runtimes.

Constructor

new Tinypool({}) // Defaults to 'worker_threads' for backwards compatibility
new Tinypool({ runtime: 'worker_threads' })
new Tinypool({ runtime: 'child_process' })

In future we might even add support for third party runtimes. These could be for example browser runtimes:

new Tinypool({ runtime: 'tinypool-runtime-browser' })
new Tinypool({ runtime: '@organization/tinypool-runtime-custom' })

Pool methods

There might be times where we don't know which runtime to use when initializing the pool. We'll need to add support for changing the runtime of existing pool.

pool.run()

const pool = new Tinypool({
  runtime: 'worker_threads',
  minThreads: 4,
  maxThreads: 4
})
await pool.run(task) // Runs in `worker_threads`

At this point pool has 4 idle worker_threads. We want to run next task in child_process instead:

await pool.run(task, { runtime: 'child_process' })

Pool notices that runtime does not match with idle workers. It has to pick a worker from pool, terminate it and spawn a new worker with different runtime.

Once task has finished there will be 3 worker_threads and 1 child_process workers idle.

pool.recycleWorkers()

For optimal performance the end-users should be able to change runtime of all workers. This can be useful when they can identify which runtimes their predetermined tasks will need.

const tasks = [...]
const pool = new Tinypool({ runtime: 'worker_threads' })

// Run `worker_thread` tasks first
await Promise.all(tasks.filter(pickWorkerThreadCompatibleTasks).map(t => pool.run(t)))

await pool.recycleWorkers({ runtime: 'child_process' })
// All idle workers will now be `child_process` runtimes

await Promise.all(tasks.filter(pickChildProcessTasks).map(t => pool.run(t)))

Other

This won't be easy task and might require heavy refactoring. If there are some features that require worker_threads, I think we should simply throw or log an error when those are called with different runtime.

Best approach to start this is to create a common interface for runtimes. This interface would hide implementation details of runtimes and provide a simple API for pool to utilize. Same interface would eventually be used by third party runtime implementors.

@AriPerkkio AriPerkkio added the enhancement New feature or request label Jul 7, 2023
@AriPerkkio
Copy link
Member Author

Pool methods

pool.run()

await pool.run(task, { runtime: 'child_process' })

Implementing the runtime changing for a single task seems really difficult. Piscina's codebase wasn't built to support this kind of changes.

I think this part of the feature should be left out for now. Users could still change the runtime using pool.recycleWorkers({ runtime }). That one should be much easier to implement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant