#任务执行 #任务 #同步 #exec #键值

exec-rs

提供任务执行实用特质的库,如果启用sync功能,则可以根据键的值同步任务。

3个版本

0.1.2 2021年5月18日
0.1.1 2021年3月24日
0.1.0 2021年3月3日

Rust模式 中排名第 909

每月下载量 25

Apache-2.0

50KB
749

exec-rs

Rust版本的相应kotlin库

提供任务执行实用特质的库,如果启用sync功能,则可以根据键的值同步任务。

安装

要将exec-rs添加到您的项目,只需添加以下Cargo依赖项

[dependencies]
exec-rs = "0.1.2"

或者要排除"sync"功能

[dependencies.exec-rs]
version = "0.1.2"
default-features = false

执行器

提供两种不同类型,可以根据使用情况管理任务执行。

调用者

pub trait Invoker {

    fn pre_invoke(&self);

    fn invoke_with_mode<'f, T: 'f, F: FnOnce() -> T + 'f>(
        &'f self,
        mode: &'f Mode<'f, T>,
        task: F,
    ) -> T;

    fn invoke<'f, T: 'f, F: FnOnce() -> T + 'f>(&'f self, task: F) -> T;

    fn invoke_with_mode_optional<'f, T: 'f, F: FnOnce() -> T + 'f>(
        &'f self,
        mode: Option<&'f Mode<'f, T>>,
        task: F,
    ) -> T;

    fn do_invoke<'f, T: 'f, F: FnOnce() -> T + 'f>(
        &'f self,
        mode: Option<&'f Mode<'f, T>>,
        task: F,
    ) -> T;

    fn post_invoke(&self);

    fn invoke_post_invoke_on_panic(&self) -> bool;

    fn and_then<I: Invoker>(self, inner: I) -> CombinedInvoker<Self, I>;
}

可以用于实现类型,这些类型管理执行任务而不关心任务返回类型。实现者可以简单地重写pre_invokepost_invoke来在调用任务前后运行代码,或者重写do_invoke来精确控制任务的调用方式,默认情况下,如果没有提供模式,则简单地调用任务;如果提供了模式,则调用crate::invoke

pre_invokepost_invoke的调用由invoke_with_mode_optional管理,这是invoke_with_modeinvoke使用的函数,并内部调用do_invoke。因此,如果实现者重写了invoke_with_mode_optional,他们必须管理调用pre_invokepost_invoke或者不使用这些函数。

模式

模式API由3部分组成:Mode、ModeWrapper和ModeCombiner。

模式

pub struct Mode<'m, T: 'm> {
    mode_combiner: Option<Box<dyn ModeCombiner<'m, T> + 'm>>,
}

结构,用于收集和组合ModeWrapper。这是提交任务时提供的类型,用于应用ModeWrappers

可以通过实现 ModeWrapper 特性来使用模式,以便在包围函数中包装任务。与 Invokers 不同,ModesModeWrappers 可以泛型地处理它们可能包装的任务的返回类型,因此可以直接与任务的返回值交互。这也意味着模式的生存期与它们泛型的类型的生存期相关联。

ModeWrapper

pub trait ModeWrapper<'m, T: 'm> {

    fn wrap(self: Arc<Self>, task: Box<dyn FnOnce() -> T + 'm>) -> Box<dyn FnOnce() -> T + 'm>;

    fn into_combiner(self) -> Box<dyn ModeCombiner<'m, T> + 'm>;
}

要应用模式到任务,需要实现此特性。ModeWrappers 通过使用 Mode::with 传递给 Mode,在这里它们可以使用 ModeWrapper::into_combiner 供应的 ModeCombiner 与其他 ModeWrappers 结合。与 Invokers 不同,ModesModeWrappers 可以泛型地处理它们可能包装的任务的返回类型,因此可以直接与任务的返回值交互。这也意味着模式的生存期与它们泛型的类型的生存期相关联。

ModeCombiner

pub trait ModeCombiner<'m, T: 'm> {

    fn combine(
        &self,
        other: Box<dyn ModeCombiner<'m, T> + 'm>,
    ) -> Box<dyn ModeCombiner<'m, T> + 'm>;

    fn get_outer(&self) -> Option<&dyn ModeCombiner<'m, T>>;

    fn set_outer(&mut self, outer: Arc<dyn ModeCombiner<'m, T> + 'm>);

    fn iter<'a>(&'a self) -> ModeCombinerIterator<'a, 'm, T>;

    fn wrapper_ref(&self) -> Arc<dyn ModeWrapper<'m, T> + 'm>;
}

用于组合 ModeWrappers 的特性,它允许一个 ModeWrapper 将职责委托给另一个 ModeWrapper,并提供一个可以解包组合的 ModeWrappers 的迭代器。此特性的实现由 ModeWrapper::into_combiner 返回,默认返回一个 DelegatingModeCombiner

Sync

sync 模块提供了 MutexSync 结构体,它可以用来通过提交任务时提供的键值来执行和同步任务。

pub struct MutexSync<K>
where
    K: 'static + Sync + Send + Clone + Hash + Ord,
{
    mutex_map: flurry::HashMap<K, ReferenceCountedMutex<K>>,
}

impl<K> MutexSync<K>
where
    K: 'static + Sync + Send + Clone + Hash + Ord,
{
    pub fn new() -> Self;

    pub fn evaluate<R, F: FnOnce() -> R>(&self, key: K, task: F) -> R;
}

可以通过提交任务时提供的键值来同步任务的执行。

例如,如果使用 i32 作为键类型,那么带有键值 3 和 5 的任务可以并发运行,但带有键值 7 的多个任务将通过映射到键的互斥锁进行同步。

管理一个并发哈希映射,该映射将 ReferenceCountedMutex 元素映射到使用的键。该 ReferenceCountedMutex 结构体包含用于同步的互斥锁,并通过管理一个原子引用计数器自动从映射中删除,如果没有任何线程再使用它。如果计数器从 1 减少到 0,则将元素从映射中删除,并且计数器不能再次增加。如果计数器达到 0,则未来的增加尝试失败,并创建一个新的 ReferenceCountedMutex。当创建一个新的 ReferenceCountedMutex 并将其插入映射失败,因为另一个线程已经为相同的键创建了元素时,当前线程会尝试使用找到的现有元素,只要其引用计数器有效(大于 0),否则会重试创建元素。

用于同步的键类型必须能够用作映射的键,因此必须实现 Sync + Send + Clone + Hash + Ord 并且具有静态生存期。

依赖项

~0–485KB