-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Enable asset transformation feature in hot reload workflow (excluding Web) #144161
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
Enable asset transformation feature in hot reload workflow (excluding Web) #144161
Conversation
packages/flutter_tools/lib/src/build_system/tools/asset_transformer.dart
Outdated
Show resolved
Hide resolved
packages/flutter_tools/lib/src/build_system/tools/asset_transformer.dart
Outdated
Show resolved
Hide resolved
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.
late should generally be avoided (except it's useful in test code, where you ensure it's always initialized from setUp()). Consider if line 172 throws and we never initialize inputFile, we'd get a LateInitializationError on line 202. Maybe we make it nullable, and then update the check on 201 to be if (inputFile != null && cleanupInput)?
I think it's the right tool for the job here of unconditionally cleaning up resources, however finally can make it more difficult to reason about the type safety of a block of code.
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.
Addressed in nit, but in slightly a different way than proposed. I make a null-assertion on inputFile, since it should be set if cleanupInput was set.
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.
I'm not familiar with the implementations of DevFSContent. When would we get DevFSFileContent vs say DevFSByteContent?
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.
I wouldn't be surprised if this is always a DevFSFileContent. However, this code can't know that. There is probably a missing abstraction somewhere upstream that guarantees this is a file, but I don't think improving this situation would be easy.
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.
for my understanding, why do we not evict this path the first upload?
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.
Good question. The only reference to assetsPathToEvict is here:
flutter/packages/flutter_tools/lib/src/run_hot.dart
Lines 1207 to 1215 in 4e70bfa
| for (final String assetPath in device.devFS!.assetPathsToEvict) { | |
| futures.add( | |
| device.vmService! | |
| .flutterEvictAsset( | |
| assetPath, | |
| isolateId: views.first.uiIsolate!.id!, | |
| ) | |
| ); | |
| } |
where make some vm service call, ext.flutter.evict. Do you know where to find the code that process this call?
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.
Nevermind. I'm starting to figure this out, give me a sec.
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.
So this VM service call ends up here:
flutter/packages/flutter/lib/src/services/binding.dart
Lines 250 to 258 in 7a4c246
| /// Called in response to the `ext.flutter.evict` service extension. | |
| /// | |
| /// This is used by the `flutter` tool during hot reload so that any images | |
| /// that have changed on disk get cleared from caches. | |
| @protected | |
| @mustCallSuper | |
| void evict(String asset) { | |
| rootBundle.evict(asset); | |
| } |
which indeed just evicts the asset from the framework's cache. However, I don't know if there is a specific reason to not vacuously evict from the cache in first upload (other than perhaps performance).
christopherfujino
left a comment
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.
2 nits, about avoiding late and await-ing a future, but otherwise LGTM
|
One issue worth pointing out is that if (during
then the asset won't be re-transformed. This is because the only thing we check during a DevFS update is the last-modified time of the asset file. |
What is the "asset file" in this context? the output of the transformer? And is this a temporary bug, or a known limitation that we should document? |
The original file. This is a limitation of how we implement hot reload. More research and another PR likely to follow. |
Ahh, I see what you mean. If the input asset is the same, but the transformer itself was changed. Is the timestamp on the application's |
e83b193 to
49cb3f0
Compare
|
I believe I've fixed the hot reload issue. Changes are in this commit: fix asset not being updated when transformers are changed before hot reload. This works primarily by utilizing the previously dormant I am not sure this is acceptable, as any modification to a pubspec basically means all assets needs to be processed and rewritten to the device, which could be slow given the right circumstances (or basically any case with transformers). I want to experiment with more granular caching, though this will likely make all this code even more complicated than it already is. |
I thought about this more and brought this up during this week's tool PR review. I'm OK with punting on this by documenting this feature as not being supported in hot-reload. To make this feature work with hot reload, we'd need to do some significant refactoring to asset bundling+writing code (to avoid adding more spaghetti than there already is). We need to overhaul what makes an asset "dirty" so we know when to retransform and rewrite it to the device. Currently, this mechanism is implemented as a function of the last-modified-time on the underlying asset file (or for non-files, a boolean that returns true the first time it's read and then false afterwards). It is unclear if this is worth overhauling at this time, but perhaps such a decision would be easier if we had another asset related feature that would require a similar refactoring to support hot reload. |
…ore hot reload" This reverts commit 49cb3f03ee083e86f492d762b846c74e656a0c31.
4bfd9bf to
cc2544c
Compare
|
@christopherfujino, after this PR lands, I'll make a documentative PR that demonstrates a duct-tape/hacky solution to make this work for hot reload. It'll include comments that point out the obstacles in the way of making hot reload work well for this. This could be referenced in the future when we come back to this. |
SGTM |
|
@christopherfujino poke |
packages/flutter_tools/lib/src/build_system/tools/asset_transformer.dart
Outdated
Show resolved
Hide resolved
christopherfujino
left a comment
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.
LGTM
|
More thoughts about hot-reload: Another challenge with making this fully-support hot reload is that This is problematic because the Dart VSCode extension seems to run |
flutter/flutter@3b5a2ec...8f84f3f 2024-03-06 [email protected] Roll Packages from 2aa6e3f to 9b88dbc (8 revisions) (flutter/flutter#144693) 2024-03-06 [email protected] Roll Flutter Engine from 370e7d5866d9 to b6efe0dd88fe (1 revision) (flutter/flutter#144668) 2024-03-06 [email protected] Roll Flutter Engine from d374c78bcf52 to 370e7d5866d9 (1 revision) (flutter/flutter#144661) 2024-03-06 [email protected] Roll Flutter Engine from effcf97a1f7c to d374c78bcf52 (5 revisions) (flutter/flutter#144659) 2024-03-06 [email protected] Fill in SliverConstraints fields missing from ==, hashCode, toString (flutter/flutter#143661) 2024-03-06 [email protected] Roll Flutter Engine from 49bc1577f317 to effcf97a1f7c (10 revisions) (flutter/flutter#144653) 2024-03-05 49699333+dependabot[bot]@users.noreply.github.com Bump codecov/codecov-action from 4.0.2 to 4.1.0 (flutter/flutter#144174) 2024-03-05 [email protected] Fix embedding FlutterMacOS.framework for macOS add2app via cocoapods (flutter/flutter#144248) 2024-03-05 [email protected] Enable asset transformation feature in hot reload workflow (excluding Web) (flutter/flutter#144161) 2024-03-05 [email protected] Roll Flutter Engine from 3e8b0deffe4e to 49bc1577f317 (5 revisions) (flutter/flutter#144639) 2024-03-05 [email protected] Updated the smiley TextButton example again (flutter/flutter#144630) 2024-03-05 [email protected] Adds missing `style` to `PopupMenuButton` (flutter/flutter#143392) 2024-03-05 [email protected] Roll Flutter Engine from a7c785884903 to 3e8b0deffe4e (1 revision) (flutter/flutter#144629) 2024-03-05 [email protected] Add regression test for TabBar crash (flutter/flutter#144627) 2024-03-05 [email protected] Roll Packages from 0625827 to 2aa6e3f (5 revisions) (flutter/flutter#144628) 2024-03-05 [email protected] remove unused `firstBuildTime` parameter in `DevFS::update` (flutter/flutter#144576) 2024-03-05 [email protected] Roll Flutter Engine from 8916bb32b7b8 to a7c785884903 (1 revision) (flutter/flutter#144624) 2024-03-05 [email protected] Revert "_DefaultTabControllerState should dispose all created TabContoller instances. (#136608)" (flutter/flutter#144579) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
flutter/flutter@3b5a2ec...8f84f3f 2024-03-06 [email protected] Roll Packages from 2aa6e3f to 9b88dbc (8 revisions) (flutter/flutter#144693) 2024-03-06 [email protected] Roll Flutter Engine from 370e7d5866d9 to b6efe0dd88fe (1 revision) (flutter/flutter#144668) 2024-03-06 [email protected] Roll Flutter Engine from d374c78bcf52 to 370e7d5866d9 (1 revision) (flutter/flutter#144661) 2024-03-06 [email protected] Roll Flutter Engine from effcf97a1f7c to d374c78bcf52 (5 revisions) (flutter/flutter#144659) 2024-03-06 [email protected] Fill in SliverConstraints fields missing from ==, hashCode, toString (flutter/flutter#143661) 2024-03-06 [email protected] Roll Flutter Engine from 49bc1577f317 to effcf97a1f7c (10 revisions) (flutter/flutter#144653) 2024-03-05 49699333+dependabot[bot]@users.noreply.github.com Bump codecov/codecov-action from 4.0.2 to 4.1.0 (flutter/flutter#144174) 2024-03-05 [email protected] Fix embedding FlutterMacOS.framework for macOS add2app via cocoapods (flutter/flutter#144248) 2024-03-05 [email protected] Enable asset transformation feature in hot reload workflow (excluding Web) (flutter/flutter#144161) 2024-03-05 [email protected] Roll Flutter Engine from 3e8b0deffe4e to 49bc1577f317 (5 revisions) (flutter/flutter#144639) 2024-03-05 [email protected] Updated the smiley TextButton example again (flutter/flutter#144630) 2024-03-05 [email protected] Adds missing `style` to `PopupMenuButton` (flutter/flutter#143392) 2024-03-05 [email protected] Roll Flutter Engine from a7c785884903 to 3e8b0deffe4e (1 revision) (flutter/flutter#144629) 2024-03-05 [email protected] Add regression test for TabBar crash (flutter/flutter#144627) 2024-03-05 [email protected] Roll Packages from 0625827 to 2aa6e3f (5 revisions) (flutter/flutter#144628) 2024-03-05 [email protected] remove unused `firstBuildTime` parameter in `DevFS::update` (flutter/flutter#144576) 2024-03-05 [email protected] Roll Flutter Engine from 8916bb32b7b8 to a7c785884903 (1 revision) (flutter/flutter#144624) 2024-03-05 [email protected] Revert "_DefaultTabControllerState should dispose all created TabContoller instances. (#136608)" (flutter/flutter#144579) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Partial implementation of #143348
This enables asset transformation during hot reload (except for web, because that has its own implementation of
DevFS🙃). Asset transformers will be reapplied after changing any asset and performing a hot reload duringflutter run.Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.