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
Dart formatter Keeps running endlessly #3270
Comments
Can you confirm which Flutter SDK version you're on, and whether LSP is enabled (hover over the SDK version in the status bar to see whether it says "DAS" or "LSP"). I've seen this before (and a few others have noted it), although I've never been able to get a log file or repro it. If you're able to get a log when this occurs, that may be useful in tracking it down. Thanks! |
FWIW - some performance improvements have landed in Flutter master recently that may impact this, though it's hard to be sure since I haven't been able to repro. |
Recently the same issue did not come up. It used to happen when I used Alt + shift + f in VScode. Anytime soon I get the same Issue I will post the logs. |
I may have a repro for this. I'm using SDK: Loc: /Users/danny/Dev/Dart SDKs/nightly-2021-04-06 I'm opening the SDK The file is very large (35k lines) so it might not be the same issue seen on smaller files, but it's definitely way slower than I would expect - 22 seconds in this example (which produced 0 edits because the change was in a comment): https://gist.github.com/DanTup/05e61e341998ab2c94aed3053899c997
|
Looks like this time is actually spent in the formatting and not where I thought it might be (generating minimal edits). I'm not sure if this is expected performance though. @munificent I'm not sure what the expected timings are for a large file like this - it's about 20 seconds for 35k lines. It's definitely a large file (and therefore may be unrelated to the original issue raised here), but I thought it worth checking. It's the same on stable 2.12.0 SDK (v1.3.11 of the formatter) and a recent nightly with v2.0.0 of the formatter. Repo:
Edit: A comment at dart-lang/dart_style#864 (comment) suggests the whole Flutter repo could be formatted in around 10-12 seconds, so it does seem like this might not be expected. Here's a CPU profile trace exported from DevTools: https://gist.github.com/DanTup/567ebca5f20c3cd4c647dfdc6a3b56cf Which looks like this: Perhaps this 1903 character statement isn't helping (I'm now more convinced this is unrelated to the original issue - I don't think most people have code like this!): final documentChanges = (json['documentChanges'] is List && (json['documentChanges'].every((item) => TextDocumentEdit.canParse(item, nullLspJsonReporter))))
? Either2<List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>.t1(
json['documentChanges']
?.map((item) =>
item != null ? TextDocumentEdit.fromJson(item) : null)
?.cast<TextDocumentEdit>()
?.toList())
: ((json['documentChanges'] is List && (json['documentChanges'].every((item) => (TextDocumentEdit.canParse(item, nullLspJsonReporter) || CreateFile.canParse(item, nullLspJsonReporter) || RenameFile.canParse(item, nullLspJsonReporter) || DeleteFile.canParse(item, nullLspJsonReporter)))))
? Either2<List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>.t2(json['documentChanges']
?.map((item) => TextDocumentEdit.canParse(item, nullLspJsonReporter)
? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t1(
item != null ? TextDocumentEdit.fromJson(item) : null)
: (CreateFile.canParse(item, nullLspJsonReporter)
? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t2(item != null ? CreateFile.fromJson(item) : null)
: (RenameFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t3(item != null ? RenameFile.fromJson(item) : null) : (DeleteFile.canParse(item, nullLspJsonReporter) ? Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t4(item != null ? DeleteFile.fromJson(item) : null) : (item == null ? null : (throw '''$item was not one of (TextDocumentEdit, CreateFile, RenameFile, DeleteFile)'''))))))
?.cast<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>()
?.toList())
: (json['documentChanges'] == null ? null : (throw '''${json['documentChanges']} was not one of (List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>)'''))); |
Even very large files should be quite fast to format, but there are corner cases where a file that contains a large number of pathologically complex expressions can get pretty slow.
You wouldn't believe the things I've seen. That one is definitely pretty bad, but generated code often looks like this and dartfmt is supposed to handle it well. |
@munificent is it worth me filing an issue in dart_style about that? (do you think it's likely significant gains could be made?). I could also tweak this generated code (I'm generating it), although my concern was less about this specific file than whether there's a more general issue other users may also see. If not, I wonder if the analysis server should offload this to another isolate, since it's currently synchronous in the main isolate that will block all other language server requests for the duration (@bwilkerson any thoughts?). Although, I don't think either of those resolve the original issue here. I'm not sure it's just slow formatting, but suspect the server was busy with something else (perhaps rebuilding contexts it didn't need to - which hopefully is now fixed). |
If we're sure that dart_style is causing the issue (and not something else in server), then it might well make sense to run |
I'm not sure it's the cause of the original issue raised here - I think I just happened to see the same behaviour but it was caused by the big file. I don't expect many users have code like generated code above, but it would be nice not to improve the experience if they did.
If I understand correctly, I think it may be parsing currently anyway? Is it possible to run dart_style asynchronously? I thought it was all synchronous and CPU bound. If it can be run asynchronously (whether in an isolate or otherwise), I'd prefer to support cancellation than add a timeout (at least for LSP). Timeouts can be frustrating because in some cases users might want to wait for an operation to complete (because the result are more important than it being fast). As long as it's running asynchronously, for LSP we can receive cancellation requests from the client and could abort - that way the user is in control of whether they wait of cancel, rather than it being a fixed time (which could have different cut-offs in terms of file size/complexity based on how powerful the users machine is). This is probably moot if Bob thinks this could be much faster (in which case I'll file a dart_style issue with the repro above), though otherwise I could file an SDK issue about handling this better and we can figure out the best way there. I'll leave this issue open for now either way, as I think there's another issue - which may or may not be fixed by the context rebuild changes - that's causing people to see what looks like slow formatting but might not be. |
Yes, it looks that way. I'd assumed that we'd ask the
Probably not.
The legacy protocol doesn't support that, so we might have to have a timeout there, or just let the client (IntelliJ) handle the timeout. |
Is there a way to time out synchronous code? If not, presumably an isolate would be the only way? (and then it probably wouldn't really be cancelled, but rather us just returning early and it finishing in the background). If we do decide it needs a timeout, it shouldn't be difficult to add to just the non-LSP protocol and use cancellation for LSP (or at least, have a higher timeout for LSP). We can revisit when it's clearer whether this is a common case (I suspect not) and whether there are optimisations dart_style could make for code like the above. I think may "repro" above is likely an edge case and a bit of a red herring. |
Yes, please do.
Yeah, it's definitely possible, though I can't promise when I'll have time to look into it.
Tweaking the code would definitely be a good idea. That's a huge expression, and a giant generated file that contains many many expressions that large is basically the worst case for dartfmt. If you generate code like: final documentChanges = () {
if (json['documentChanges'] is List &&
(json['documentChanges'].every(
(item) => TextDocumentEdit.canParse(item, nullLspJsonReporter)))) {
return Either2<
List<TextDocumentEdit>,
List<
Either4<TextDocumentEdit, CreateFile, RenameFile,
DeleteFile>>>.t1(json['documentChanges']
?.map((item) => item != null ? TextDocumentEdit.fromJson(item) : null)
?.cast<TextDocumentEdit>()
?.toList());
} else if (json['documentChanges'] is List &&
(json['documentChanges'].every((item) =>
(TextDocumentEdit.canParse(item, nullLspJsonReporter) ||
CreateFile.canParse(item, nullLspJsonReporter) ||
RenameFile.canParse(item, nullLspJsonReporter) ||
DeleteFile.canParse(item, nullLspJsonReporter))))) {
return Either2<
List<TextDocumentEdit>,
List<
Either4<TextDocumentEdit, CreateFile, RenameFile,
DeleteFile>>>.t2(json['documentChanges']
?.map((item) {
if (TextDocumentEdit.canParse(item, nullLspJsonReporter)) {
return Either4<TextDocumentEdit, CreateFile, RenameFile,
DeleteFile>.t1(
item != null ? TextDocumentEdit.fromJson(item) : null);
} else if (CreateFile.canParse(item, nullLspJsonReporter)) {
return Either4<TextDocumentEdit, CreateFile, RenameFile,
DeleteFile>.t2(item != null ? CreateFile.fromJson(item) : null);
} else if (RenameFile.canParse(item, nullLspJsonReporter)) {
return Either4<TextDocumentEdit, CreateFile, RenameFile,
DeleteFile>.t3(item != null ? RenameFile.fromJson(item) : null);
} else if (DeleteFile.canParse(item, nullLspJsonReporter)) {
return Either4<TextDocumentEdit, CreateFile, RenameFile,
DeleteFile>.t4(item != null ? DeleteFile.fromJson(item) : null);
} else if (item == null) {
return null;
} else {
throw '''$item was not one of (TextDocumentEdit, CreateFile, RenameFile, DeleteFile)''';
}
})
?.cast<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>()
?.toList());
} else if (json['documentChanges'] == null) {
return null;
} else {
throw '''${json['documentChanges']} was not one of (List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>)''';
}
}; Then it will format it about 1200x faster. (That's times, not percent.) |
@munificent thanks! I've raised dart-lang/dart_style#1022 and may see if it's easy to tweak that in future (I don't hand-edit/format this file, but the generation script does format it at the end - so now I realise why that seemed to be taking a while too). |
This issue has been marked stale because it is tagged awaiting-info for 30 days with no activity. Remove the stale label or comment to prevent the issue being closed in 10 days. |
I don't know what is causing it, but all I see is "Saving 'http.dart': Running 'Dart' Formatter (configure)". and it doesn't stop. Started with the latest Flutter upgrade. Have to restart vscode everytime and try again, works for one or two saves. Is there anything I can provide to help solve this issue? Serious workflow problem. Flutter 2.2.0 • channel stable • https://github.com/flutter/flutter.git |
@mellowcello77 a log could be very helpful:
The log file may contain parts of your source code so if it's something you can't share, please open the log file and look for the last few occurrences of If you can repro on a project without sensitive code, feel free to just attach (or email to me at logs@dartcode.org) the lines starting a handful above the last server response. Thanks! |
even with no more than 300 lines of flutter code, no conditionals. But system overall low memory (less than 1Gb unallocated) still causes this issue on a daily basis. Could it be that the formatting process requires some system resources to be available at the forefront (even if it doesn't utilize them completely)? |
One day later and have not been able to replicate it again. Will post as requested by DanTup soon as it happens again. |
I'm not certain, but I suspect it's probably not the formatter here - I think the server is not responding correctly and then the format requests jut gets stuck (I think it was coincidence that I triggered something similar behaviour by actually having something that formatted slowly). If this seems to happen after you're just run a debug session and the analysis server appears to never recover, then it could be related to dart-lang/sdk#45996 (which my or may not be specific to macOS), though I don't fully understand what's happening there yet. |
I have not corroborated this, but someone on my team reported that this appears to happen to them when they have Android studio open at the same time as VS Code. I can't easily imagine how that could happen, perhaps some sort of shared resource contention (seems unlikely right?), but I figure it doesn't hurt too much to share that theory. I'm also trying to replicate with logging turned on, but haven't had any luck. |
I have deleted |
I made an update. The problem still persists. I will send log to logs@dartcode.org. |
@ilkerulusoy thanks! I checked the log, but it looks like it didn't include the request to format. The log file ends right after the initial analysis completes. Did you try to save/format while initial analysis may still have been in progress? (parts of that analysis are synchronous and will delay formatting until they're complete). Also - could you see if enabling the |
@DanTup Restarting vscode fixed it. My log setting is active, I'll repost from the next. I didn't make any changes for |
I just emailed a log taken during a formatter hang in VSCode. I'm using 2.2.2. The issue is very intermittent for me. The same project will work fine for a week or so and then I'll get a hang. I've had logging turned on for a long time to see if I could catch one in progress. Let me know if the log snippet I sent isn't enough. The whole log was > 700 mb so I only sent the last 200 lines. The formatter was hung for more than three minutes before I closed VSCode and sent the log. |
@sowens-csd thanks for the log - unfortunately it doesn't seem to include the formatting request, so it's hard to tell what was going on. Was the formatting still occurring when you took this log? There are lots of requests/responses in the part you sent me, suggesting the server was responsive so I'm not yet sure what might've happened. If you still have the full log, are you able to search for |
I do still have the full log and did a grep for 'formatting' and it doesn't appear in the file |
@sowens-csd that's definitely strange (although perhaps may also be related? 🤔) A few questions:
It may also be interesting to run Dart: Capture Logs and just force a format operation and see whether that shows up in the log or not. |
I tried a |
@sowens-csd sorry, my mistake - I thought you had LSP enabled but checking the log again it is not. In this case you should be looking for That said, I would also encourage enabling LSP with the To force formatting, you should be able to just insert any unformatted code (eg.
Running from the command line or embedded terminal definitely won't show up, as they're completely disconnected from the extension and just work on the filesystem directly. |
I just sent you a larger log extract that includes the last I'll give the |
In the log you sent me, I only see one There have been many improvements in LSP in the latest stable releases, and from the next release of the Dart plugin it will be on by default for everyone that hasn't explicitly turned it off (it's currently at 75%). If there are any outstanding issues with it I'd definitely like to know. (I'm not sure it'll make much difference here, but it's certainly worth trying - there's less to go wrong in the VS Code side using LSP, and if things go wrong in the server they're usually more obvious from the logs). In LSP the formatting is a little different too - we minimise the edits on the server, whereas without we'll send a replacement for the entire file and let VS Code figure it out. Again, I'm not sure it would affect this issue, but it will cut out that extra work being done by VS Code. |
Thanks for having a look. I've switched to LSP and will post an update if I see the format issue again. |
Had the same issue with Flutter 2.2.1. After uninstalling Flutter and Dart extensions, upgrading flutter to latest version (now 2.2.3) and reinstalling the extensions, the formatting on save works instantly. |
This issue has been marked stale because it is tagged awaiting-info for 20 days with no activity. Remove the stale label or comment to prevent the issue being closed in 10 days. |
Having the same issues with the following - Flutter 2.8.0 • channel stable • https://github.com/flutter/flutter.git |
@temitopeog can you reproduce it reliably? Is it with particular files? (If so, are you able to share one so that I can reproduce)? |
Removing all package files from the project and deleting local VS Code files (package files etc.) and reinstalling them worked for me idk why. |
I can't explain that either, but if you see this come back, please do file a new issue so we can do some digging. Thanks! |
I am getting this issue alot. I need to use various flutter versions of flutter including 2.2.0. Restarting the window with cmd-R helps at lest temporarily. My log file has no error messages: Dart Code extension: 3.34.0 App: Visual Studio Code Workspace type: Flutter Dart SDK: HTTP_PROXY: undefined Logging Categories: Fri Feb 04 2022 [14:23:27 GMT-0500 (Eastern Standard Time)] Log file started |
@Cory-FanDemand the log you included doesn't seem to have captured anything - did you start capturing before saving/formatting? I see you're not on the latest version of Flutter (you have v2.2.1, the latest is v2.10). There have been many fixes to the LSP server since then - please try upgrading to the latest version and it may be that the problem goes away. |
@DanTup Yes I did, next time it starts happening - if I'm on 2.10 at the time - I'll try to capture again. |
@Cory-FanDemand thanks - you ned to start capturing before the format request is sent (and ideally, leave it for until it completes). You can set logging to run all the time using settings on this page: https://dartcode.org/docs/logging/#analyzer Although the files can get quite large, so you should keep an eye on them. FYI - the analysis server logs will contain parts of your source code, so they may need reviewing/redacting before sharing. |
I was facing the same issue and noticed it would only happen when my internet connection was slow or down. For me, disabling analytics solved the problem: dart --disable-analytics |
@grlduarte can you reliably reproduce this? (for example if you manually disconnect your internet, does it occur?) There are some things I'm aware of where the server will try to connect to the internet (such as caching Pub package names to use in code completion) but I didn't think it was currently sending any analytics. I'm surprised that disabling analytics would fix formatting getting stuck. Has it been long since you disabled them? Is it possible it be intermittent and you've just been lucky since disabling it? If you can reproduce the issue, I'd be interested in a new issue opening (here or in dart-lang/sdk and CCing me) so we can capture some logs and understand what's happening. (@bwilkerson FYI) |
@DanTup I have had this problem on and off for some time. Using Vim + Dart plugin I noticed every time my internet was down the editor would stuck on save. Today I tried what you suggested and: TA-DA. Once the problem was isolated, I don't know what led me to it, but I disabled analytics and the problem was gone. There's more, I didn't mention in the previous answer but every Also worth mentioning that my SDK is pretty outdated (2.18.2). I will open a new issue in dart-lang/sdk since this does not seems to be related to Dart Code |
If this hang still occurs on the latest SDK, I would certainly file an issue in dart-lang/sdk about it. Analytics and no internet should defintely not prevent these commands from working. If the |
Issue Type: Bug
It's random.
At times when you save dart code. Dart formatter starts running and do not stops for several minutes (around 5 minutes minimum). I have to cancel it and save again and same thing happens.
Only solution is restart VScode or sometimes restart the PC.
Extension version: 3.21.1
VS Code version: Code 1.55.1 (08a217c4d27a02a5bcde898fd7981bda5b49391b, 2021-04-07T15:06:02.360Z)
OS version: Windows_NT x64 10.0.19041
System Info
gpu_compositing: enabled
multiple_raster_threads: enabled_on
oop_rasterization: enabled
opengl: enabled_on
protected_video_decode: enabled
rasterization: enabled
skia_renderer: enabled_on
video_decode: enabled
vulkan: disabled_off
webgl: enabled
webgl2: enabled
A/B Experiments
The text was updated successfully, but these errors were encountered: