Search code examples
rustatomictauri

Using a Sender as global State in a Tauri Plugin


Issue

I'm attempting to write a relatively large-scale Tauri Application and divide it into plugins as recommended by the Tauri docs.

The only issue being these plugins need to be able to call upon each other.

Since the traditional way in rust to send messages across a program is the std::sync::mpsc::channel, I thought to try using that and put a sender of the plugins specific set of commands in the Tauri global state via AppHandle<R: Runtime>::manage function during the initialisation of each plugin.

The problem with this solution is the manage function require the state to be Send + Sync and the Sender is Send + !Sync.

Code Sample

Initlialise Function

Attempts to put the sender in global state

fn initialize(
    &mut self,
    handle: &tauri::AppHandle<R>,
    config: serde_json::Value,
) -> PluginResult<()> {
    let cfg = Config::from_serde_value(config)?;

    handle.manage(DiscordRichPresence::new_mutex(&cfg.client_id));
    handle.manage(self.sender.clone());

    Ok(())
}

Any ideas as to any wrapper types of a form of "Clone on Read" type that may be able to help?

Happy to provide more code sample if needed to understand better


Solution

  • FIXED:

    the answer is to use tokio::sync::mspc::channel instead of std::sync::mpsc::channel since the tokio one is Send + Sync as opposed to the std Sender which is Send + !Sync.

    just add the following to your Cargo.toml:

    [dependencies]
    tokio = { version = "1.23.0", features = ["sync"] }
    

    However, if you require it to be Synchronous, std::sync::mpsc::sync_channel should also work, though, in the case of Tauri, async is recommended since Tauri is itself built on top of Tokio. and making commands asynchronous is easy.