如何在多线程中使用RpcClient

How to use RpcClient in multiple threads

我正在编写一个程序,它可以在终端中打印出您的 SOL 余额,但在获取它时会显示一个加载指示器。我正在使用 solana_client 箱子中的 RpcClient 来获取我的 SOL 余额,但是在一个新线程上,所以我可以在请求为 运行.

时在主线程上旋转加载指示器

我的问题是,如果我尝试在传递给 thread::spawn():

的函数中使用 RpcClient 的指针,我会收到错误消息
fn main() {
    let url = "https://api.testnet.solana.com".to_string();
    let client = RpcClient::new(url);
    let pubkey = Pubkey::from_str(ADDRESS).unwrap();

    get_balance(&client, &pubkey);
}

fn get_balance(client: &RpcClient, pubkey: &Pubkey) {
    let (tx, rx): (Sender<u64>, Receiver<u64>) = mpsc::channel();
    let pubkey = pubkey.clone();
    thread::spawn(move || {
        let balance = client.get_balance(&pubkey).unwrap();
        tx.send(balance)
            .expect("failed to send back result throught tx channel");
    });
    let balance = spin(rx);
    println!("balance: {}", balance);
}

错误:

error[E0759]: `client` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
   --> src/main.rs:24:19
    |
21  |   fn get_balance(client: &RpcClient, pubkey: &Pubkey) {
    |                          ---------- this data with an anonymous lifetime `'_`...
...
24  |       thread::spawn(move || {
    |  ___________________^
25  | |         let balance = client.get_balance(&pubkey).unwrap();
26  | |         tx.send(balance)
27  | |             .expect("failed to send back result throught tx channel");
28  | |     });
    | |_____^ ...is used here...
    |

我试图将 client 变量设为静态,但这导致了另一个错误:

...
    let client: &'static RpcClient = &RpcClient::new(url);
...
fn get_balance(client: &'static RpcClient, pubkey: &Pubkey) {
...

error[E0716]: temporary value dropped while borrowed
  --> src/main.rs:15:39
   |
15 |     let client: &'static RpcClient = &RpcClient::new(url);
   |                 ------------------    ^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
   |                 |
   |                 type annotation requires that borrow lasts for `'static`
...
19 | }
   | - temporary value is freed at the end of this statement

如果我尝试在 get_balance 函数中克隆 client,我会得到同样的错误,就像我在 pubkey.

中所做的那样

我可以通过传递 url 并在线程内创建一个新的 RpcClient 来解决这个问题,但我试图理解为什么我当前的实现不起作用,以及我如何使用线程时应该处理此类问题。

感谢 我能够通过将客户端包装在 Arc:

中来解决问题
fn main() {
    let url = "https://api.testnet.solana.com".to_string();
    let client = Arc::new(RpcClient::new(url));
    let pubkey = Pubkey::from_str(ADDRESS).unwrap();
    get_balance(&client, &pubkey);
}

fn get_balance(client: &Arc<RpcClient>, pubkey: &Pubkey) {
    let (tx, rx): (Sender<u64>, Receiver<u64>) = mpsc::channel();
    let client = client.clone();
    let pubkey = pubkey.clone();
    thread::spawn(move || {
        let balance = client.get_balance(&pubkey).unwrap();
        tx.send(balance)
            .expect("failed to send back result throught tx channel");
    });
    let balance = spin(rx);
    println!("balance: {}", balance);
}

我还发现 帮助我理解了为什么我的原始代码不起作用。