-
Notifications
You must be signed in to change notification settings - Fork 290
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
Hot reload Rust libraries when changed #1966
Comments
Hi! Thanks for opening your first issue here! 😄 |
Shit, this is probably impossible: flutter/flutter#75528 Then, this is not a bug… Sorry for that. |
Yes, I think so... |
This may be possible if we don't mind creating tons of garbage. Dart does not support hot reloading FFI libraries, but does it support loading new FFI libraries? If so, in theory we can change the name of the whole Rust library, point the Dart code to this new library, then hot reload the Dart code. How does that sound? In this scenario, every time we update the Rust code, we create a new dylib and load it into the Dart VM. The old dylib is not freed from the Dart VM, piling up as garbage. But, this may be fine because Rust dylibs are typically just a few MiBs (in my impression), and this garbage process is only done during development. (I was messing with Python and it turned out it cannot reload C extension modules neither, but it works if I rename the extension module. This is where this idea comes from.) |
Looks interesting! I guess there may be multiple subquestions. A quick brainstorm:
(Title and tag changed since this looks like a feature request; feel free to re-change if needed) |
I really don't know about this. Loading an FFI library should be just reading and parsing something into memory and pointing stuff to it, but the issue linked above seems to suggest there are some limitations in the Dart VM by design.
It would be nice to not forcefully delete them, but it is tricky as Rust does not have hot-reload semantics. Hot-changing a struct definition is a good way to get a SegFault. Evcxr (REPL and Jupyter kernel) tries to avoid this by invalidating variables whose types changed, but this requires static analysis of code changes. If I understand correctly, The only relevant things in a dylib are the functions (and maybe constants)? Then, by loading another dylib, the effect would be similar to changing a bunch of function pointers? New functions would be applied to old structures; this is undefined behavior. One thing we could consider, is to tell people that using Rust values after changing their structure definitions is undefined behavior, and then just don't do anything about it. People would have the choice to persist changing structures in Dart, or always restart the program when they change Rust types (or shoot themselves in the foot and get a SegFault if they so choose). |
Not checked the details yet, a quick glances and it seems that, maybe that issue is talking about there is not yet a hook when hot restart.
I think so, thus that package is somehow hacky.
Not very sure about your question, but it seems that we do generate Dart code to open dylib and call functions across ffi boundary, so seems no problem: The new Dart code uses new function pointers to new Rust code.
Agree, that looks like the approach hot-lib-reloader is taking. |
I think you got the idea. |
Mark as awaiting, since native_assets will be the preferred approach in future Dart, thus it would be great if we could build our infra based on native_assets-based things like dart-lang/sdk#55850. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new issue. |
Describe the bug
When the Rust library is modified and the bindings are regenerated, the Flutter app does not load the new version of the Rust library when using hot reload (r) or hot restart (R). A full restart of the run is needed.
Steps to reproduce
Create a new Flutter-Rust project:
flutter_rust_bridge_codegen create rapid_dart_rs cd rapid_dart_rs
On a separate terminal T1, watch and generate the bindings:
Start the app in terminal T2, targeting macOS:
Output:
Change the
greet
function inrust/src/api/simple.rs
to return something different, wait until the watching generator in T1 finishes (Done!
), and press r in T2.Expected behavior
The UI changes and reflect the behavior of the new Rust library.
Versions
flutter_rust_bridge_codegen
: flutter_rust_bridge_codegen 2.0.0-dev.35Flutter info
clang++
: Apple clang version 14.0.0 (clang-1400.0.29.202)Additional context
Please tell me if there are additional setup I needed to go through, or there is anything I was doing wrong here. Thanks!
The text was updated successfully, but these errors were encountered: