-
Notifications
You must be signed in to change notification settings - Fork 244
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
Host conout socket in a worker #415
Conversation
Conpty can send a final screen update after ClosePseudoConsole which waits for the socket to be drained before continuing. When both the socket draining and closing occurs on the same thread a deadlock can occur which locks up VS Code's UI, the only ways to fix are to close the client or kill the misbehaving conhost instance. This change moves the handling of the conout named pipe to a Worker which bumps the minimum Node version requirement to 12 (10 with a flag). This change may also have positive performance benefits as called out in microsoft/vscode#74620 The worker change also happens for winpty, it seems to work there too. Fixes #375
@Tyriar Does this work with high input data pressure from the slave side? I wonder if it needs some flow control measures to be passed along to avoid turning the worker thread into a memory hog. |
I've validated this,
I don't think flow control is needed as a result of this change because the socket is piped, things are responsive with When trying to validate in VS Code I ran into something I've not yet figured out how to solve; The Electron thing seems like a problem since then Hyper and other Electron-based terminals will need big changes to get it to work, and we can't use web workers unless |
Also validated that this does indeed fix the hang using this repro microsoft/vscode#71966 (comment) |
@Tyriar About electron and worker threads - would it be possible to resort here to an iframe hack? Imho those would run in a separate JS context, but surely the merging back of the data streams will be an issue with that. Idk - is there a specific reason, why plain JS workers are prohibited in electron? |
@jerch we're moving quickly towards having no node integration in the browser window and using an iframe would be going in the opposite direction. node-pty will probably eventually live in another process off of the electron main process (regular node), that solution should work in the long run, at least for VS Code.
Trying to figure that out, this is the exception that's thrown: |
Maybe this helps in the meantime? let win = new BrowserWindow({
webPreferences: {
nodeIntegrationInWorker: true
}
}) Taken from https://www.electronjs.org/docs/tutorial/multithreading. |
@jerch that's just for web workers though. Support both node workers and web workers is one option but it's super ugly, web workers wouldn't be typed and we'd need to loosen security restrictions of the app. |
I see, well seems getting the separation done on pure node level is the only option then. |
Yeah, looking into how difficult it would be to do it the right way. |
@deepak1556 let me know that node workers should be working in Electron 8 (and if they don't it's an unknown bug). |
Ok It's not working on Electron 8 either |
@Tyriar Normal webworkers are funtional in electron render stage? Would it be possible to move the custom logic from a node worker to a normal web worker here? Not sure if webworkers have access to nodejs module stuff though. Quite rough edges still I guess... |
@jerch they would work currently but we would need to enable node integration in them which would be loosening the security restrictions of vscode that we're trying to tighten up, plus it would be super hacky code that is difficult to test without publishing the npm package. I think waiting on Electron to fix it to bring it in is probably the way to go. |
It was closed as wontfix because the renderer will only allow web workers electron/electron#18540 (comment). I guess the way forward is to move the node-pty process out of the renderer process and hope that we get a more direct channel of communication between an arbitrary node process and an electron renderer to avoid the data hopping across multiple processes. |
@Tyriar This move sounds reasonable to not mix the different JS contexts further up (which surely would create lots of tension and bad hacks on low level, a nightmare from a security/isolation perspective). On a sidenote - is it even worth getting this PR properly working, given that you want to reshape |
Do you mean the non-context aware issue #405? The direction with this PR is moving away from using Electron renderers all together which is best practice from a security perspective so I don't think we need to do that anymore. |
Can this be merged and released as 0.10.0-beta17 maybe @Tyriar |
@gpetrov unfortunately not, this won't work in Electron because of electron/electron#18540 (comment) The options are to optionally use a web worker as well which would be a mess to maintain or wait until node-pty moves out of the renderer process in VS Code which is a bit of an involved change microsoft/vscode#74620. |
@Tyriar No problem - I installed your hang_fix branch directly from github and it is running perfectly. No more freezes. We are running on NWJS with the latest Chrome 85 engine so have all the latest node workers support. |
@gpetrov glad to hear it's working out 👍, we'll get either this or a similar fix in for this eventually. |
FYI this is available to pick up in [email protected], I'll be bringing it into VS Code soon |
This brings in microsoft/node-pty#415 which will finally fix the hang issue on Windows with conpty. Performance on Windows should also improve a lot because node-pty is now hosted outside of the cluttered renderer process. Fixes #71966
@Tyriar just FYI, it appears that |
@Eugeny Shouldn't this just be |
@jerch web workers would work (sorry) but this PR explicitly imports Node |
@Eugeny
To me it seems logically not to allow Maybe this needs some clarification from an electron dev, to explain the thread/worker bounderies more clearly. |
They allow Node modules in browser contexts (both in renderer and worker, controlled separately via Does VSCode host |
I think it's time to move it to the main process as it looks like nodeIntegration is discouraged by electron because of the security implications it has. |
@Eugeny Since this is possible - what would need real In general I second @mofux's remark - being able to load native node modules in the browser ctx cries for bad security conditions. Still I understand your hestitation - the additional IPC will have negative perf impact (but thats not that bad if properly prebuffered to reduce event loop pressure, as you can test with our repo demo). The main downside of decoupled |
https://www.electronjs.org/docs/tutorial/multithreading Native nodejs modules inside browser worker threads is NOT recommended. I was under the impression that the problem was related to dynamic native code loading itself not being thread safe. 🤷♂️ I've been using node-pty from the main process (no other threads etc) and sending data to/from the browser process for years. I haven't noticed any big latency problems related to that set up. I do get to side-step all these questions around threading though and that does save a lot of worrying. |
You can follow the linked issues for more details but the summary is:
Maybe this is a big enough of a change to warrant a bump to v1.0.0, we're essentially following semver already. |
Ah yepp, the browser engines have a hard time to deal with tons of small chunks per function call on the event loop. Seems libuv's loop does not suffer that much under these conditions, which should show a remarkable speed gain for this edge case. But - can't |
They probably could, that would be a discussion for the terminal repo. Regardless, conpty updates with windows so we'd need to deal with these smaller chunks anyway. |
Note that this doesn't play nicely with asar currently: microsoft/vscode#116373 (comment) |
This brings in microsoft/node-pty#415 which will finally fix the hang issue on Windows with conpty. Performance on Windows should also improve a lot because node-pty is now hosted outside of the cluttered renderer process. Fixes microsoft#71966
Conpty can send a final screen update after ClosePseudoConsole which waits for the socket
to be drained before continuing. When both the socket draining and closing occurs on the
same thread a deadlock can occur which locks up VS Code's UI, the only ways to fix are
to close the client or kill the misbehaving conhost instance. This change moves the
handling of the conout named pipe to a Worker which bumps the minimum Node version
requirement to 12 (10 with a flag). This change may also have positive performance
benefits as called out in microsoft/vscode#74620
The worker change also happens for winpty, it seems to work there too.
Fixes #375