nodejs / node-addon-api

Module for using Node-API from C++
MIT License
2.12k stars 461 forks source link

AsyncProgressQueueWorker hangs on elements more than two #1539

Closed redplc closed 1 month ago

redplc commented 1 month ago

I wrote a program to detect changes in the GPIO on the Raspberry Pi and to call a callback when a change occurs. If I set up more than two watches, node.js hangs. The function poll_gpio(event) waits for a change in the GPIO and return true for change and false for stop worker. What could be the cause of this?

KevinEady commented 1 month ago

Hi @redplc ,

AsyncWorkers are backed by the libuv's uv_work_t with works on a thread pool:

Its default size is 4, but it can be changed at startup time by setting the UV_THREADPOOL_SIZE environment variable to any value (the absolute maximum is 1024).

You can try changing the environmental variable and see if you get any change in results. Not sure why you're limited to two if the default is four? Maybe there are additional libuv workers running?

I would change your architecture to use an std::thread with a thread-safe function. There are a few ways depending on your needs. Seems like you'd create a thread for each GPIO poll (since that blocks), but then either

  1. Create a new thread-safe function for each thread, or
  2. Create a single thread-safe function on addon initialization and share with each thread.

Question: how do you plan on interrupting the polling block?

Hope this helps!

iiot2k commented 1 month ago

Hello Kevin, Thank you for your suggestion and for developing node-addon-api. I fell into the UV_THREADPOOL_SIZE trap again. The poll function is called in the poll_gpio function. I use eventfd elements for the interruption. If you want, I can send you the code. I'll probably have to solve the problem differently now.

Viele Grüße aus Bremen Derya

iiot2k commented 1 month ago

Solved with thread safe function. Thanks to Kevin and everyone who helped. Can be closed.

redplc commented 1 month ago

Closed