The gist of it is that we intercept the Rust linking phase and then drive `rustc` manually. There's some diffing logic that compares assembly between compiles and then a linking phase where we patch symbols against the running process. Works across macOS, Windows, Linux, iOS, Android, and WASM. On my m4 I can get 130ms compile-patch times, quite wicked stuff.
We handle the hard parts that the traditional dylib-reloading doesn't including TLS, statics, constructors, etc.
I've been posting demos of it to our twitter page (yes twitter, sorry...)
- With bevy: https://x.com/dioxuslabs/status/1924762773734511035
- On iOS: https://x.com/dioxuslabs/status/1920184030173278608
- Frontend + backend (axum): https://x.com/dioxuslabs/status/1913353712552251860
- Ratatui (tui apps): https://x.com/dioxuslabs/status/1899539430173786505
Our unfinished release notes are here:
https://github.com/DioxusLabs/dioxus/releases/tag/v0.7.0-alp...
More details to come!
It's a little specific to how dioxus uses axum today, but we plan to release an axum-only integration in the future.
From the docs Subsecond looks almost perfect. The only downside I found is that (if I understood correctly) you have to modify the function call in the source code of every function you want to hotpatch.
It is a bit mitigated in that the change does not cost anything in release builds, but it still is a big thing. Do I want sprinkle my code with call for every function I might potentially have to patch in a debugging session?
Currently Dioxus and Bevy have subsecond integration so they get automatic hot-patching without any end-user setup.
We hope to release some general purpose adapters for axum, ratatui, egui, etc.
The goal is that frameworks just bake `subsecond::current` into their `tick()` function and end-users get hot-patching for free.
Also, didn't the article say explicitly that struct layout changes aren't supported??
Layout changes are supported for structs that don’t persist across the well-defined reload point.
Metaprogramming that maintenance burden seems like it should be relatively straight-forward, if you've written a linker already.
I looked into liveplusplus a lot and their unreal integration also requires a broker to get the most out of it. If you're building a game engine and want to support struct layout and alignment changes, you'll need to do some re-instancing. Hiding a `subsecond::call` deep in the bowels of the host framework hides it from the user and lets the framework handle any complicated state management it needs during hotpatches.
I wouldn't say it's purity - the first version of subsecond actually did do in-process modification - but after playing around with it for a while, I much preferred the light runtime integration. The dioxus integration was about 5 lines of code, so it's quite minimal.
mmastrac•7h ago
My current day job @ Gel has me working on a Rust socket frontend for some pretty complex code and that could also be pretty interesting.
It seems to require that you choose a good "cutover" point in your codebase, but TBH that's probably not too hard to pick. The HTTP service handler in a webserver, the socket handlers in non-web serving code, etc.
It does appear to have a limitation where it will only allow the main crate to be hotpatched. That's less than ideal, but I suppose the convenience might justify some code structure changes to allow that.