node.jsnode-cron

Will scheduling tasks on a node server block it processing requests?


I have a very simple express server with 1 endpoint listening on a certain port.

I'd like a separate scheduled script to make an API call every 10 minutes and save the data locally (in memory).

When the endpoint on my server is hit, I'd like to serve the locally cached data from memory.

How can I make sure that the scheduled cron job does not ever block the processing of requests coming in i.e. both continue to happen at the same time.

I've read about child processes and worker threads, but I'm not sure if this would be a good use case for it.


Solution

  • JavaScript is single-threaded, so worker threads and forking notwithstanding, every line of JavaScript code that executes blocks other lines of code from executing. Only one can execute at a time. So forgetting about the scheduled job for a moment, in an express server, multiple requests happening concurrently will compete with each other for CPU resources and block each other.

    However, Node.js has asynchronous I/O. A typical request often looks a bit like this:

    1. Receive request and run a little bit of JavaScript code (maybe 1ms).
    2. Query an external REST API (let's say 50ms)
    3. Run a little more JavaScript code and send a response (maybe 1ms).

    In steps 1 and 3, all other requests are blocked from executing JavaScript code. They have to wait until the current request is done executing its code. In step 2 however, other requests are free to execute JavaScript code, one after the other, since the network request is non-blocking.

    I explain all this because it sounds like your scheduled job might go through the same three steps mentioned above. If that's the case, then functionally it's not going to block anything any more than simultaneous requests to the server are already blocking each other, and there's little reason to worry about threading or multi-processing unless your server is under such heavy load that it cannot serve all incoming requests.

    So this is not a good use case for child processes and worker threads unless the scheduled job has different characteristics than I'm assuming (for example if it spends multiple seconds crunching heavy computations in JavaScript, that would noticeably impact request response time when it runs, and might make sense to break out into a separate process or worker thread).