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

[Debug] Allow to list variables asynchronously #135147

Closed
testforstephen opened this issue Oct 15, 2021 · 27 comments
Closed

[Debug] Allow to list variables asynchronously #135147

testforstephen opened this issue Oct 15, 2021 · 27 comments
Assignees
Labels
debug Debug viewlet, configurations, breakpoints, adapter issues feature-request Request for new features or functionality insiders-released Patch has been released in VS Code Insiders verification-needed Verification of issue is requested verified Verification succeeded
Milestone

Comments

@testforstephen
Copy link

Use Case:

In Java Debugger, we have added some features to display some additional information about object variables. For example, displaying info about the size of a collection, and displaying the toString value of a class that overrides the toString() method. A side effect is that these properties require some extra calculation in the debuggee to get them , and can be slow on some large objects. In particular, getting the toString value of a large object can be very slow. Currently, variable responses must be returned in a single request, and in some bad cases, the user could wait for a long time to get the variables being displayed in Variables view.

image

One idea is to support listing variables asynchronously. For example, in a Variables response, we could first return the basic variable properties and display some placeholders (e.g. loading...) for those that are not yet ready. Once the debugger gets them, use some event (e.g. refreshVariableEvent) to notify the client to refresh a node.

@weinand weinand added debug Debug viewlet, configurations, breakpoints, adapter issues feature-request Request for new features or functionality labels Oct 18, 2021
@weinand weinand added this to the On Deck milestone Oct 18, 2021
@weinand
Copy link
Contributor

weinand commented Oct 18, 2021

This feature is somewhat similar to #134450

@roblourens
Copy link
Member

Kind of related to the way that the variables pane doesn't update when I modify a variable in the debug console, but the runtime might know that it was updated. I think there was a request for that at some point.

@weinand
Copy link
Contributor

weinand commented Nov 16, 2021

@testforstephen the somewhat related request #134450 asks for making additional information available via an explicit UI element and gesture. So a VS Code could show an ellipsis () next to a variable value where additional information is available. Clicking on the ellipsis would load the information (in your case the expensive toString()) with an additional (variables) request.
The advantage of this approach: no new DAP protocol for a variables event needed, and expensive toString() requests are only triggered when the user explicitly asks for them (instead of automatically triggering many expensive toString() requests and discarding their results if the user has already hit the "next" button...)

Would this approach still address your problem?

@weinand weinand added the under-discussion Issue is under discussion for relevance, priority, approach label Nov 16, 2021
@testforstephen
Copy link
Author

Yes, my issue is similar to #134450. The proposal you mentioned seems more feasible and can solve my problem. One concern is how does the user aware of ... is clickable? Maybe we can have some mockup to see how it looks like.

@weinand
Copy link
Contributor

weinand commented Nov 17, 2021

@testforstephen great, then let's first tackle #134450 and if that turns out to be not a good solution for your case, then we can work on "asynchronous variable updates".

@weinand weinand removed the under-discussion Issue is under discussion for relevance, priority, approach label Nov 17, 2021
@weinand
Copy link
Contributor

weinand commented Mar 1, 2022

@testforstephen the February release has a first cut of a "lazy variables" feature.

image

It would be great if you could try this for Java and provide feedback.

What you have to do is explained here.

@testforstephen
Copy link
Author

@weinand Sure, let me play a little. thank you for your excellent work.

@CsCherrYY
Copy link
Contributor

@weinand I just tried the feature, and it works great!👍

And I just notice that if VariablePresentationHint.lazy is set to true, although we have a valid string in the value of the response Variable, it will be ignored, and VS Code will just show an ellipsis.

Screenshot 2022-03-09 180309
for an example, we can calculate StringContains@12 in a short time but for the following part (details in the square and children information) we want to make it lazy. Can we just show

d: StringContains@12 (...)

here, instead of

d: (...)

It would be great to show more thing we can get to the users.

@weinand
Copy link
Contributor

weinand commented Mar 9, 2022

@CsCherrYY yes, your proposal to show the value property and the ellipsis sounds reasonable.

@DanTup @roblourens @connor4312 what do you think?

@DanTup
Copy link
Contributor

DanTup commented Mar 9, 2022

Sounds reasonable to me too. I haven't gotten to testing this out yet, though there's probably some useful info we could show in Dart before evaluating (for example the static type).

I presume this would be optional though, and it's possible to just have the ellipsis too.

@weinand
Copy link
Contributor

weinand commented Mar 9, 2022

@DanTup the value property is not optional (for historical reasons), but its comment already says:

An empty string can be used if no value should be shown in the UI.

@roblourens
Copy link
Member

Screen Shot 2022-03-09 at 10 57 07 AM

The value is shown in the tooltip currently at least. I wonder whether it would be too much noise in cases like js-debug where value can have a lot of text

@weinand
Copy link
Contributor

weinand commented Mar 9, 2022

Yes, showing the getter's source as the value would result in too much noise.
So a DA must make a careful decision what to use as the value when adding the lazy flag.

But since the lazy flag is not the default, DAs have to actively opt-into this feature and they can do the right thing.

@connor4312 what do you think?

@connor4312
Copy link
Member

connor4312 commented Mar 10, 2022

I'm not a fan of the proposal to show the value of the variable as a prefix. As mentioned, DAs have to be very careful not to make the string 'too long'. However, 'too long' is entirely based on the width of the user's sidebar, which is not something the DA will know or should care about. It also breaks up the visual flow: I need to scan to the end of the line to figure out that there's a value to reveal.

