如何在异步东京运行时使用future::join_all与多路复用的redis
我尝试在异步多路复用模式下使用,作为异步运行时,并动态加入未来数 我成功地在固定数量的future上使用了如何在异步东京运行时使用future::join_all与多路复用的redis,redis,rust,async-await,rust-tokio,Redis,Rust,Async Await,Rust Tokio,我尝试在异步多路复用模式下使用,作为异步运行时,并动态加入未来数 我成功地在固定数量的future上使用了future::join3,但我想复用更多的命令(编译时不必知道具体的大小,但即使这样也会有所改进) 这是使用future::join3时的工作示例;该示例正确地打印 Ok(一些(“PONG”))Ok(一些(“PONG”))Ok(一些(“PONG”)) Cargo.toml [package] name = "redis_sample" version = "0
future::join3
,但我想复用更多的命令(编译时不必知道具体的大小,但即使这样也会有所改进)
这是使用future::join3
时的工作示例;该示例正确地打印
Ok(一些(“PONG”))Ok(一些(“PONG”))Ok(一些(“PONG”))
Cargo.toml
[package]
name = "redis_sample"
version = "0.1.0"
authors = ["---"]
edition = "2018"
[dependencies]
redis = { version = "0.17.0", features = ["aio", "tokio-comp", "tokio-rt-core"] }
tokio = { version = "0.2.23", features = ["full"] }
futures = "0.3.8"
src/main.rs
use futures::{future, Future};
use std::pin::Pin;
use redis::RedisResult;
const BATCH_SIZE: usize = 10;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let redis_client = redis::Client::open("redis://127.0.0.1:6379")?;
let redis_connection = redis_client.get_multiplexed_tokio_connection().await?;
let mut commands: Vec<Pin<Box<dyn Future<Output = RedisResult<Option<String>>>>>> = vec![];
for _ in 0..BATCH_SIZE {
commands.push(Box::pin(redis::cmd("PING").query_async(& mut redis_connection.clone())));
}
let results = future::join_all(commands).await;
println!("{:?}", results);
Ok(())
}
使用期货::未来;
使用redis::RedisResult;
#[tokio::main]
异步fn main()->结果{
让redis_client=redis::client::open(“redis://127.0.0.1:6379")?;
让mut redis_connection=redis_client.get_multiplexed_tokio_connection().wait?;
让结果:(RedisResult,RedisResult,RedisResult)=未来::join3(
redis::cmd(“PING”).query\u async(&mut redis\u connection.clone()),
redis::cmd(“PING”).query\u async(&mut redis\u connection.clone()),
redis::cmd(“PING”).query\u异步(&mut redis\u连接),
).等待;
println!(“{:?}{:?}{:?}”,results.0,results.1,results.2);
好(())
}
现在我想做同样的事情,但是使用
n
命令(比方说10个,但理想情况下我想根据生产中的性能调整)。这是我所能做到的,但我无法克服借款规则;我尝试将一些中介体(redisCmd
或future本身)存储在Vec中以延长它们的寿命,但这也存在其他问题(使用多个mut
引用)
Cargo.toml
是相同的;这里是main.rs
use futures::{future, Future};
use std::pin::Pin;
use redis::RedisResult;
const BATCH_SIZE: usize = 10;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let redis_client = redis::Client::open("redis://127.0.0.1:6379")?;
let redis_connection = redis_client.get_multiplexed_tokio_connection().await?;
let mut commands: Vec<Pin<Box<dyn Future<Output = RedisResult<Option<String>>>>>> = vec![];
for _ in 0..BATCH_SIZE {
commands.push(Box::pin(redis::cmd("PING").query_async(& mut redis_connection.clone())));
}
let results = future::join_all(commands).await;
println!("{:?}", results);
Ok(())
}
感谢您的帮助 这应该行得通,我刚刚延长了
redis\u连接的生命周期
使用期货:{future,future};
使用std::pin::pin;
使用redis::RedisResult;
常量批量大小:usize=10;
#[tokio::main]
异步fn main()->结果{
让redis_client=redis::client::open(“redis://127.0.0.1:6379")?;
让redis_connection=redis_client.get_multiplexed_tokio_connection().等待?;
让mut命令:Vec=Vec![];
对于0.批次大小中的u{
让mut redis_connection=redis_connection.clone();
commands.push(Box::pin)(异步移动{
redis::cmd(“PING”)。查询异步(&mut redis\u连接)。等待
}));
}
让results=future::join_all(命令)。等待;
println!(“{:?}”,结果);
好(())
}
由于您位于函数体内部,甚至不需要对未来进行装箱,因此类型推断可以完成所有工作:
使用期货::未来;
使用redis::RedisResult;
常量批量大小:usize=10;
#[tokio::main]
异步fn main()->结果{
让redis_client=redis::client::open(“redis://127.0.0.1:6379")?;
让redis_connection=redis_client.get_multiplexed_tokio_connection().等待?;
让mut commands=vec![];
对于0.批次大小中的u{
让mut redis_connection=redis_connection.clone();
命令。推送(异步移动){
redis::cmd(“PING”)。查询异步::(&mut redis\u连接)。等待
});
}
让results=future::join_all(命令)。等待;
println!(“{:?}”,结果);
好(())
}
谢谢!第一个例子效果很好,太棒了。您介意再描述一下为什么需要异步移动吗{
以及为什么要存储的结果。wait
,或者可能链接到某个地方的书/解释?我可能看错了未来,但我认为。wait
要等到将来完成。不幸的是,第二个示例没有为我编译,redis::cmd(“PING”)上有两个编译器错误.query_async
行-两者都是:错误[E0698]:在此上下文中必须知道'async'块内部的类型
谢谢!我需要异步移动才能将redis连接移动到未来。否则,未来将借用redis连接,但这将出错,因为未来需要比redis连接更长寿-它需要比循环的一次迭代更长寿。是的,你是对的等待等待直到未来完成,但是异步块创建了一个新的未来,因此不会立即运行。我将修复答案以使其编译。