-
Notifications
You must be signed in to change notification settings - Fork 324
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
"flutter.setSubscriptions" call never forgets a file (aka will ask about an ever growing number of files) #7980
Comments
/cc @jwren |
…ening new files This benchmark simulates the current bug at flutter/flutter-intellij#7980 Comparing this benchmark across dart versions also reveals something interesting, here run on the "ImportChain" type with 100 files: Comparing 3.5.4 with 3.6.2 ``` Initial analysis: -2.5724% +/- 1.5022% (-0.16 +/- 0.10) (6.35 -> 6.19) Completion after open of new file: -1.4714% +/- 1.0334% (-0.04 +/- 0.03) (2.92 -> 2.87) peak virtual memory size: 8.6445% +/- 2.4585% (220.40 +/- 62.68) (2549.60 -> 2770.00) total program size (virtual): 9.0756% +/- 2.4049% (226.20 +/- 59.94) (2492.40 -> 2718.60) peak resident set size ("high water mark"): -9.7940% +/- 1.6649% (-58.00 +/- 9.86) (592.20 -> 534.20) size of memory portions (rss): -8.7961% +/- 3.4971% (-47.20 +/- 18.77) (536.60 -> 489.40) ``` Comparing 3.6.2 with 3.7.2 ``` Initial analysis: -8.7696% +/- 2.2759% (-0.54 +/- 0.14) (6.19 -> 5.64) Completion without opening files: 16.5289% +/- 8.3591% (0.07 +/- 0.03) (0.41 -> 0.48) Completion after open of new file: 45.0913% +/- 2.8023% (1.30 +/- 0.08) (2.87 -> 4.17) getAssists call: 21.4736% +/- 2.3049% (0.61 +/- 0.07) (2.86 -> 3.48) peak virtual memory size: -5.9134% +/- 3.8164% (-163.80 +/- 105.72) (2770.00 -> 2606.20) total program size (virtual): -6.5548% +/- 4.0754% (-178.20 +/- 110.79) (2718.60 -> 2540.40) peak resident set size ("high water mark"): -16.3984% +/- 0.5460% (-87.60 +/- 2.92) (534.20 -> 446.60) size of memory portions (rss): -18.0629% +/- 3.2699% (-88.40 +/- 16.00) (489.40 -> 401.00) ``` Where, between 3.6.2 and 3.7.2 these stand out: ``` Completion without opening files: 16.5289% +/- 8.3591% (0.07 +/- 0.03) (0.41 -> 0.48) Completion after open of new file: 45.0913% +/- 2.8023% (1.30 +/- 0.08) (2.87 -> 4.17) getAssists call: 21.4736% +/- 2.3049% (0.61 +/- 0.07) (2.86 -> 3.48) ``` these surely weren't great before, but are much worse now. Change-Id: I6f94f941cda86b1aa9ee7e7a9b1912df85c7acb2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/417820 Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
@jwren Is it true that IntelliJ should never need to get flutter outline information for more than one file at a time? |
I am not familiar enough with the Flutter setSubscriptions protocol (https://htmlpreview.github.io/?https://github.com/dart-lang/sdk/blob/main/pkg/analysis_server/doc/api.html#request_flutter.setSubscriptions) to be able to come in and determine if the right things are being done here from the IJ side without lots of manual testing and digging into the protocol. It looks like the feature was largely added by Konstantin and Jacob. Thanks for starting to look into this issue to get better performance. |
…ptions" are not; non-interactive ones have less priority The legacy_many_files_in_flutter_set_subscriptions benchmark shows how "flutter.setSubscriptions" calls can make the analyzer slower to respond. What happens is this: * The user opens a new file in the IDE. * The IDE sends the `flutter.setSubscriptions` request which equates to a call to `getResolvedUnit` for each file in the request. If this is, say, 300 files it's 300 calls to `getResolvedUnit`. * The IDE sends a `edit.getAssists` request for the newly opened file. This request starts processing, reaches `getResolvedLibrary(file)` which calls `getUnitElement` ultimately adding the path to `_unitElementRequestedFiles` which in `performWork` is done _after_ `_requestedFiles`, meaning it has to do all the flutter requested files first. * The user might then request completion for instance, but because the analyzer only processes one request at a time it has to wait for the `edit.getAssists` request to finish first, which had to wait for the files from the `flutter.setSubscriptions` request to process. All in all it's a lot of waiting for the user. This CL adds a `interactive` option to the `getResolvedUnit` call. It defaults to true in which case files are still added to `_requestedFiles` and processed the same. If it's false it will instead be added to a newly introduced list instead and processed at a lower priority. Subscription requests are changed to pass `false` to `interactive`, avoiding the scenario above. Comparing before this CL with this CL on the "legacy_many_files_in_flutter_set_subscriptions" benchmark with 100 files / CodeType.ImportChain these are the statistics on the changes based on 5 runs each: ``` Completion after open of new file: -81.6652% +/- 7.7564% (-3.70 +/- 0.35) (4.53 -> 0.83) getAssists call: -96.6315% +/- 0.9307% (-3.61 +/- 0.03) (3.74 -> 0.13) peak virtual memory size: -5.6786% +/- 3.2964% (-139.00 +/- 80.69) (2447.80 -> 2308.80) total program size (virtual): -4.6387% +/- 3.8146% (-110.80 +/- 91.11) (2388.60 -> 2277.80) ``` Even when flutter/flutter-intellij#7980 is hopefully fixed I think it is a fair change to de-prioritize a non-interactive request. Change-Id: Icba2faebf12f9913cf24db7cb90fdc6f4c74164e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/418020 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Jens Johansen <jensj@google.com>
Thanks for this great report @jensjoha! Taking a look at this now. |
The the fileOutlineListeners map grows indefinitely because
If all code related to the "flutter.setSubscriptions" call is not needed anymore, this map may be completely removed along with a bunch of other obsolete code |
Right! I'm trying to establish exactly this. It looks like Thanks! |
On the topic of managing the file map, it seems like the issue is introduced (or at least manifest) here: flutter-intellij/flutter-idea/src/io/flutter/editor/ActiveEditorsOutlineService.java Lines 134 to 136 in 38e78f0
The rub is that the path in @alexander-doroshko: it seems like In the meantime, I think using the obsolete path as-is addresses the problem: for (final String path : obsoletePaths) {
final FlutterOutlineListener listener = outlineListeners.remove(path);
... |
As for the use of the flutter outline service in general, even though we are no longer displaying a flutter outline view, it does seem like we're using the the service to figure out where to contribute test line markers. See: flutter-intellij/flutter-idea/src/io/flutter/run/common/TestLineMarkerContributor.java Line 63 in a801049
which calls here: flutter-intellij/flutter-idea/src/io/flutter/run/common/CommonTestConfigUtils.java Line 59 in 9a6aff3
I've confirmed that this code is alive and does contribute to markers showing up but I'm not sure it's entirely working as intended. Either way, in the absences of a flutter outline view, it's likely this isn't the best way to calculate test line markers regardless but I'm missing a lot of context and need to do some more digging but maybe we should create another issue for that and just focus on getting the subscribed file list to stop growing infinitely. |
You mean 'already a URI' :)
You mean 'to do the right thing in case a valid file URI is passed into it' :) I'd say passing URI to |
In IntelliJ, opening a project with
flutter
in theenvironment
inpubspec.yaml
, e.g. something likeopening a file sends a
flutter.setSubscriptions
request looking something like this:Say we close the file and open another, it now sends something like this:
closing that and opening a third, closing that and opening a forth etc a bunch of times and you'll end up with something like
at which point the analyzer will start to become slow:
Notice that if I open a file I've already opened once it doesn't send the request, I believe because of this:
flutter-intellij/flutter-idea/src/io/flutter/dart/FlutterDartAnalysisServer.java
Lines 140 to 150 in 38e78f0
(i.e.
sendSubscriptions
is only called i it actually adds the path)I'm guessing something goes wrong in these lines:
flutter-intellij/flutter-idea/src/io/flutter/editor/ActiveEditorsOutlineService.java
Lines 125 to 152 in 38e78f0
Without having looked into it it seems suspect that it takes a key from
outlineListeners
(final String path : outlineListeners.keySet()
) and then does something to it before trying to remove it again (final String filePathOrUri = getAnalysisServer().getAnalysisService().getLocalFileUri(path);
,final FlutterOutlineListener listener = outlineListeners.remove(filePathOrUri);
), but I'm guessing.The text was updated successfully, but these errors were encountered: