我可以克隆未来吗?
Can I clone a future?
我想为将来编写一些通用的重试逻辑。
我知道具体的 return 类型,想重试相同的未来。
我的代码只能访问未来 - 我不想将每个 fn 调用站点包装在一个闭包中以重新创建它。
好像一个“future”是(fn, args)的组合,当.await
被调用时,它就运行并等待结果。
如果我能够克隆所有 args,是否可以创建一个未开始的 future 的克隆以在第一次失败时重试?
问题在于,尚未开始的未来与已经开始的未来属于同一类型——未来会就地转换自身。因此,虽然理论上 Future
可以 是 Clone
,但这将对其在其整个生命周期中允许保持的状态施加严格的限制。对于使用 async fn
实现的期货,不仅初始状态(传递给 async fn
的参数)必须是 Clone
,而且跨 .await
的所有局部变量也必须是 Clone
点.
一个简单的实验表明,当前的 async
不会像它那样自动实现 Clone
,例如Send
,即使对于安全的异步函数也是如此。例如:
async fn retry(f: impl Future + Clone) {
todo!()
}
fn main() {
// fails to compile:
retry(async {});
// ^^^^^^^^ the trait `Clone` is not implemented for `impl Future`
}
I do not want to wrap every fn call site in a closure to enable recreating it.
在这种情况下,这可能正是您需要做的。或者,如果闭包需要太多样板文件,则使用某种宏。
可以通过 https://docs.rs/futures/latest/futures/future/trait.FutureExt.html#method.shared 克隆 Future
。这对于将未来传递给多个消费者很有用,但不适合重试。
要重试 Futures,您需要某种 Future
工厂,以便在发生错误时创建新的 Future
进行重试。理想情况下,此重试机制将包装在自己的 Future 中,以隐藏消费者的复杂性。
已经有一个箱子可以做到这一点:https://docs.rs/futures-retry/latest/futures_retry/struct.FutureRetry.html
我想为将来编写一些通用的重试逻辑。
我知道具体的 return 类型,想重试相同的未来。
我的代码只能访问未来 - 我不想将每个 fn 调用站点包装在一个闭包中以重新创建它。
好像一个“future”是(fn, args)的组合,当.await
被调用时,它就运行并等待结果。
如果我能够克隆所有 args,是否可以创建一个未开始的 future 的克隆以在第一次失败时重试?
问题在于,尚未开始的未来与已经开始的未来属于同一类型——未来会就地转换自身。因此,虽然理论上 Future
可以 是 Clone
,但这将对其在其整个生命周期中允许保持的状态施加严格的限制。对于使用 async fn
实现的期货,不仅初始状态(传递给 async fn
的参数)必须是 Clone
,而且跨 .await
的所有局部变量也必须是 Clone
点.
一个简单的实验表明,当前的 async
不会像它那样自动实现 Clone
,例如Send
,即使对于安全的异步函数也是如此。例如:
async fn retry(f: impl Future + Clone) {
todo!()
}
fn main() {
// fails to compile:
retry(async {});
// ^^^^^^^^ the trait `Clone` is not implemented for `impl Future`
}
I do not want to wrap every fn call site in a closure to enable recreating it.
在这种情况下,这可能正是您需要做的。或者,如果闭包需要太多样板文件,则使用某种宏。
可以通过 https://docs.rs/futures/latest/futures/future/trait.FutureExt.html#method.shared 克隆 Future
。这对于将未来传递给多个消费者很有用,但不适合重试。
要重试 Futures,您需要某种 Future
工厂,以便在发生错误时创建新的 Future
进行重试。理想情况下,此重试机制将包装在自己的 Future 中,以隐藏消费者的复杂性。
已经有一个箱子可以做到这一点:https://docs.rs/futures-retry/latest/futures_retry/struct.FutureRetry.html