Skip to content
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

issue: Unexpected behaviors when editing dynamic parts with hot-reload #766

Open
jsprog opened this issue Jul 6, 2024 · 4 comments
Open

Comments

@jsprog
Copy link

jsprog commented Jul 6, 2024

Let's consider the sample code below (counter)

to crash the app:

  • cargo run
  • replace "{count}" with "", then save to see the change reflecting on screen
  • undo the previous change then save. app will crash!

to freeze hot-reload:

  • cargo run
  • change initialization value for count signal
  • or change "{count}" to "count: {count}"
  • or introduce extra content that depends on count signal
  • then save to see nothing reflecting to this and subsequent changes.

development environment:

  • stable-x86_64-unknown-linux-gnu - rustc 1.79.0 (129f3b996 2024-06-10)
  • nightly-x86_64-unknown-linux-gnu - rustc 1.81.0-nightly (59e2c01c2 2024-06-17)
// main.rs

use freya::prelude::*;
use freya::hotreload::FreyaCtx;

fn main() {
    dioxus_hot_reload::hot_reload_init!(Config::<FreyaCtx>::default());
    launch(app)
}

#[component]
fn app() -> Element {
    let mut count = use_signal(|| 0);
    rsx!(
        rect {
            height: "50%",
            width: "100%",
            main_align: "center",
            cross_align: "center",
            background: "rgb(0, 119, 182)",
            color: "white",
            shadow: "0 4 20 5 rgb(0, 0, 0, 80)",
            label {
                font_size: "75",
                font_weight: "bold",
                "{count}"
            }
        }
        rect {
            height: "50%",
            width: "100%",
            main_align: "center",
            cross_align: "center",
            direction: "horizontal",
            Button {
                onclick: move |_| count += 1,
                label { "Increase" }
            }
            Button {
                onclick: move |_| count -= 1,
                label { "Decrease" }
            }
        }

    )
}
# Cargo.toml

[package]
name = "freya-intro"
version = "0.1.0"
edition = "2021"

[dependencies]
dioxus = { version = "0.5.1", default-features = false, features = ["hooks", "macro"] }
dioxus-hot-reload = "0.5.0"
dioxus-router = "0.5.0"
freya = { git="https://github.com/marc2332/freya", features = ["hot-reload"]}
# freya = { version = "0.2.2", features = ["hot-reload"] } # note: this even failed with hot-reload
@jsprog
Copy link
Author

jsprog commented Jul 6, 2024

For the second case (to freeze hot-reload), I'm receiving this terminal message:

Rebuild needed... shutting down hot reloading.
Manually rebuild the application to view further changes.

how can I automate rebuild when requested by freya?

@marc2332
Copy link
Owner

marc2332 commented Jul 6, 2024

Hey,

Support for Dioxus hotreload is limited, can only edit static parts, this means that changing "{count}" or any other dynamic code will lead to unexpected behaviors. You will even get the Rebuild needed... shutting down hot reloading. message as you shared, that is when Dioxus can't simply figure out how to hotreload the code.

And no, Freya cannot request another build because it's being run through by cargo whereas Dioxus has a custom CLI, something I am not willing to do as I prefer to just use cargo.

That said, I might actually just remove hot reload in the next release. I don't think most people use it (I don't at least) because of how not-worth using it is. Maybe once Dioxus gets decent support for binary patching, I could support it in Freya

@marc2332 marc2332 changed the title hot-reload may crash app or stop to react to changes! issue: Unexpected behaviors when editing dynamic parts with hot-reload Jul 6, 2024
@jsprog
Copy link
Author

jsprog commented Jul 7, 2024

That said, I might actually just remove hot reload in the next release

hot-reload existed to increase productivity when coding apps, and despite the limits mentioned above, it helps saving developer's time when styling and positioning content.

And no, Freya cannot request another build because it's being run through by cargo

Maybe once Dioxus gets decent support for ....

Currently, the logs are available to recommend a manual restart, and by invoking cargo run as a child process, we should be able to decide when to kill and re-spawn again as cargo watch -x 'cargo run' is doing!

node run.js

// run.js
const { spawn } = require('child_process');

spawn_cargo()

function spawn_cargo() {
    const child = spawn('cargo', ['run']);

    child.stdout.on('data', (data) => {
        console.log(`${data}`)
        if (data.indexOf("Manually rebuild the application to view further changes.") > -1) {
            child.kill('SIGINT')
            spawn_cargo()
        }
    });
      
    child.stderr.on('data', (data) => {
        console.error(`${data}`)
    });
      
    child.on('error', (error) => {
        console.error(`error: ${error.message}`);
    });
      
    child.on('close', (code) => {
        console.log(`child process exited with code ${code}`);
    });
}

@marc2332
Copy link
Owner

marc2332 commented Jul 7, 2024

Currently, the logs are available to recommend a manual restart, and by invoking cargo run as a child process, we should be able to decide when to kill and re-spawn again as cargo watch -x 'cargo run' is doing!

node run.js

// run.js
const { spawn } = require('child_process');

spawn_cargo()

function spawn_cargo() {
    const child = spawn('cargo', ['run']);

    child.stdout.on('data', (data) => {
        console.log(`${data}`)
        if (data.indexOf("Manually rebuild the application to view further changes.") > -1) {
            child.kill('SIGINT')
            spawn_cargo()
        }
    });
      
    child.stderr.on('data', (data) => {
        console.error(`${data}`)
    });
      
    child.on('error', (error) => {
        console.error(`error: ${error.message}`);
    });
      
    child.on('close', (code) => {
        console.log(`child process exited with code ${code}`);
    });
}

Yeah sure but that would require a small CLI as you can see, if you want to make a rust POC maybe I could consider it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants