How to perform async operation on exit

I am trying to perform an asynchronous operation until the completion of my process.

The expression "completed" I mean every possibility of termination:

  • ctrl+c
  • Unable exception
  • Crashes
  • End of code
  • Everything..

As far as I know, the exit event does this, but for synchronous operations.

When reading Nodejs docs, I found a beforeExit event for asynchronous BUT operations:

The 'beforeExit' event is not thrown for conditions that cause an explicit end, such as a call to process.exit() or non-displayed exceptions.

"beforeExit" should not be used as an alternative to the "exit" event, unless the intention is to plan additional work.

Any suggestions?

+12
source share
2 answers

You can intercept signals and perform an asynchronous task before exiting. Something like this will call the terminator () function before exiting (even a JavaScript error in the code):

 process.on('exit', function () { // Do some cleanup such as close db if (db) { db.close(); } }); // catching signals and do something before exit ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT', 'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM' ].forEach(function (sig) { process.on(sig, function () { terminator(sig); console.log('signal: ' + sig); }); }); function terminator(sig) { if (typeof sig === "string") { // call your async task here and then call process.exit() after async task is done myAsyncTaskBeforeExit(function() { console.log('Received %s - terminating server app ...', sig); process.exit(1); }); } console.log('Node server stopped.'); } 

Add details requested in comments:

  • Signals explained in the node documentation , this link refers to standard POSIX signal names
  • Signals must be string. However, I saw others do the check, so there may be some other unexpected signals that I don’t know about. I just want to make sure before calling process.exit (). I believe that verification will not take much time anyway.
  • for db.close (), I think it depends on the driver you are using. Whether synchronization is asynchronous. Even if it is asynchronous and you do not need to do anything after closing db, then everything should be fine, because async db.close () just generates a close event, and the event loop will continue to process it, regardless of whether your server has finished or not.
+10
source

Using the hook beforeExit

The beforeExit event is generated when Node.js clears its event processing loop and has no additional work to do with scheduling. Typically, the Node.js process terminates when work is not scheduled, but a listener registered in the beforeExit event can make asynchronous calls and thereby continue the Node.js.

 process.on('beforeExit', async ()=> { await something() process.exit(0) // if you don't close yourself this will run forever } 
0
source

Source: https://habr.com/ru/post/1012283/


All Articles