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

Port project to N-API #432

Closed
wants to merge 5 commits into from
Closed

Port project to N-API #432

wants to merge 5 commits into from

Conversation

DavidRusso
Copy link

Is there any interest in porting the project from NAN to N-API? If so, here is a working port.

@ghost
Copy link

ghost commented Oct 14, 2020

CLA assistant check
All CLA requirements met.

@Tyriar Tyriar requested review from deepak1556 and Tyriar and removed request for deepak1556 October 30, 2020 23:06
@Tyriar
Copy link
Member

Tyriar commented Oct 30, 2020

@deepak1556 could you check this out when you get a chance?

@Tyriar Tyriar mentioned this pull request Nov 2, 2020
@Eugeny
Copy link
Contributor

Eugeny commented Jan 2, 2021

Tested on all three platforms 👍

@jerch
Copy link
Collaborator

jerch commented Jan 2, 2021

ptsname needs a reentrant replacement to work correctly across multiple workers, otherwise spawing ptys in parallel might report the wrong pty path. Glibc knows a ptsname_r for that case, shims for OSX and FreeBSD can be found here.

@Eugeny
Copy link
Contributor

Eugeny commented Jan 4, 2021

A crash when an Electron renderer process gets reused. Looks like Node is forcefully stopping all AsyncWorkers during cleanup and an OnOK callback in node-pty crashes:

FATAL ERROR: Error::Error napi_create_reference
 1: 0x10ee00815 node::Buffer::New(v8::Isolate*, char*, unsigned long, void (*)(char*, void*), void*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
 2: 0x10ee009b4 node::Buffer::New(v8::Isolate*, char*, unsigned long, void (*)(char*, void*), void*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
 3: 0x10ee00839 node::Buffer::New(v8::Isolate*, char*, unsigned long, void (*)(char*, void*), void*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
 4: 0x10edd9f44 napi_fatal_error [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
 5: 0x114e931ba Napi::Error::Fatal(char const*, char const*) [/Users/eugene/Work/terminus/app/node_modules/@terminus-term/node-pty/build/Release/pty.node]
 6: 0x114e98328 Napi::Error::New(napi_env__*) [/Users/eugene/Work/terminus/app/node_modules/@terminus-term/node-pty/build/Release/pty.node]
 7: 0x114e98dda Napi::Function::Call(std::initializer_list<napi_value__*> const&) const [/Users/eugene/Work/terminus/app/node_modules/@terminus-term/node-pty/build/Release/pty.node]
 8: 0x114e98b68 Napi::FunctionReference::Call(std::initializer_list<napi_value__*> const&) const [/Users/eugene/Work/terminus/app/node_modules/@terminus-term/node-pty/build/Release/pty.node]
 9: 0x114e98614 WaitForExit::OnOK() [/Users/eugene/Work/terminus/app/node_modules/@terminus-term/node-pty/build/Release/pty.node]
10: 0x114e98ea5 Napi::AsyncWorker::OnWorkComplete(Napi::Env, napi_status)::'lambda'()::operator()() const [/Users/eugene/Work/terminus/app/node_modules/@terminus-term/node-pty/build/Release/pty.node]
11: 0x114e97c25 Napi::AsyncWorker::OnWorkComplete(Napi::Env, napi_status) [/Users/eugene/Work/terminus/app/node_modules/@terminus-term/node-pty/build/Release/pty.node]
12: 0x10eddbe86 napi_ref_threadsafe_function [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
13: 0x10c477398 uv_random [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
14: 0x10c47b020 uv_async_send [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
15: 0x10c48c5fc uv_free_interface_addresses [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
16: 0x10c47b497 uv_run [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
17: 0x10edb82c5 node::EmitAsyncDestroy(node::Environment*, node::async_context) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
18: 0x10edb8590 node::EmitAsyncDestroy(node::Environment*, node::async_context) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
19: 0x10ed7d67e node::FreeEnvironment(node::Environment*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
20: 0x10c5e8516 ElectronInitializeICUandStartNode [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
21: 0x10ed19a3d v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
22: 0x10dec22dc v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
23: 0x10dedf006 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
24: 0x10e44ec5a v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
25: 0x10e6e969e v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
26: 0x10e6e9c9c v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
27: 0x10e6f79b3 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
28: 0x10e49b965 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
29: 0x10ed0b643 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
30: 0x10ed221cd v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
31: 0x10ed22096 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
32: 0x10ed0a22a v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
33: 0x10ed01d16 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
34: 0x10c9de0a3 ElectronInitializeICUandStartNode [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
35: 0x10ed0225b v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
36: 0x10d7027af v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
37: 0x10d72e8ff v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
38: 0x10d72cc7f v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
39: 0x10d5992f9 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
40: 0x10d5a694f v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
41: 0x10d5a6560 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
42: 0x10d5d84f0 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
43: 0x10d5d500a v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
44: 0x10d5d7ecf v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
45: 0x7fff20458a0c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ [/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation]
46: 0x7fff20458974 __CFRunLoopDoSource0 [/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation]
47: 0x7fff204586ef __CFRunLoopDoSources0 [/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation]
48: 0x7fff20457121 __CFRunLoopRun [/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation]
49: 0x7fff204566ce CFRunLoopRunSpecific [/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation]
50: 0x7fff211e3fa1 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] [/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation]
51: 0x10d5d89c4 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
52: 0x10d5d7a62 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
53: 0x10d5a6ea1 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
54: 0x10d5855d9 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
55: 0x10ed36368 v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
56: 0x10d1e6b1d v8::internal::SetupIsolateDelegate::SetupHeap(v8::internal::Heap*) [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
57: 0x10ca30f0e ElectronInitializeICUandStartNode [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
58: 0x10ca31412 ElectronInitializeICUandStartNode [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
59: 0x10c48cc08 ElectronMain [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
60: 0x10c42a6e0  [/Users/eugene/Work/terminus/node_modules/electron/dist/Electron.app/Contents/Frameworks/Electron Helper (Renderer).app/Contents/MacOS/Electron Helper (Renderer)]
61: 0x7fff2037b621 start [/usr/lib/system/libdyld.dylib]
62: 0x17 

@Tyriar Tyriar added this to the 0.10.0 milestone Jan 8, 2021
Copy link
Contributor

@deepak1556 deepak1556 left a comment

Choose a reason for hiding this comment

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

@Eugeny the PR doesn't make the module multi-context aware but rather a refactor from NAN to NAPI.

LGTM for api changes.

Copy link
Member

@Tyriar Tyriar left a comment

Choose a reason for hiding this comment

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

I tested this out and it seems to work initially, but when I create a 5th terminal in VS Code it doesn't work, and from that point on I cannot exit VS Code. It happens on both macOS and Windows (I didn't check Linux).

recording (6)

Steps to repro:

  • Setup VS Code dev env
  •  cd node_modules
     rmdir node-pty
     git clone https://github.com/DavidRusso/node-pty
     cd node-pty
     git checkout napi
     yarn
    
  • ./scripts/code.bat (or sh)

Comment on lines +5 to +8
*
* Ported to N-API by Matthew Denninghoff and David Russo
* Reference: https://github.com/nodejs/node-addon-api
*
Copy link
Member

@Tyriar Tyriar Feb 1, 2021

Choose a reason for hiding this comment

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

We can add this to the big files ((con|win)?pty.cc) if you want since this was a lot of effort, but it's a little overkill for the small ones. You'll be in commit history 🙂

Copy link
Author

Choose a reason for hiding this comment

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

Sounds good!

@Eugeny
Copy link
Contributor

Eugeny commented Feb 1, 2021

Same on Linux: Eugeny/tabby#3337

@jerch
Copy link
Collaborator

jerch commented Feb 1, 2021

This may sound disruptive - I think the module should not be moved to the new native API without addressing the underlying bugs it already has (see #85 which reveals serious issues around the blocking semantics). To me it seems more appropriate to rewrite the whole module from scratch with the new API to get rid of those low level issues (and that awkward Socket hack).

@Eugeny
Copy link
Contributor

Eugeny commented Feb 1, 2021

While I strongly agree that #85 is a serious issue, I don't think that it warrants delaying support for upcoming Electron versions once V8 API gets effectively banned.

Even though above makes node-pty unreliable in a context where it's used as "child_process with PTY", IMHO most node-pty end-users are using it for slowly-flowing terminal emulation - although my view might be biased.

@jerch
Copy link
Collaborator

jerch commented Feb 1, 2021

@Eugeny I admit that #85 has been around for ys, still the module is basically broken in this regard. A major API shift always opens the door to also get rid of those buried more serious issues, as you have to touch 80% of the code anyway. Note that it just happens to work for 90% of the module user by accident, because they normally use it with a shell and manage to attach a data handler fast enough. Still it shows nondeterministic behavior at these edges.

@Tyriar Tyriar removed this from the 0.10.0 milestone Feb 2, 2021
Base automatically changed from master to main February 19, 2021 16:56
@Tyriar
Copy link
Member

Tyriar commented Oct 22, 2021

Closing since this change has the remaining pretty big issue #432 (review). We do want to move to NAPI and may be force to eventually depending on Electron (if nan support breaks), that will make sharing binaries across platforms much nicer.

@Tyriar Tyriar closed this Oct 22, 2021
@kkocdko kkocdko mentioned this pull request Dec 4, 2023
5 tasks
deepak1556 added a commit that referenced this pull request Jan 26, 2024
* Port to NAPI

The "5th pty bug" in #432 fixed also.

* Fix help message in pty.cc

* Move NAPI deps to devDependencies in package.json

* Apply most of deepak1556's suggestions

* Fix winpty

* Fix conpty missing CloseHandle

* Use unique_ptr to avoid `goto`s

* Why macos failed?

* fix: ci and minor cleanups

* fix build failed on windows

---------

Co-authored-by: deepak1556 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants