3个版本
0.1.2 | 2021年5月18日 |
---|---|
0.1.1 | 2021年3月24日 |
0.1.0 | 2021年3月3日 |
在 Rust模式 中排名第 909
每月下载量 25
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_invoke
和post_invoke
来在调用任务前后运行代码,或者重写do_invoke
来精确控制任务的调用方式,默认情况下,如果没有提供模式,则简单地调用任务;如果提供了模式,则调用crate::invoke
。
pre_invoke
和post_invoke
的调用由invoke_with_mode_optional
管理,这是invoke_with_mode
和invoke
使用的函数,并内部调用do_invoke
。因此,如果实现者重写了invoke_with_mode_optional
,他们必须管理调用pre_invoke
和post_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
不同,Modes
和 ModeWrappers
可以泛型地处理它们可能包装的任务的返回类型,因此可以直接与任务的返回值交互。这也意味着模式的生存期与它们泛型的类型的生存期相关联。
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
不同,Modes
和 ModeWrappers
可以泛型地处理它们可能包装的任务的返回类型,因此可以直接与任务的返回值交互。这也意味着模式的生存期与它们泛型的类型的生存期相关联。
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