Displaying the value as a suffix after (...) would solve this however.

@weinand
Copy link
Contributor

weinand commented Mar 10, 2022

@CsCherrYY @DanTup what do you think about @connor4312's idea to show the value as a suffix?

@roblourens
Copy link
Member

And if it matters, we probably plan to replace the ... with a real button with some icon, too #143602 although I am increasingly getting used to (...).

@testforstephen
Copy link
Author

Mixing (...) between the name and the value is a little weird for me. To simplify the client-side recognition logic, I like to display (...) as a separate UI element. Either a real button or using a different style like below .

image

@roblourens
Copy link
Member

Sorry I don't follow, what is the screenshot showing?

@testforstephen
Copy link
Author

Sorry for not being clear. The variable screenshot is from other IDE, I use it to demo how it might look like to show a (...) after the value part (refer to the look of Collecting data... ). Giving it a different css style can make it more distinguishable.

@CsCherrYY
Copy link
Contributor

hi @weinand , I have another problem when implementing this. Since there are two requests on resolving the lazy variable, I found it's hard for us to distinguish which request is for lazy resolving and which request is for resolving children.

We just used a flag to mark if this variable needs to be lazy resolved. if this flag is true we will first return the lazy value and second return the children.

But if we add something to the watch view or the debug console panel, all the lazy variables in the Variables view will refresh and reset the status to unresolved. We can't keep sync with the correct status of the variables since the server isn't aware of this refresh. How can we response the new request from resolving lazy variables in the Variables view now? Do you have any comments?

@weinand
Copy link
Contributor

weinand commented Mar 23, 2022

@CsCherrYY using state ("a flag") on your backend variable is calling for trouble. Don't do this.

I suggest to introduce an intermediate object instead:

  • when an expensive Java variable needs to be converted into a DAP variable, first create an intermediate object in memory (a "proxy") instead, that "knows" how to do the evaluate on the real Java variable. Then create the DAP variable for it and set the "lazy" flag to true.
  • Later when the user triggers the lazy evaluation, the DA receives another variables request that refers to the intermediate object. Let the intermediate object do the evaluation and return its children as DAP variables.

With this approach no state is needed and sync issues are impossible.

Please note that the "intermediate object" approach was our recommendation already before we introduced "lazy" variables last month. Previously the "intermediate object" was just visible in the UI (which was a bit confusing).
Please see here how the "intermediate object" looks and behaves.

If you want to make sure that your new implementation works in old versions of VS Code (which don't support "lazy" variables), I suggest that you disable the "lazy" flag on the DAP variable and then verify that everything still works fine.

@DanTup
Copy link
Contributor

DanTup commented Mar 23, 2022

@CsCherrYY @DanTup what do you think about @connor4312's idea to show the value as a suffix?

Sorry, I missed this before. I agree that a suffix would look better in the collapsed form:

myDate: (...) DateTime

In the expanded form, does it remain there? eg.:

myDate: [value from child variable] [value from wrapper variable]

@CsCherrYY
Copy link
Contributor

@weinand thanks for the detail clarification and guidance! I'll have a try and verify it

@testforstephen
Copy link
Author

Hey @weinand, we have just released the lazy variables feature in Java Debugger, and want to share some user feedbacks on the lazy variable user experience.

  • The new variable view hides more information than just the toString() value. Cannot see class name any more. This is a reasonable concern, and we have discussed this above.

    Java Debugger Variable View
    Before Before
    After After (not loaded)
  • Since variables are not shown >, users no longer realize that they can expand this variable further.

  • Users want to have a setting to turn off the lazy loading behavior. Consider that lazy loading is not a Java specific feature, can we ask VS Code to provide such a setting?

@weinand
Copy link
Contributor

weinand commented Mar 31, 2022

@testforstephen thanks a lot for trying lazy variables and providing very helpful feedback!

To address items 1+2 I think we should start showing the value of the lazy item as a suffix of the "(...)", e.g.:

foo: (...) CdsEntityBuilder$CdsEntityimpl@30 "Universal.Foo"

After expanding (clicking) the '(...)', both the (...) and the suffix are replaced by the expanded value.
(@DanTup this answers your question)

Item 3 is already planned for April: #144861

In addition, as suggested by @testforstephen above we should use a "separate UI element" (an icon) instead of the "(...)". Please see #143602:

156189419-5d5f99ba-0732-437f-b45e-ce339f96f766

@weinand weinand modified the milestones: On Deck, April 2022 Mar 31, 2022
@roblourens
Copy link
Member

Pushed a change to show the value next to the new icon. I think that is the only issue here that is not covered by another issue.

@roblourens roblourens added the verification-needed Verification of issue is requested label Apr 25, 2022
@roblourens
Copy link
Member

roblourens commented Apr 25, 2022

@connor4312 if you want to make any changes here for js-debug you can do that and verify this

@connor4312 connor4312 added the verified Verification succeeded label Apr 27, 2022
@github-actions github-actions bot locked and limited conversation to collaborators May 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
debug Debug viewlet, configurations, breakpoints, adapter issues feature-request Request for new features or functionality insiders-released Patch has been released in VS Code Insiders verification-needed Verification of issue is requested verified Verification succeeded
Projects
None yet
Development

No branches or pull requests

7 participants
@roblourens @DanTup @weinand @connor4312 @testforstephen @CsCherrYY and others