X Tutup
The Wayback Machine - https://web.archive.org/web/20220405131611/https://github.com/nodejs/node-addon-api/issues/1087
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

Electron addon: Napi::AsyncWorker does not work #1087

Open
pirroman opened this issue Oct 6, 2021 · 14 comments
Open

Electron addon: Napi::AsyncWorker does not work #1087

pirroman opened this issue Oct 6, 2021 · 14 comments
Labels

Comments

@pirroman
Copy link

@pirroman pirroman commented Oct 6, 2021

Hello!
I am trying to migrate native module for electron application from nan to napi using addon-node-api wrapper. I am facing a problem with AsyncWorker. Overridden Execute works fine and gets results, but OnOK is never called. Under debugging I realized that the OnAsyncWorkComplete callback is never called. I downloaded the examples (https://github.com/nodejs/node-addon-examples), built a napi-asyncworker-example for electron and got the same result. If you build under node and run on it, everything works fine.

I've tried electron 15.1.1, 15.1.0, 14.1.0

$ npm install

> napi-asyncworker-example@1.0.0 install
> node-gyp rebuild

gyp info it worked if it ends with ok
gyp info using node-gyp@8.2.0
gyp info using node@14.18.0 | win32 | x64
gyp info find Python using Python version 3.9.7 found at "C:\Users\roman\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\python.exe"
gyp info find VS using VS2017 (15.9.28307.1525) found at:
gyp info find VS "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise"
gyp info find VS run with --verbose for detailed information
gyp info spawn C:\Users\roman\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\python.exe
gyp info spawn args [
gyp info spawn args   'C:\\workspace\\node-addon-examples\\napi-asyncworker-example\\node-addon-api\\node_modules\\node-gyp\\gyp\\gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'msvs',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\workspace\\node-addon-examples\\napi-asyncworker-example\\node-addon-api\\build\\config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\workspace\\node-addon-examples\\napi-asyncworker-example\\node-addon-api\\node_modules\\node-gyp\\addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   'C:\\Users\\roman\\AppData\\Local\\node-gyp\\Cache\\14.18.0\\include\\node\\common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=C:\\Users\\roman\\AppData\\Local\\node-gyp\\Cache\\14.18.0',
gyp info spawn args   '-Dnode_gyp_dir=C:\\workspace\\node-addon-examples\\napi-asyncworker-example\\node-addon-api\\node_modules\\node-gyp',
gyp info spawn args   '-Dnode_lib_file=C:\\\\Users\\\\roman\\\\AppData\\\\Local\\\\node-gyp\\\\Cache\\\\14.18.0\\\\<(target_arch)\\\\node.lib',
gyp info spawn args   '-Dmodule_root_dir=C:\\workspace\\node-addon-examples\\napi-asyncworker-example\\node-addon-api',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'C:\\workspace\\node-addon-examples\\napi-asyncworker-example\\node-addon-api\\build',
gyp info spawn args   '-Goutput_dir=.'
gyp info spawn args ]
gyp info spawn C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe
gyp info spawn args [
gyp info spawn args   'build/binding.sln',
gyp info spawn args   '/clp:Verbosity=minimal',
gyp info spawn args   '/nologo',
gyp info spawn args   '/p:Configuration=Release;Platform=x64'
gyp info spawn args ]
Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
  nothing.c
  win_delay_load_hook.cc
  nothing.vcxproj -> C:\workspace\node-addon-examples\napi-asyncworker-example\node-addon-api\build\Release\\nothing.lib
  RunSimpleAsyncWorker.cc
  SimpleAsyncWorker.cc
  win_delay_load_hook.cc
     Creating library C:\workspace\node-addon-examples\napi-asyncworker-example\node-addon-api\build\Release\napi-asyncworker-example-native.lib and object C:\workspace\node-addon-examples\napi-asyncworker-example\node-addon-api\build\Release\napi-asyncworker-example-native.exp
  Generating code
  All 312 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
  Finished generating code
  napi-asyncworker-example-native.vcxproj -> C:\workspace\node-addon-examples\napi-asyncworker-example\node-addon-api\build\Release\\napi-asyncworker-example-native.node
gyp info ok

up to date in 8s

38 packages are looking for funding
  run `npm fund` for details

roman@pirogov MINGW64 /c/workspace/node-addon-examples/napi-asyncworker-example/node-addon-api (main)
$ ./node_modules/.bin/electron-rebuild
⠏ Building module: node-addon-api, Completed: 0Building the projects in this solution one at a time. To enable parallel build, please add the "-m" switch.
⠧ Building module: node-addon-api, Completed: 0  nothing.c
⠙ Building module: node-addon-api, Completed: 0  win_delay_load_hook.cc
⠦ Building module: node-addon-api, Completed: 0  nothing.vcxproj -> C:\workspace\node-addon-examples\napi-asyncworker-example\node-addon-api\build\Release\\nothing.lib
⠏ Building module: node-addon-api, Completed: 0  RunSimpleAsyncWorker.cc
⠦ Building module: node-addon-api, Completed: 0  SimpleAsyncWorker.cc
⠼ Building module: node-addon-api, Completed: 0  win_delay_load_hook.cc
⠏ Building module: node-addon-api, Completed: 0     Creating library C:\workspace\node-addon-examples\napi-asyncworker-example\node-addon-api\build\Release\napi-asyncworker-example-native.lib and object C:\workspace\node-addon-examples\napi-asyncworker-example\node-addon-api\build\Release\napi-asyncworker-example-native.exp
  Generating code
  Previous IPDB not found, fall back to full compilation.
⠙ Building module: node-addon-api, Completed: 0  All 325 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
  Finished generating code
⠼ Building module: node-addon-api, Completed: 0  napi-asyncworker-example-native.vcxproj -> C:\workspace\node-addon-examples\napi-asyncworker-example\node-addon-api\build\Release\\napi-asyncworker-example-native.node
✔ Rebuild Complete

roman@pirogov MINGW64 /c/workspace/node-addon-examples/napi-asyncworker-example/node-addon-api (main)
$ ./node_modules/electron-mocha/bin/electron-mocha

runSimpleAsyncWorker returned 'SimpleAsyncWorker for 2 seconds queued.'.
runSimpleAsyncWorker returned 'SimpleAsyncWorker for 4 seconds queued.'.
runSimpleAsyncWorker returned 'SimpleAsyncWorker for 8 seconds queued.'.


  0 passing (0ms)
@mithusingh32
Copy link

@mithusingh32 mithusingh32 commented Oct 6, 2021

I'm having no issues w/ AsyncWorker w/ ipcMain calling my addon.
But I am using cmake-js instead of gpy.

Could you post the code you're using?

@pirroman
Copy link
Author

@pirroman pirroman commented Oct 6, 2021

@mithusingh32 I reproduced it on https://github.com/nodejs/node-addon-examples/tree/main/napi-asyncworker-example/node-addon-api. Just added electron, electron-rebuild, electron-mocha, and ran the following commands.

npm install
./node_modules/.bin/electron-rebuild
./node_modules/electron-mocha/bin/electron-mocha

@pirroman
Copy link
Author

@pirroman pirroman commented Oct 6, 2021

I also tried it with the updated node-addon-api 4.2.0, it didn't help.

@mithusingh32
Copy link

@mithusingh32 mithusingh32 commented Oct 6, 2021

The log you provided, is that when you're seeing the issue or when its working?

Because the

runSimpleAsyncWorker returned 'SimpleAsyncWorker for 2 seconds queued.'.
runSimpleAsyncWorker returned 'SimpleAsyncWorker for 4 seconds queued.'.
runSimpleAsyncWorker returned 'SimpleAsyncWorker for 8 seconds queued.'.

makes me think that AsyncWorker is working.

@pirroman
Copy link
Author

@pirroman pirroman commented Oct 6, 2021

@mithusingh32 No, in the example these are synchronous responses of runSimpleAsyncWorker, also there should have been an asynchronous responses through the callback. It should have worked like this:

runSimpleAsyncWorker returned 'SimpleAsyncWorker for 2 seconds queued.'.
runSimpleAsyncWorker returned 'SimpleAsyncWorker for 4 seconds queued.'.
runSimpleAsyncWorker returned 'SimpleAsyncWorker for 8 seconds queued.'.
SimpleAsyncWorker returned 'SimpleAsyncWorker returning after 'working' 2 seconds.'.
SimpleAsyncWorker returned an error:  [Error: Oops! Failed after 'working' 4 seconds.]
SimpleAsyncWorker returned 'SimpleAsyncWorker returning after 'working' 8 seconds.'.

@mithusingh32
Copy link

@mithusingh32 mithusingh32 commented Oct 6, 2021

Weird.
How are you calling the code on electron?

@pirroman
Copy link
Author

@pirroman pirroman commented Oct 7, 2021

npm install
npm install --save-dev electron
npm install --save-dev electron-mocha
npm install --save-dev electron-rebuild
./node_modules/.bin/electron-rebuild
./node_modules/electron-mocha/bin/electron-mocha

@mithusingh32
Copy link

@mithusingh32 mithusingh32 commented Oct 8, 2021

I mean the actual method call within your app.

@pirroman
Copy link
Author

@pirroman pirroman commented Oct 11, 2021

I don't really understand the question. I have the addon written in C++ which has an api that looks exactly like the runSimpleAsyncWorker method from the example, this addon is used in the electron application. I use electron-mocha to run tests of the api.

I also found out that AsyncWorker doesn't work since electron version 8.5.2.

@mhdawson
Copy link
Member

@mhdawson mhdawson commented Oct 13, 2021

@codebytere can you comment if there is anything on the electron side that might explain why it does not work in electron versus working in Node.js itself?

@codebytere
Copy link
Member

@codebytere codebytere commented Oct 14, 2021

If i'm understanding right and this is running in the renderer process, it's the case that we integrate the event loop from Node.js into that of Chromium, so there are subtle bugs like this that can arise from time to time. i'll try to see what's going on with it when i have some time!

@FLevent29
Copy link

@FLevent29 FLevent29 commented Dec 17, 2021

I just ran into this issue as well. I am using electron 16.0.4.0 on Windows. For me the Napi::AsyncWorker seems to work just fine, but when I try to stop it from BrowserWindow this.mainWindow.on('close' async () => { ... }) or any other event that handles things before quitting, I get exit code -1073740791 (0xC0000409).

My Napi::AsyncWorker class uses a promise so I can tell when it's done. If I await that promise when quitting, it always exits with -1073740791 (0xC0000409). If I don't await that promise, sometimes everything seems to get handled correctly and my electron app exits with code 0. It usually exits properly if I close the app a little faster (AsyncWorker is still guaranteed started and working at this point). In Windows Event Viewer I get these Faulting application electron.exe error logs.

Is there any way I can detect when electron will quit from Node.js side and run code there? If I manually stop the worker via interacting in a specific way with my app, quitting doesn't result in any crash.

@FLevent29
Copy link

@FLevent29 FLevent29 commented Dec 18, 2021

Never mind figured it out.

this.exitEvent.on('exit', async () => {
  if (!this.reader.isStopped) await this.reader.Stop();
  app.quit();
});

this.mainWindow.once('close', (event) => {
  event.preventDefault();
  this.exitEvent.emit('exit');
  return undefined;
});

It might not cover all the possible exit scenarios, but it will do for now for my use case. I might make an example later of how I use Napi::AsyncWorker and Napi::ThreadSafeFunction for my specific use case, with examples of how it crashes.

@github-actions
Copy link

@github-actions github-actions bot commented Mar 19, 2022

This issue is stale because it has been open many days with no activity. It will be closed soon unless the stale label is removed or a comment is made.

@github-actions github-actions bot added the stale label Mar 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants
X Tutup