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

Refactor continue events to avoid UI hanging #308

Closed
wants to merge 2 commits into from

Conversation

jonyo
Copy link
Contributor

@jonyo jonyo commented Sep 19, 2018

If you click next or continue and the PHP code is taking a while to run, it seems like the button did not have an effect because the context still shows and it still appears to be paused. The only hint that it worked, is that if you try to interact with the context, or eval any code in the console, it won't work because it has actually continued.

Looking at the docs for the continue, step into, etc. events, they indicate that it should actually send the response right away indicating that the action has started. Then after the action is complete, send the appropriate stop event depending on if it is now stopped on breakpoint etc.

But the way it was before, it did not do this, it waited until the next pause point before sending both the initial response and the one run after it is done. This was causing the UI to hang as described above.

Here is the applicable reference documentation I relied on when making this change:

https://github.com/Microsoft/vscode-debugadapter-node/blob/750f50bc875669fe3cb7594804bcfc6326b27d0e/protocol/src/debugProtocol.ts#L559

The debug adapter first sends the response and then a 'stopped' event (with reason 'step') after the step has completed.

(my emphasis added)

Relates to #307 #301

@codecov
Copy link

codecov bot commented Sep 19, 2018

Codecov Report

Merging #308 into master will increase coverage by 1.21%.
The diff coverage is 17.64%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #308      +/-   ##
==========================================
+ Coverage   70.05%   71.27%   +1.21%     
==========================================
  Files           5        5              
  Lines        1012      992      -20     
  Branches      161      157       -4     
==========================================
- Hits          709      707       -2     
+ Misses        303      285      -18
Impacted Files Coverage Δ
src/phpDebug.ts 69.23% <17.64%> (+2.42%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 047777b...8bbc53f. Read the comment docs.

src/phpDebug.ts Outdated
@@ -279,10 +279,6 @@ class PhpDebugSession extends vscode.DebugSession {
})
connection.on('error', disposeConnection)
connection.on('close', disposeConnection)
connection.on('before-execute-command', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is that event still used at all?

this.sendResponse(response)
this._checkStatus(xdebugResponse)
this._checkStatus(await connection.sendRunCommand())
Copy link
Contributor

Choose a reason for hiding this comment

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

The problem with this is that you are not handling the error anymore. The response to this command is the only chance to report that the run command failed. XDebug doesn't return a response to the continue command unless the command failed or the program stopped again.

If the only way is to send the response straight away, it needs to at least log errors, or only send the response after a timeout.

Copy link
Contributor Author

@jonyo jonyo Sep 21, 2018

Choose a reason for hiding this comment

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

@felixfbecker

If the only way is to send the response straight away, it needs to at least log errors, or only send the response after a timeout.

How I interpreted the docs, I believe that we do need to send the response right away on requests that are running more code as an acknowledgment that it has started. As I understand it (again the docs are vague), it should use sendErrorResponse() only if there is some reason it cannot start the action. The results of the action are sent up the line to vscode in other ways already, these are the different outcomes I can think of:

It looked like the try/catch was specifically for handling when the connection was not found with that threadId, and when that is the case, we now handle it directly by responding with sendErrorResponse(). As far as I could tell it would never throw an exception as part of the call to connection.sendRunCommand(), instead it would either return a response with an error in it (handled by _checkStatus(), or emit an event which the phpDebug is already handling on it's own as noted above.

All vscode needs to know here is that we started running the command, after that point if there is an error we let vscode know about it in other emitted events.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for the late reply. I agree with what you say, but that doesn't change the fact that sendRunCommand() can reject with an exception, and that exception needs to be handled somehow. Even if it is handled async and we send the response before, it needs an error handler that at a minimum needs to send an error log to VS Code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I see what you mean, if the xdebug socket is not writable it will reject so need to catch that.

If you are in agreement about using async calls (with addition of handling the reject error) let me know. If interested I'd be happy to rebase (if possible after a year) or just redo this PR when I have some time.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes that sounds good

src/phpDebug.ts Outdated
@@ -1008,7 +969,6 @@ class PhpDebugSession extends vscode.DebugSession {
this.sendErrorResponse(response, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

This line is not valid anymore because the response has already been sent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, good point. I'll change that part.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@felixfbecker I ended up reverting this part to how it was. Really the docs are rather vague so we are forced to figure out whether we should send immediately or wait. My original thought was to not wait since the response has no information to tell vscode, it is just an acknowledgment.

But now I'm thinking, this is a disconnect response, there is no harm in waiting, especially since it already has timeouts built in.

In addition, this could be a part of a restart request, in which case we do definitely want to wait before telling vscode, I could see a situation where we let vscode know too early and it results in vscode attempting to start a new connection before the old one is done. You would end up with errors about the port already being in use.

tl;dr: No harm in making it work like it did before, and there is potentially a problem by not waiting, so better to be on the safe side since we don't have much direction from the docs.

felixfbecker pushed a commit that referenced this pull request Sep 21, 2018
A debug adapter is not expected to send this event in response to a request that implies that execution continues, e.g. 'launch' or 'continue'.
It is only necessary to send a 'continued' event if there was no previous request that implied this.

Note: there is still the problem that it will seem to "hang" when you continue and the PHP code takes a while to run, #308 will fix that.

Fixes #301
@felixfbecker felixfbecker self-requested a review December 9, 2018 20:59
@nn-hh nn-hh mentioned this pull request Jan 9, 2019
towhidabsar pushed a commit to towhidabsar/vscode-php-debug that referenced this pull request Apr 29, 2019
A debug adapter is not expected to send this event in response to a request that implies that execution continues, e.g. 'launch' or 'continue'.
It is only necessary to send a 'continued' event if there was no previous request that implied this.

Note: there is still the problem that it will seem to "hang" when you continue and the PHP code takes a while to run, xdebug#308 will fix that.

Fixes xdebug#301
@felixfbecker felixfbecker changed the base branch from master to main December 21, 2020 20:20
@zobo
Copy link
Contributor

zobo commented Feb 3, 2021

Already solved by #367.

@zobo zobo closed this Feb 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants