2 个不稳定版本
| 0.2.2 | 2023 年 1 月 23 日 | 
|---|---|
| 0.2.1 |  | 
| 0.2.0 |  | 
| 0.1.0 | 2023 年 1 月 21 日 | 
1584 在 Rust 模式
25KB
395 行
context-rs
Go 一直建议你在异步上下文中的所有函数,如 Web 服务器,提供一个 ctx context.Context 参数。这对于将截止日期等信息传递到调用栈中很有用,以便允许叶函数安排关闭。
Rust 已经为所有异步函数自动传递了一个上下文值,这已经命名为 Context,但它功能强大——只提供一个 '唤醒' 处理程序。
通过使用 nightly Provider API,我们可以修改这个上下文,以在调用栈中按需提供值。这避免了使用 thread_locals,这需要 std,或者在每个函数调用中传递一个 TypeMap,这既不直观又需要 alloc。
示例
使用 get_value 和 provide_ref 展示异步截止日期的示例
use context_rs::{get_value, ProviderFutExt};
use std::time::{Instant, Duration};
// New type makes it easier to have unique keys in the context
#[derive(Clone)]
struct Deadline(Instant);
#[derive(Debug, PartialEq)]
struct Expired;
impl Deadline {
    // check if the deadline stored in the context has expired
    // returns OK if no deadline is stored.
    async fn expired() -> Result<(), Expired> {
        get_value().await.map(|Deadline(deadline)| {
            // if there is a deadline set, check if it has expired
            if deadline < Instant::now() {
                Err(Expired)
            } else {
                Ok(())
            }
        }).unwrap_or(Ok(())) // or ignore it if no deadline is set
    }
}
// some top level work - agnostic to the context
async fn some_work() -> Result<(), Expired> {
    loop {
        some_nested_function().await?
    }
}
// some deeply nested work, cares about the deadline context
async fn some_nested_function() -> Result<(), Expired> {
    // will acquire the deadline from the context itself
    Deadline::expired().await?;
    // do some logic in here
    Ok(())
}
#[tokio::main]
async fn main() {
    // timeout in 2 seconds
    let deadline = Instant::now() + Duration::from_secs(2);
    let res = some_work().provide_ref(&Deadline(deadline)).await;
    assert_eq!(res, Err(Expired));
}
如果你只需要临时访问值,并且你想要的值很昂贵,你可以使用 with_ref 而不是 get_value。这将接受一个闭包,该闭包接受提供的引用,具有短暂的生存期。
依赖关系
~0–1.2MB
~20K SLoC