fix: Don't recompile Flutter apps that already failed to compile#3953
Closed
spydon wants to merge 1 commit into
Closed
fix: Don't recompile Flutter apps that already failed to compile#3953spydon wants to merge 1 commit into
spydon wants to merge 1 commit into
Conversation
The `flutter-app` directive dedupes compilation via `COMPILED`, but that list is only appended to after a successful compile, copy and assert. When `flutter build web` fails, the target is never recorded, so every page that references the same app pays for another full compile of an app that is guaranteed to fail again in exactly the same way. Failures are now recorded in `FAILED` alongside the error, and subsequent pages re-report the stored error instead of recompiling. Every referencing page still surfaces the error, so nothing is silently swallowed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
_ensure_compileddedupes compilation through the staticCOMPILEDlist, butCOMPILED.append(...)is the last statement of the function. If the compile, the copy or oneof the asserts raises, the target is never recorded, so the next page referencing that app
compiles it all over again, even though the result is guaranteed to be identical.
The effect is quadratic in the worst case. The v1.35.1 docs reference
../flame/examplesfrom36 pages, so a single broken app produced 36 identical failing web builds of ~62s each:
Failures are now recorded in a
FAILEDmap alongside their error. A target that alreadyfailed re-raises the stored error instead of paying for another
flutter build web. Errorreporting is unchanged: every page referencing a broken app still reports it, so nothing is
silently swallowed.
Context
This was found while investigating why the docs build on flame-docs-site takes 4h17m. The
reason those compiles were failing in the first place turned out to be a separate bug in that
repo's build script, fixed in flame-engine/flame-docs-site#22: the versions are built
sequentially in one clone, and
git checkout -fleaves ignored files alone, so a generatedweb plugin registrant importing
package:rive_nativesurvived from a version usingrive
^0.14into versions using rive^0.13, which do not depend on it.So that PR, not this one, is the actual fix for the failing builds. This PR is worth having
regardless: retrying a deterministic failure once per referencing page is wrong on its own
terms, and it is what turned a handful of broken apps into 590 failed compiles and ~3.3 hours
of wasted CI time. With this change, a genuinely broken app costs one compile instead of 36.
To be explicit about the numbers: on run 29694895994 this change alone would have cut the
build from 4h17m to ~58m. Once the state leak is fixed the compiles succeed, so the saving
from this PR in normal operation is small. Its value is bounding the cost of future breakage
rather than speeding up the healthy path.
Testing instructions
The behaviour only differs when an app fails to compile, so the failure has to be forced:
melos run doc-setupint x = 'oops';toexamples/lib/main.dart.melos run doc-buildBefore this change,
Compiling Flutter app [flame-examples]is logged once per referencingpage (36 times, each a full failing web build). After it, the app is compiled once and every
referencing page still reports the error.
Reverting step 2 and running
melos run doc-buildagain should behave exactly as before,since nothing changes on the success path.
Checklist
docsand added dartdoc comments with///.examplesordocs.Breaking Change?
Related Issues