克隆 tokio 频道发件人以关闭期货的替代方法

Alternative to cloning tokio channel's sender for futures' closures

我正在使用 tokiohyper 来生成多个任务。

// Defining the task
let task = self.some_future_using
            .map(move |resp| println!("OK: {}", resp))
            .map_err(move |e| println!("Error: {}",e));

// Spawning the task
tokio::spawn(task);

我不想简单地记录结果,而是想通过有界的 tokio 频道发送结果。

// Defines the channel
let (tx, rx) = mpsc::channel(10);

// Defining the task
let task = self.some_future_using
            .map(|resp| /* Send Ok(resp) to tx */ )
            .map_err(|e| /* Send Err(e) to tx */);

// Spawning the task
tokio::spawn(task);

由于两个闭包都可能比 tx 定义的范围长,我们需要为两个闭包克隆和移动 tx

// Defines the channel
let (tx, rx) = mpsc::channel(10);
let mut tx_ok = tx.clone();
let mut tx_err = tx.clone();

// Defining the task
let task = self.some_future_using
            .map(move |resp| tx_ok.try_send(Ok(())).unwrap() )
            .map_err(move |e| tx_err.try_send(Ok(())).unwrap() );

// Spawning the task
tokio::spawn(task);

在使用组合器(mapand_then 等)添加更多逻辑的情况下,每个闭包都需要它自己的 tx 克隆版本才能使用它。

克隆是唯一的解决办法吗?我们能否在不为使用它的每个已声明闭包克隆通道的发送者的情况下实现相同的目标?

Could we achieve the same without cloning the channel's sender for each declared closure that uses it?

没有。这就是 Sender 的共享方式,没有其他安全的方式可以做到这一点。

通道通过将共享资源包装在 Arc 中来管理共享资源,因此它们可以在线程之间安全地共享。 Sender 的克隆方法涉及一些逻辑,但最终它是关于克隆那些 Arc 的——这就是 Arc 的共享方式。

克隆一个 Arc 很便宜,而且可能不是你应该担心的事情,除非你在一个紧密的循环中克隆它们。一旦它们被克隆,Arc 的开销非常小 - 每个克隆本质上都是一个指针。