Search code examples
rustgtk4

How to run child process in a new thread using Rust / Relm4?


I'm using Rust, GTK4-rs and the Relm4 UI framework.

So I have Relm4 SimpleComponent. In its update() method, I have a message handler which spawns a child process to run some task. This is kinda a long running task, so I would like to show a spinner while it's running, then, when it's done, hide the spinner and show a bunch of other widgets (form in gtk:Box)

I know there are multiple ways to handle this with Relm4 / Rust, but since I'm new to both I'm not sure what's the best approach. What do I need here? A worker? Async update function? Something else?

I checked this page: https://aaronerhardt.github.io/relm4-book/book/threads_and_async.html but it's not clear to me how could I implement this using SimpleComponent or something similar. Any help would be appreciated.

Basically I just wanna run something like this in a non-blocking way:

fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
        match message {
            Something::Execute => {
               self.executing = true
                let mut cmd = Command::new("command goes here..");
                ...
                let out = cmd.output().expect("Command failed to start"); // I want this to not block the main thread
                self.executing = false;
                self.output_buf
                    .set_text(&String::from_utf8_lossy(&out.stdout));
                self.error_buf
                    .set_text(&String::from_utf8_lossy(&out.stderr));
            }
        }
    }

Solution

  • Actually it's possible to do this, there are multiple solutions.

    Check out this page for an overview:

    https://relm4.org/book/stable/threads_and_async/index.html

    I used a Component and Commands, basically just as described here:

    https://relm4.org/book/stable/threads_and_async/commands.html