Skip to content

C++ Embedding - HTTP Module + fetch() Doesn't Work Outside node::LoadEnvironment #48760

Open
@Jamie0

Description

@Jamie0

Version

18.16.1

Platform

Darwin 19.6.0 Darwin Kernel Version 19.6.0: Mon Aug 31 22:12:52 PDT 2020; root:xnu-6153.141.2~1/RELEASE_X86_64 x86_64

Subsystem

embedding

What steps will reproduce the bug?

  1. Define a function that includes some use of network API (e.g. fetch or net.Socket.prototype.connect)
  2. In C++, invoke this function e.g. through fn->Call or value->CallAsFunction
  3. Attempt to spin the event loop ( e.g. uv_run(loop, UV_RUN_DEFAULT) ) until uv_loop_alive(loop) == 0 to open the socket

How often does it reproduce? Is there a required condition?

I can reproduce this reliably (see additional information). The I/O operation has to involve network - e.g. await fs.promises.readFile('test.txt') works correctly

What is the expected behavior? Why is that the expected behavior?

The network request should succeed.

What do you see instead?

uv_loop_alive(loop) immediately returns 0, and any subsequent call to uv_loop block and never return.

Additional information

I've tried many different ways of running the event loop and the result is the same - if the network request was started from Call or CallAsFunction, the work never reaches the event loop. If it is scheduled inside node::LoadEnvironment, the request succeeds.

Although I am not familiar with the nodejs internals, I have been working on the assumption something inside node is not scheduling the network request before Call[AsFunction] returns and execution of the context stops. Following the v8 documentation, I've tried executing PerformMicrotaskCheckpoint, FlushForegroundTasks, and DrainTasks before spinning the loop to no avail.

For context, I am attempting to build a nginx module to extend the nginx web server with node modules. Code that reproduces the bug is on the project's repo - https://github.com/Jamie0/nginx-nodejs-module

I also note if testing a net.Socket(), the 'close' callback immediately executes if attempting to use a DNS name rather than an IP address. With fetch, the behaviour is the same regardless of host name.

If this is intended behaviour when using Call[AsFunction], I would be grateful if the documentation could be updated to explain how one can achieve this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    embeddingIssues and PRs related to embedding Node.js in another project.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions