Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: fix beforeExit not working with -e #8821

Merged
merged 1 commit into from
Oct 24, 2016
Merged

Conversation

bnoordhuis
Copy link
Member

Commit 93a44d5 ("src: fix deferred events not working with -e") defers
evaluation of the script to the next tick.

A side effect of that change is that 'beforeExit' listeners run before
the actual script. 'beforeExit' is emitted when the event loop is
empty but process.nextTick() does not ref the event loop.

Fix that by using setImmediate(). Because it is implemented in terms
of a uv_check_t handle, it interacts with the event loop properly.

Fixes: #8534

R=@Fishrock123

@nodejs-github-bot nodejs-github-bot added the lib / src Issues and PRs related to general changes in the lib or src directory. label Sep 28, 2016
@Fishrock123
Copy link
Contributor

patch LGTM, but isn't there still a larger issue that this is necessary?

That is, normal modules don't seem to need this, so why does -e?

@Fishrock123 Fishrock123 added the process Issues and PRs related to the process subsystem. label Sep 28, 2016
Copy link
Contributor

@Fishrock123 Fishrock123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imyller
Copy link
Member

imyller commented Oct 2, 2016

@bnoordhuis
Copy link
Member Author

@nodejs/platform-windows Any ideas on why the test times out on Windows? Example: https://ci.nodejs.org/job/node-test-binary-windows/4154/RUN_SUBSET=1,VS_VERSION=vcbt2015,label=win10/console

@joaocgreis
Copy link
Member

Investigated, but this was not easy as it first seemed to be. The test hangs in a live loop printing beforeExit to stdout. Apparently it's an unrelated issue, opened #9067 with my findings.

@joaocgreis
Copy link
Member

As shown in #9067 , using console.log in beforeExit creates a loop. @bnoordhuis perhaps change the test to something like

  const script = `
      var beforeExitCalled = false;
      process.on("beforeExit", () => {beforeExitCalled = true});
      process.on("exit", () => {if(beforeExitCalled) console.log("ok")});
  `;

(This seems to work on Windows: fails without and passes with the change on this PR.)

@bnoordhuis
Copy link
Member Author

Aw, and I even commented on that issue. I must have been having a brain boo boo that day.

Thanks for the pointer. Rebased and updated, PTAL. I switched the beforeExit listener from .on() to .once().

CI: https://ci.nodejs.org/job/node-test-pull-request/4546/

@bnoordhuis
Copy link
Member Author

Green! (Well, yellow.) @cjihrig @Fishrock123 Still LGTY?

normal modules don't seem to need this, so why does -e?

The module system does it too, see Module.runMain(). The equivalent for -e would be this:

diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js
index 8b8d066..e778cb4 100644
--- a/lib/internal/bootstrap_node.js
+++ b/lib/internal/bootstrap_node.js
@@ -338,13 +338,9 @@
                    'return require("vm").runInThisContext(' +
                    `${JSON.stringify(body)}, { filename: ` +
                    `${JSON.stringify(name)}, displayErrors: true });\n`;
-    // Defer evaluation for a tick.  This is a workaround for deferred
-    // events not firing when evaluating scripts from the command line,
-    // see https://github.com/nodejs/node/issues/1600.
-    process.nextTick(function() {
-      const result = module._compile(script, `${name}-wrapper`);
-      if (process._print_eval) console.log(result);
-    });
+    const result = module._compile(script, `${name}-wrapper`);
+    if (process._print_eval) console.log(result);
+    process._tickCallback();
   }

   // Load preload modules

setImmediate() and process._tickCallback() are functionally identical here as far as I can tell

@cjihrig
Copy link
Contributor

cjihrig commented Oct 17, 2016

Not sure if the template string in the test should be indented 2 or 4 spaces, but yes, still LGTM.

@rvagg rvagg force-pushed the master branch 2 times, most recently from c133999 to 83c7a88 Compare October 18, 2016 17:02
Commit 93a44d5 ("src: fix deferred events not working with -e") defers
evaluation of the script to the next tick.

A side effect of that change is that 'beforeExit' listeners run before
the actual script.  'beforeExit' is emitted when the event loop is
empty but process.nextTick() does not ref the event loop.

Fix that by using setImmediate().  Because it is implemented in terms
of a uv_check_t handle, it interacts with the event loop properly.

Fixes: nodejs#8534
PR-URL: nodejs#8821
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
@bnoordhuis
Copy link
Member Author

Not sure if the template string in the test should be indented 2 or 4 spaces

I see both styles in the code base and the linter isn't complaining so I decided to leave it as-is.

evanlucas pushed a commit that referenced this pull request Nov 2, 2016
Commit 93a44d5 ("src: fix deferred events not working with -e") defers
evaluation of the script to the next tick.

A side effect of that change is that 'beforeExit' listeners run before
the actual script.  'beforeExit' is emitted when the event loop is
empty but process.nextTick() does not ref the event loop.

Fix that by using setImmediate().  Because it is implemented in terms
of a uv_check_t handle, it interacts with the event loop properly.

Fixes: #8534
PR-URL: #8821
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
MylesBorins pushed a commit that referenced this pull request Nov 18, 2016
Commit 93a44d5 ("src: fix deferred events not working with -e") defers
evaluation of the script to the next tick.

A side effect of that change is that 'beforeExit' listeners run before
the actual script.  'beforeExit' is emitted when the event loop is
empty but process.nextTick() does not ref the event loop.

Fix that by using setImmediate().  Because it is implemented in terms
of a uv_check_t handle, it interacts with the event loop properly.

Fixes: #8534
PR-URL: #8821
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
MylesBorins pushed a commit to MylesBorins/node that referenced this pull request Nov 18, 2016
Commit 93a44d5 ("src: fix deferred events not working with -e") defers
evaluation of the script to the next tick.

A side effect of that change is that 'beforeExit' listeners run before
the actual script.  'beforeExit' is emitted when the event loop is
empty but process.nextTick() does not ref the event loop.

Fix that by using setImmediate().  Because it is implemented in terms
of a uv_check_t handle, it interacts with the event loop properly.

Ref: nodejs#9680
Fixes: nodejs#8534
PR-URL: nodejs#8821
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
MylesBorins pushed a commit that referenced this pull request Nov 19, 2016
Commit 93a44d5 ("src: fix deferred events not working with -e") defers
evaluation of the script to the next tick.

A side effect of that change is that 'beforeExit' listeners run before
the actual script.  'beforeExit' is emitted when the event loop is
empty but process.nextTick() does not ref the event loop.

Fix that by using setImmediate().  Because it is implemented in terms
of a uv_check_t handle, it interacts with the event loop properly.

Fixes: #8534
PR-URL: #8821
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
@MylesBorins MylesBorins mentioned this pull request Nov 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lib / src Issues and PRs related to general changes in the lib or src directory. process Issues and PRs related to the process subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Impossible to listen to beforeExit in single-tick --eval
7 participants