#future #mutex #oneshot-channel #borrowing #mutation #async #owner

potential

未来借用 - Potential 允许通过互斥锁和异步借用(租赁)通过 oneshot 通道进行内部突变

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并发

Download history 83/week @ 2024-03-11 78/week @ 2024-03-18 53/week @ 2024-03-25 45/week @ 2024-04-01 101/week @ 2024-04-08 86/week @ 2024-04-15 104/week @ 2024-04-22 119/week @ 2024-04-29 122/week @ 2024-05-06 178/week @ 2024-05-13 126/week @ 2024-05-20 207/week @ 2024-05-27 305/week @ 2024-06-03 116/week @ 2024-06-10 121/week @ 2024-06-17 58/week @ 2024-06-24

603 每月下载量
用于 3 个 crates(通过 samotop-delivery

MIT/Apache

25KB
291

Build Status Maintenance

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