47ng/fastify-cron

Allow running crons in worker threads

franky47 opened this issue ยท 7 comments

This could make it tricky to implement such cron tasks, as worker threads have a different execution context and may not do as much as main-threaded tasks, but it would be a nice option for CPU-intensive tasks.

Documentation

https://nodejs.org/api/worker_threads.html

Packages & Third-Party Solutions

I can work on this

Great! How would you go about it?

I'm more in favor of using threads.js than the other 3 purely because of its (subjectively) straightforward APIs.

We can add a flag like useBackgroundWorkers that will only accept onTick functions that are enclosed in a threads.js expose function and then through the Worker API from threads.js execute them. Unfortunately, that means each function enclosed in an expose will have to be on a separate file, but other then that there's no issue.

We can either install threads.js manually, or we can have it as a registered fastify plugin that we require whenever the useBackgroundWorkers flag is true.

I'm fine with workers having to be declared in separate files, it's the same for web workers.

Is the flag necessary? Could we detect somehow that the onTick function is wrapped automatically? That would just be a nice-to-have though, I'm also happy with a flag.

Regarding dependencies, I'd rather leave threads.js as a peer dependency (ie: not bundle it). I'm not sure it needs to go through the Fastify plugin wrapping, though I guess it depends if/how consumers of this package already use threads.js.

I guess a workaround we can do is have them give the path of the file that houses the function that must be executed on a worker_thread, detect which lib they have installed (of the few we support) and then run it.

Some implementations might have differences in how they spawn a worker, pass data and shutdown a working thread so we might have to create some sort of interface that abstracts whatever lib is detected.

Up to you if you want to support multiple multithreading libraries, but I like the idea of a common interface (and have separate packages that implement them, so we don't need peer dependencies).

Regarding data transfer, I'd wager to only do a one way main thread -> worker thread when we pass the Fastify instance, as we do as the argument of the cron callback in the single-threaded version. Not sure how the multithreading would impact references and things changing on the main thread (eg: changing the value of a property on the Fastify instance in a worker thread while there are things reading the value on request handlers).

Apologies for the late reply.

Sounds good, will fork it and push a PR when ready :)