Rust 如何查找tokio::sync::mpsc::Receiver是否已关闭?
我有一个循环,在那里我做一些工作,并将结果发送给发送者。这项工作需要时间,如果失败,我需要重试。有可能在我重试时,接收器已关闭,我的重试将是浪费时间。因此,我需要一种方法来检查接收器是否可用,而无需发送消息 在理想情况下,我希望我的代码在伪代码中如下所示:Rust 如何查找tokio::sync::mpsc::Receiver是否已关闭?,rust,future,rust-tokio,Rust,Future,Rust Tokio,我有一个循环,在那里我做一些工作,并将结果发送给发送者。这项工作需要时间,如果失败,我需要重试。有可能在我重试时,接收器已关闭,我的重试将是浪费时间。因此,我需要一种方法来检查接收器是否可用,而无需发送消息 在理想情况下,我希望我的代码在伪代码中如下所示: let (tx, rx) = tokio::sync::mpsc::channel(1); tokio::spawn(async move { // do som stuff with rx and drop it after som
let (tx, rx) = tokio::sync::mpsc::channel(1);
tokio::spawn(async move {
// do som stuff with rx and drop it after some time
rx.recv(...).await;
});
let mut attempts = 0;
loop {
if tx.is_closed() {
break;
}
if let Ok(result) = do_work().await {
attempts = 0;
let _ = tx.send(result).await;
} else {
if attempts >= 10 {
break;
} else {
attempts += 1;
continue;
}
}
};
问题是发送方没有is_closed方法。它有pub fn poll_ready&mut self,cx:&mut Context发送方有一个方法:
尝试立即在此发件人上发送邮件
此方法与发送不同,它在通道缓冲区已满或没有接收器等待获取某些数据时立即返回。与send相比,该功能有两种故障情况,而不是一种断开连接,一种是满缓冲区
使用它而不是发送并检查错误:
如果让ErrTrySendError::Closed_uz=tx.sendresult.await{
打破
}
可以使用期货板条箱中的poll_fn做您想要做的事情。它使用函数returning Poll来返回未来
使用futures::future::poll\u fn;//0.3.5
使用std::future::future;
使用tokio::sync::mpsc::{channel,error::ClosedError,Sender};//0.2.22
使用tokio::time::delay_;//0.2.22
fn等待_,直到_准备好impl Future+'a{
poll_fnmove | cx | sender.poll_readycx
}
[tokio::main]
异步fn主{
让mut tx,mut rx=通道::1;
东京:异步移动{
//接收一个值并关闭通道;
让val=rx.recv.wait;
println!{:?},val;
};
等待,直到准备就绪&mut tx.wait.unwrap;
tx.send123.wait.unwrap;
等待,直到准备就绪&mut tx.wait.unwrap;
延迟时间::时间::持续时间::从秒开始等待;
tx.send456.await.unwrap;//456可能从未打印出来,
//尽管有积极的反应
//发送成功了吗
}
然而,请注意,在一般情况下,这容易受到影响。即使发送方的poll_ready在通道中保留了一个插槽供以后使用,也有可能在就绪检查和实际发送之间关闭接收端。我试图在代码中指出这一点。发件人有一个方法:
尝试立即在此发件人上发送邮件
此方法与发送不同,它在通道缓冲区已满或没有接收器等待获取某些数据时立即返回。与send相比,该功能有两种故障情况,而不是一种断开连接,一种是满缓冲区
使用它而不是发送并检查错误:
如果让ErrTrySendError::Closed_uz=tx.sendresult.await{
打破
}
可以使用期货板条箱中的poll_fn做您想要做的事情。它使用函数returning Poll来返回未来
使用futures::future::poll\u fn;//0.3.5
使用std::future::future;
使用tokio::sync::mpsc::{channel,error::ClosedError,Sender};//0.2.22
使用tokio::time::delay_;//0.2.22
fn等待_,直到_准备好impl Future+'a{
poll_fnmove | cx | sender.poll_readycx
}
[tokio::main]
异步fn主{
让mut tx,mut rx=通道::1;
东京:异步移动{
//接收一个值并关闭通道;
让val=rx.recv.wait;
println!{:?},val;
};
等待,直到准备就绪&mut tx.wait.unwrap;
tx.send123.wait.unwrap;
等待,直到准备就绪&mut tx.wait.unwrap;
延迟时间::时间::持续时间::从秒开始等待;
tx.send456.await.unwrap;//456可能从未打印出来,
//尽管有积极的反应
//发送成功了吗
}
然而,请注意,在一般情况下,这容易受到影响。即使发送方的poll_ready在通道中保留了一个插槽供以后使用,也有可能在就绪检查和实际发送之间关闭接收端。我试图在代码中指出这一点。发送一条接收方忽略的空消息。它可能是任何东西。例如,如果您现在发送T,您可以将其更改为Option,并让接收者忽略Nones
是的,这会管用的,尽管我不太喜欢这种方法,因为我需要改变沟通方式
我不会对沟通方式挂断电话。这不是一个定义良好的网络协议,应该与实现细节隔离;这是您自己的两段代码之间的内部通信机制。发送一条接收方忽略的空消息。它可能是任何东西。例如,如果您现在发送T,您可以将其更改为Option,并让接收者忽略Nones
是的,这会管用的,尽管我不太喜欢这种方法,因为我需要改变沟通方式 我不会对沟通方式挂断电话。这不是一个定义良好的网络协议
与实施细节隔离;这是您自己的两段代码之间的内部通信机制。但我没有要发送的值。这就是问题所在。在获取和发送之前,我需要知道是否还需要值。如果我有一个值,我就不会对旧的常规发送方法有问题。我已经使用poll_ready更新了我的答案,并提供了一个可能的解决方案。但是我没有要发送的值。这就是问题所在。在获取和发送之前,我需要知道是否还需要值。如果我有一个值,我就不会对旧的常规发送方法有问题。我已经使用poll_ready更新了我的答案,并提供了一个可能的解决方案。是的,这会起作用,尽管我不太喜欢这种方法,因为我需要更改通信格式。是的,这会起作用,虽然我不太喜欢这种方式,因为我需要改变沟通方式。