#Creating a background thread or run loop

4 messages · Page 1 of 1 (latest)

dark valley
#

(I'm both a Rust and Tauri noob, so apologies...)

I'm building a desktop app. I'd like to have a background thread / run loop that continually checks a local sqlite db and picks up unprocessed rows to perform some work on. The starting/stopping of this background work should be controlled from the frontend, but the work will all be performed in rust.

My first idea looks like this, but doesn't compile because I'm passing state into the async_runtime::spawn. How should I be approaching this problem please?

#[derive(Default)]
pub struct RunnerState {
    is_running: Arc<Mutex<bool>>,
}

pub fn init<R: Runtime>() -> TauriPlugin<R> {
    Builder::new("runner")
        .setup(|app, _api| {
            app.manage(RunnerState::default());
            Ok(())
        })
        .invoke_handler(tauri::generate_handler![start])
        .build()
}

fn run_loop(state: tauri::State<'_, RunnerState>) {
    if !*state.is_running.lock().unwrap() {
        println!("Runner stopped");
        return;
    }
    tauri::async_runtime::spawn(async move {
        // Do some work here
        thread::sleep(time::Duration::from_secs(5));
        run_loop(state);
    });
}

#[tauri::command]
async fn start(state: tauri::State<'_, RunnerState>) -> Result<(), String> {
    if *state.is_running.lock().unwrap() {
        println!("Already running");
    } else {
        *state.is_running.lock().unwrap() = true;
        println!("Runner started");
        run_loop(state);
    }
    Ok(())
}
keen fossil
#

If I understand this correctly, you just need a function that spawns a new thread and inside the thread, you can use a while loop or tokio::select!, query your db, and do the work. That means you don't need to pass state to the thread.

Not sure if you need the thread to run constantly, or if it's going to stop and restart.

dark valley
#

Correct, I probably don't need access to the state that I've created here. However, I would like to have access to db connection state(?) (probably need to maintain a single connection to the sqlite db).

vocal needle
#

Take an AppHandle insted of State. From the AppHandle you can fetch the State later.