laverdet / node-fibers

Fiber/coroutine support for v8 and node.
MIT License
3.56k stars 224 forks source link

node process blocks if you use fiber in proces.once('exit', ...) callback #453

Closed mitar closed 3 years ago

mitar commented 3 years ago

I know the project is not maintained anymore, but I just want to document this for anyone else who might spend time debugging this. I use fibers through Meteor and in Meteor I had the following code:

const connectionIds = new Set();

Meteor.onConnection((connection) => {
  connectionIds.add(connection.id);

  connection.onClose(() => {
    SomeDocuments.remove({
      connectionId: connection.id,
    });
    connectionIds.delete(connection.id);
  });
});

const connectionsCleanup = Meteor.bindEnvironment(() => {
  for (const connectionId of connectionIds) {
    SomeDocuments.remove({
      connectionId,
    });
    connectionIds.delete(connectionId);
  }
});

process.once('exit', connectionsCleanup);
process.once('SIGTERM', connectionsCleanup);
process.once('SIGINT', connectionsCleanup);

SomeDocuments.remove does some database requests (inside a fiber).

With Meteor 1.11.1 (which uses node v12.18.4) this makes the whole process block and never exit. It is documented that:

There is no way to prevent the exiting of the event loop at this point, and once all 'exit' listeners have finished running the Node.js process will terminate.

And:

Listener functions must only perform synchronous operations. The Node.js process will exit immediately after calling the 'exit' event listeners causing any additional work still queued in the event loop to be abandoned.

It seems running fibers in there messes up with things. So do not do it.