Vo Thanh Thang
Vo Thanh Thang

Reputation: 370

Does cron job block the main process or nodejs will create a worker to do cron task

I am using node-cron to do some heavy tasks (update database) every minute. Does this task use main process to work or nodejs will create some workers to do these taks?

var CronJob = require('cron').CronJob;
new CronJob('0 * * * * *', function() {
  //Update database every minute here
  console.log('Update database every minute');
}, null, true, 'America/Los_Angeles');

Upvotes: 10

Views: 9187

Answers (4)

SNOSeeds
SNOSeeds

Reputation: 176

First, node-cron has the same merits and demerits as Node.js, being a runtime of JavaScript, which happens to be a non-blocking single-threaded language that uses the event loop.

Secondly, to understand the merit part of that fact, note that there is a difference between an asynchronous task and a synchronous task. That difference is about whether the task or code instruction is to run outside your program in case of asynchronous and whether it's to run inside your program in case of synchronous. So, where Node.js shines is that it does not pause your program execution resource (a single thread) when it encounters an instruction that is to run outside your program (an example of which is waiting for results of interacting with a database like in your case), and rather uses the event loop to wait for the response from the external land that handles that task, after which it can process the result according to whatever functionality (callback) you have hooked to run the received result. Until recently, many popular programming languages will always block the program execution resource (a thread your program is using albeit they often have multiple threads) while waiting for an asynchronous task, despite such task's execution being outside of your program. That's why Node.js is highly performant when your application is doing heavy i/o interactions with various external resources, unlike other blocking variants for asynchronous tasks, where their multiple threads get blocked pretty fast as they are not released while waiting for results that are not to be processed by them. Enough said about the plus for Node.js. Next is the demerit of the single-threaded nature of Node.js.

Thirdly, the demerit of the single-threaded nature of Node.js comes from heavy synchronous tasks. These are tasks that need to run inside your program and are CPU intensive, imagine looping through a very long list or rendering or processing high fidelity graphics. Since Node.js has a single thread, any other request in that meanwhile of processing a heavy synchronous task will have to wait till the heavy synchronous task finishes processing. Enough said about the minus for Node.js. Next is the solution to this problem.

Enter worker threads. From Node.js v10.5 upwards, a node app, which is running on a single thread that can be seen as the main thread, is able to orchestrate delegation and reporting of tasks to and from other child threads, each of which is also essentially running an isolated single-threaded JavaScript instance. Thereby, if a CPU-heavy task is encountered, you can make the main thread delegate such a task to a child thread, and thereby make the main thread to be available to service any other request. Next is to clarify if node-cron as a job scheduler uses this feature.

node-cron doesn't use the worker thread functionality of Node.js. In the case of your own job, that is not a problem as your job is asynchronous. However, there is bree.js, which is a very robust Node.js job scheduler that goes on to use the worker threads in Node.js, and I believe you now know that you will need something like that to performantly run heavy synchronous jobs.

Finally, do well to explore worker threads whenever you have heavy synchronous tasks because while Node.js supports worker threads, it won't apply that for you automatically when need be.

Upvotes: 3

Pradeep Vairamani
Pradeep Vairamani

Reputation: 4302

This question has been addressed here: https://github.com/node-cron/node-cron/issues/114

Internally node-cron performs the given function asynchronously, inside a setTimeout. But if inside your function, if you do some block io, as a for, it'll block all your thread.

Upvotes: 1

Orkun
Orkun

Reputation: 7228

Any blocking operation will block the main thread indeed, at least with node-cron.

I have tried with an expressjs app where the cron job attemps to fetch data from web regularly:

// app.js
...

/* Routes */

app.use("/", valueRoutes);

/* Cron Job */

cron.schedule(CRON_EXP, refreshData); // long running asyn operation

export default app;

During the refreshData method execution, the express app is not able to respond to requests.

Upvotes: 6

Cesar Villasana
Cesar Villasana

Reputation: 687

It is supposed to create a worker for you.. It is not well documented in the library docs but: 1) You can see at the dependencies, it depends on node-worker. 2) If the cron job were to be blocking, then the waiting for the cron job to execute (in this case, a minute) would be blocking as well. This is because the main thread will just wait until it has to do it. Which in this case, it will be no cron job because it will be a simple sleep() and then execute.

Although, if you want to be sure, try doing a nodejs main program with a "while true" and inside probably writing something to console. And make a cronjob that every minute it will execute a sleep() command for the time you wish. The expected symptom is that the writing in console should never stop ..

Hope this helps.. Cheers

Upvotes: 1

Related Questions