#Solved - Issues with shared data using Tokio

6 messages · Page 1 of 1 (latest)

rugged obsidian
#

I'm trying to use this API for interacting with twitch, but I've also never used Tokio before, so I don't know a way around this (probably) common issue.
Inside the tokio::spawn task is where all of the messages get parsed, but I need a reference to client to be able to send messages, and (I think) it gets moved in the thread if I put it in there.

This code is pretty much a copy of the example code given in the crate's docs: https://docs.rs/twitch-irc/5.0.1/twitch_irc/#getting-started

use twitch_irc::{
    login::StaticLoginCredentials, message::ServerMessage, ClientConfig, SecureTCPTransport,
    TwitchIRCClient,
};

const CONFIG_FILE_NAME: &str = "config.txt";

#[tokio::main]
pub async fn main() {
    let user_config = parse_config(CONFIG_FILE_NAME).unwrap();

    let (mut incoming_messages, client) =
        TwitchIRCClient::<SecureTCPTransport, StaticLoginCredentials>::new((&user_config).into());

    let streamer_username = user_config.streamer_account_name;

    let join_handle = tokio::spawn(async move {
        while let Some(message) = incoming_messages.recv().await {
            if let ServerMessage::Privmsg(message) = message {
                println!("{:#?}\n", message);

                // I need `client` here to send messages that use data from chat messages
                client.say_in_reply_to(&message, "Hello!".to_owned()).await.unwrap();
            }
        }
    });

    // I also need `client` here to send general messages and to join the channel
    client.say(
            streamer_username.clone(),
            "Bot Connected!".to_owned(),
        ).await.unwrap();

    client.join(streamer_username.clone()).unwrap();

    join_handle.await.unwrap();
}```
#

The compiler error is completely useless; it says I should clone a code block

error[E0382]: borrow of moved value: `client`
  --> src\main.rs:30:2
   |
13 |       let (mut incoming_messages, client) =
   |                                   ------ move occurs because `client` has type `TwitchIRCClient<TCPTransport<TLS>, StaticLoginCredentials>`, which does not implement the `Copy` trait
...
20 |       let join_handle = tokio::spawn(async move {
   |  ____________________________________-
21 | |         while let Some(message) = incoming_messages.recv().await {
22 | |             if let ServerMessage::Privmsg(message) = message {
23 | |                 println!("{:#?}\n", message);
24 | |
25 | |                 client.say_in_reply_to(&message, "Hello!".to_owned()).await.unwrap();
   | |                 ------ variable moved due to use in generator
26 | |             }
27 | |         }
28 | |     });
   | |_____- value moved here
29 |
30 |       client
   |       ^^^^^^ value borrowed here after move
   |
help: consider cloning the value if the performance cost is acceptable
   |
28 |     }.clone());
   |      ++++++++```
#

Also some part of me is confused because all of the methods called on config are &self, so they should be runnable in parallel, right? Maybe tokio does something different

terse trail
#

Just to be clear: "cloning a code block" is perfectly valid, though I don't think it would save you here.

#

all you have to do here is to clone the client before moving it into the async closure

rugged obsidian
#

I figured that wouldn't work because I figured the client wouldn't work once cloned, but it did. Thanks