#future #async #background #background-task #experiment #metadata #group

no-std async-let

基于康拉德·卢德盖特的想法的一个实验

1 个不稳定版本

0.1.0 2023年12月23日

#219 in 无标准库

MIT/Apache

22KB
181

此 crate 将 async-let 实现为一个 #[no_std],无安全风险,无恐慌,开销最小的库。

Async-let 是基于康拉德·卢德盖特从 https://conradludgate.com/posts/async-let 的想法进行的实验,它提出了一种语法,允许 futures 在不启动额外任务的情况下“在后台”运行。async-let 的一般行为是,以下(虚构的)语法

async let metadata = client.request_metadata();

将 future 标记为后台 future。绑定和 data.await 之间的任何 await 点都将轮询 data 以及被等待的 future。

// `metadata` is marked as a background future here
async let metadata = client.request_metadata();

// both `data` and `metadata` are polled while awaiting `data`
let data = client.request_data().await;

// unmark `metadata` as a background future and await it
let metadata = metadata.await;

使用此 crate 的 API,上述内容可以写成这样。

// create a group that will drive the background futures
let group = async_let::Group::new();

// mark `metadata` as a background future by attaching it to the group
let metadata = pin!(client.request_metadata());
let (metadata, group) = group.attach(metadata);

// await `data` using the group, which polls the background futures
let data = group.wait_for(client.request_data()).await;

// detach `metadata` from the group and await it
let (metadata, group) = group.detach_and_wait_for(metadata).await;

API

此 crate 提供的主要类型有 Group<List>,一种管理驱动静态类型 List 的后台 futures 的类型;以及 Handle<Fut>,一种抽象的句柄,代表提取类型为 Fut 的后台 future 的能力。attach 方法将 future 添加到后台 futures 的列表中,detach 方法删除 future,而 wait_for 方法产生一个当被轮询时会轮询后台 futures 的 future。

为了最小化跟踪后台 futures 的开销,每个 Group 都关联一组固定的 futures。将 future 添加到组或从组中删除 future 会消耗组,并产生一个新的组,其中包含添加到或从后台 futures 集合中删除的 future。

限制

在追求最小开销的过程中,做出了一些权衡。

  • 易用性:虽然 API 被设计得尽可能易用,但调用者仍需要手动添加和删除 futures,在每个操作中通过组传递线程,并显式本地固定 futures。
  • 固定:由于一个组将它的未来列表内联存储,所以存储的未来必须是 Unpin。需要固定的未来必须通过间接引用来存储,例如使用 pin!Box::pin
  • 生命周期:当一个未来被附加或分离时,组必然会被移动。如果未来在一个嵌套的作用域中附加,必须在离开该作用域之前将其分离,否则组(及其所有附加的未来)将变得不可访问。
  • 分支:由于未来的集合是静态跟踪的,因此如果希望在条件之后组仍然可访问,则不可能仅在条件的某一分支中附加未来。可以通过将附加的未来的类型擦除为 dyn Future<Output = X> 来在组的同一位置附加不同类型的未来,但这有其局限性。

依赖

~46KB