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

Locks in VSCode debug mode on import #22

Open
TonyGravagno opened this issue Aug 29, 2024 · 6 comments
Open

Locks in VSCode debug mode on import #22

TonyGravagno opened this issue Aug 29, 2024 · 6 comments

Comments

@TonyGravagno
Copy link

v0.5.2 - When a Typescript (ESM Node) project is run in VSCode in debug mode, the initalization process gets to the import of this package and stops:

import synchronizedPrettier from "@prettier/sync";

The return stack shows the Atomic.wait seems to be locked, and when locked on itself (?) there is some conflict with debug mode.
There is no issue when not running in debug mode.

const status = Atomics.wait(semaphore, 0, 0, timeout) ref

The first issue is that the semaphore can't be locked. But there is a second issue, that when this happens there is no timeout, so the process does not terminate.

return this.#sendActionToWorker(this.#worker, action, payload) ref

That line does not include a 'timeout' parameter which is defined on that function:

#sendActionToWorker(worker, action, payload, timeout) { ref

This results in 'timeout' being undefined, resulting in an unterminating lock.

While I'd normally request/recommend a default timeout setting with an option override, that won't help in this case of the import statement locking.

Please consider both of these issues in the resolution(s) of this challenge.

I know this timeout situation is a topic for make-synchronized, but because the author is the same I'm reporting it here. I will create a new issue there on request. Because I'm not familiar with these projects I don't know if I'm not using them correctly and either or both of these issues may not be "bugs" - so I don't want to create another ticket if there is no real problem.

Thanks.

@fisker
Copy link
Member

fisker commented Aug 30, 2024

The first issue is that the semaphore can't be locked.

I can't understand what this mean.

But there is a second issue, that when this happens there is no timeout, so the process does not terminate.

Expected, when worker job is done, it will notify the main thread.

@TonyGravagno
Copy link
Author

Yes, my original text was incorrect. I am rephrasing the issue:

This is my code:

import * as prettier from "prettier";
import makeSynchronized from "make-synchronized";
export default makeSynchronized(this, async function formatByPrettier(str: string) {
	return await prettier.format(str, {
		parser: "babel-ts",
	});
});

It is called like this:

const formatted = await formatByPrettier(rawCode);

( That is not the exact code, which is nested inside other code. If necessary I will create an isolated case and attach it here. )

When that is run in VSCode from a script that executes tsx, not in debug mode, it runs correctly. The code is beautified by Prettier, and control returns to the calling code above.

When that is run in VSCode in debug mode, the semaphore locks and does not release. VSCode debug shows the Atomics.wait call at the top of the stack.
Maybe the worker process is running on another thread and is not finishing.
Maybe the worker process ( prettier ) is CJS and we cannot one-step through it when debugging ESM, but the UI doesn't show that.

I don't know what's happening. I'm just telling you what happens when I execute your prettier-synchronized code which calls to your make-synchronized code.

I hope that is helpful.

@TonyGravagno
Copy link
Author

when this happens there is no timeout, so the process does not terminate.

Expected, when worker job is done, it will notify the main thread.

It is your worker process @prettier/sync that is not finishing.
The process hangs on import synchronizedPrettier from "@prettier/sync";.
We (users of your code) can't control that, and we cannot add a timeout there.

The reason for the timeout option in your make-synchronized code is to allow a process to escape if the worker does not exit. In your prettier-synchronized code, you made a choice not to use that. So your code hangs your code.

I am suggesting that you add a timeout and maybe throw an exception if the worker does not complete:
return this.#sendActionToWorker(this.#worker, action, payload) // << here

That will not fix the problem with the code hanging in the debugger, but it will allow the code to gracefully exit whenever that situation exists.

Thank you.

@fisker
Copy link
Member

fisker commented Aug 30, 2024

I'm not sure what happened either, the timeout in make-synchronized was designed to catch worker initialize error. I don't think it's a good idea to add timeout to the actual job, since there is nothing wrong with running a program costs 1 hour.

Currently the "timeout" only works in development (make-synchronized's unbundled code, nothing related to VSCode's debug mode).

My guess is something wrong when initializing the worker, unfortunately, we can't add "timeout" for worker initialization either, see fisker/make-synchronized#17 and nodejs/node#51679

@TonyGravagno
Copy link
Author

I understand, and I thank you for your time on this.

@maxpatiiuk
Copy link

I am able to reproduce this issue consistently in a regular Chrome Debugger (not VS Code).

In my case, prettier-synchronized is imported via a dependency of mind, locking down my debugger.

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

No branches or pull requests

3 participants