-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[LLDB][Progress-On-Dap] Have indeterminate progress actually send events. #140162
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
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-lldb Author: Jacob Lalonde (Jlalond) ChangesRecently, I got a report how a user 'hung', and come to find out it's actually because DAP is checking percentage, and on non-deterministic events, we will effectively never send a progress event to DAP. Here we short circuit and don't view percentages for DAP messages and solely depend on the DAP 250ms throttle, which is probably still too aggressive, but better than no updates. Full diff: https://github.com/llvm/llvm-project/pull/140162.diff 3 Files Affected:
diff --git a/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py b/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py
index fee63655de0da..c87d2afe36821 100755
--- a/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py
+++ b/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py
@@ -81,7 +81,7 @@ def test(self):
self.verify_progress_events(
expected_title="Progress tester: Initial Indeterminate Detail",
- expected_message="Step 1",
+ expected_message="Step 2",
only_verify_first_update=True,
)
diff --git a/lldb/tools/lldb-dap/ProgressEvent.cpp b/lldb/tools/lldb-dap/ProgressEvent.cpp
index 6a4978c055e51..b6b62efb5f33c 100644
--- a/lldb/tools/lldb-dap/ProgressEvent.cpp
+++ b/lldb/tools/lldb-dap/ProgressEvent.cpp
@@ -77,16 +77,19 @@ ProgressEvent::Create(uint64_t progress_id, std::optional<StringRef> message,
if (event.GetEventType() == progressStart && event.GetEventName().empty())
return std::nullopt;
- if (prev_event && prev_event->EqualsForIDE(event))
+ if (prev_event && prev_event->EqualsForIDE(event, total))
return std::nullopt;
return event;
}
-bool ProgressEvent::EqualsForIDE(const ProgressEvent &other) const {
+bool ProgressEvent::EqualsForIDE(const ProgressEvent &other, uint64_t total) const {
return m_progress_id == other.m_progress_id &&
- m_event_type == other.m_event_type &&
- m_percentage == other.m_percentage;
+ m_event_type == other.m_event_type &&
+ // If we check the percentage of a non-deterministic event
+ // we will basically never send the event, because N+1/Uint64_max
+ // will always be an infinitesimally small change.
+ (total != UINT64_MAX && m_percentage == other.m_percentage);
}
ProgressEventType ProgressEvent::GetEventType() const { return m_event_type; }
diff --git a/lldb/tools/lldb-dap/ProgressEvent.h b/lldb/tools/lldb-dap/ProgressEvent.h
index d1b9b9dd887cd..ab3487c1dbc3d 100644
--- a/lldb/tools/lldb-dap/ProgressEvent.h
+++ b/lldb/tools/lldb-dap/ProgressEvent.h
@@ -54,7 +54,7 @@ class ProgressEvent {
/// \return
/// \b true if two event messages would result in the same event for the
/// IDE, e.g. same rounded percentage.
- bool EqualsForIDE(const ProgressEvent &other) const;
+ bool EqualsForIDE(const ProgressEvent &other, uint64_t total) const;
llvm::StringRef GetEventName() const;
|
m_event_type == other.m_event_type && | ||
m_percentage == other.m_percentage; | ||
m_event_type == other.m_event_type && | ||
// If we check the percentage of a non-deterministic event |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JDevlieghere & @ashgti, thoughts on also making it 500 ms between non-deterministic progress events, or do we think 250 is the best tradeoff of performance to responsiveness?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't m_percentage
a nullopt when the total
is UINT64_MAX? Or is there a logic issue in lines 35-65?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're correct, but then we'd be comparing if null_opt == null_opt
, and no further updates would be sent. I overlooked this when adding the total, we should short circuit and ignore the percentage if percentage is a null opt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But won't they have different event types if its changed? For a non-determinitic progress event, it should only go from m_event_type == progressStart
to m_event_type == progressEnd
, right? If we have 2 starts or 2 ends that feels like the logic got mixed up somewhere else, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First, let me apologize for being overly brief in my explanation. You're correct @ashgti, but now imagine all the updates.
Let's say we're indexing dwarf, you'll get the start, the first update and then the end.
As an extreme hypothetical, if this takes 30 minutes you will have 0 progress actually sent to the progress bar in VSCode resulting in what appears to be a hang of LLDB.
So, for non-deterministic events we want to update for every time window. DAP limits to 250 ms, which I think is fine. I might need to change the equals check now that I spell this out but I hope this explains the intent!
✅ With the latest revision this PR passed the C/C++ code formatter. |
699617e
to
55ee28c
Compare
55ee28c
to
ad616dc
Compare
Recently, I got a report how a user 'hung', and come to find out it's actually because DAP is checking percentage, and on non-deterministic events, we will effectively never send a progress event to DAP. Here we short circuit and don't view percentages for DAP messages and solely depend on the DAP 250ms throttle, which is probably still too aggressive, but better than no updates.