5 个稳定版本
2.2.1 | 2020 年 9 月 19 日 |
---|---|
2.2.0 | 2020 年 9 月 16 日 |
2.1.0 | 2020 年 9 月 14 日 |
2.0.0 | 2020 年 9 月 14 日 |
1.0.0 | 2020 年 9 月 11 日 |
#457 在 并发
603 每月下载量
用于 3 个 crates(通过 samotop-delivery)
25KB
291 行
potential 2.2.1
未来借用 - 类似于 Option
,但异步且有返回通道。类似于 Mutex
,补偿了 MutexGuard
不可安全发送。项目从所有者 Potential 移动(租赁)到租赁。当租赁释放时,项目返回到所有者。Potential 的所有者可以等待租赁项目的返回。
它针对异步服务器。用例是某些资源可以或应该被重用,例如 TCP 连接或加密配置或后端存储,但它们需要与未来的未来发送,而未来没有共享资源的 未来 跟踪,除非使用 &mut,因此保证单个副本。使用具有未来生命周期的互斥锁或您使用 Potential,它允许您不将未来的生命周期绑定到源。但是,一次只有一个运行中的未来/任务可以使用该资源。因此,所有者可以控制并发,默认为 1,可以通过重置 Potential 到新值来增加。
如果未正确释放租赁(例如,如果您使用 mem::forget()
它或当其线程严重恐慌时),则 Potential
调用将永远卡住。如果您怀疑可能会发生这种情况,请等待超时以能够恢复。
同步 + 发送未来示例
注意通过不可变引用对 String 的突变,通过租赁初始化潜在,以及未来是同步 + 发送的。租赁上的未来自然序列化(是互斥的)。
use potential::Potential;
use std::future::Future;
use std::task::Poll;
use std::pin::Pin;
#[derive(Default)]
struct Trial {
inner: Potential<String>
}
impl Trial {
async fn back_to_the_future(&self, item:String) -> usize {
let mut lease = match self.inner.lease().await {
Ok(lease) => lease,
Err(gone) => gone.set(String::new())
};
// here some other async work...
lease.extend(item.chars());
lease.len()
}
}
async fn test(trial: &Trial) -> String {
let fut2 = trial.back_to_the_future(" and then".to_owned());
let fut1 = trial.back_to_the_future("now".to_owned());
assert_eq!(fut1.await, 3);
assert_eq!(fut2.await, 12);
trial.inner.lease().await.expect("set").clone()
}
let trial = Trial::default();
let mut fut = test(&trial);
assert_eq!(Box::pin(fut).as_mut().poll(&mut cx()), Poll::Ready("now and then".to_owned()));
is_sync_and_send(test(&trial));
fn is_sync_and_send<T: Sync + Send>(_: T) {};
fn cx() -> std::task::Context<'static> {
let waker = futures_util::task::noop_waker_ref();
let cx = std::task::Context::from_waker(waker);
cx
};
示例:带有 Arc 的 'static + Sync + Send 未来
不确定如何使用 async fn 糖来做到这一点。欢迎提出建议。Self 不能被未来捕获才能正常工作。
use potential::Potential;
use std::sync::Arc;
use std::future::Future;
#[derive(Default)]
struct Trial {
inner: Arc<Potential<String>>
}
impl Trial {
fn back_to_the_static_future(&self, item:String) -> Box<dyn Future<Output = usize> + 'static + Send + Sync> {
let inner = self.inner.clone();
let fut = async move {
let mut lease = match inner.lease_on_arc().await {
Ok(lease) => lease,
Err(gone) => gone.set(String::new())
};
// here some other async work...
lease.extend(item.chars());
lease.len()
};
Box::new(fut)
}
}
let trial = Trial::default();
let fut = trial.back_to_the_static_future("now".to_owned());
is_sync_and_send_and_static(fut);
fn is_sync_and_send_and_static<T: Sync + Send + 'static>(_: T) {};
许可证
MIT 或 Apache-2.0
贡献
除非您明确声明,否则您提交给 samotop 项目以包含的贡献,根据 Apache-2.0 许可证定义,应按上述方式许可,不附加任何其他条款或条件。
依赖关系
~0.7–1MB
~17K SLoC