#flow #reference-counting #logicalcallcontext #callcontext

execution-context

一个受 .NET 启发的实验性执行上下文

1 个不稳定版本

使用旧的 Rust 2015

0.1.0 2018 年 6 月 8 日

#84#reference-counting

Apache-2.0 协议

20KB
254 代码行,不包括注释

Rust 的执行上下文

这实现了受 .NET 启发的执行上下文。想法是,如果这种机制证明性能合理,它可能成为核心语言概念。

什么是执行上下文?

执行上下文是一个逻辑调用流的容器。想法是,任何遵循相同执行流程的代码都可以访问流局部数据。一个有用的例子是安全相关的数据,代码可能希望从操作带到操作,而不会意外地丢弃它。

这是最简单的例子

flow_local!(static TEST: u32 = 42);

assert_eq!(*TEST.get(), 42);
let ec = ExecutionContext::capture();
TEST.set(23);

assert_eq!(*TEST.get(), 23);
ec.run(|| {
    assert_eq!(*TEST.get(), 42);
});

执行上下文可以被转发到其他线程,并提供了一个 API 来临时或永久抑制流传播。


lib.rs:

此软件包实现了一个 Rust 执行上下文。执行上下文通过执行逻辑流传递数据。

这受到了 .NET ExecutionContext 系统的强烈启发,作为一个实验,如果这样的 API 在 Rust 中有意义。

与 .NET 系统的主要区别

  • 这纯粹实现了执行上下文,而不是同步上下文。因此,实现简化了。
  • 这提供了永久禁用流传播的能力。
  • 此软件包将“环境数据”和“异步局部变量”称为“流局部数据”。
  • 捕获始终返回一个执行上下文,即使流被抑制。因此,运行方法不再是静态的,而是存储在实例上。
  • 在底层使用原子引用计数而不是垃圾收集器。这也意味着性能特征将不同。
  • FlowLocal 数据有一个初始化表达式,如果在当前流中没有存储局部数据,则会调用它。

示例用法

#[macro_use]
extern crate execution_context;

use execution_context::ExecutionContext;
use std::env;
use std::thread;

flow_local!(static LOCALE: String = env::var("LANG").unwrap_or_else(|_| "en_US".into()));

fn main() {
    println!("the current locale is {}", LOCALE.get());
    LOCALE.set("de_DE".into());
    println!("changing locale to {}", LOCALE.get());

    let ec = ExecutionContext::capture();
    thread::spawn(move || {
        ec.run(|| {
            println!("the locale in the child thread is {}", LOCALE.get());
            LOCALE.set("fr_FR".into());
            println!("the new locale in the child thread is {}", LOCALE.get());
        });
    }).join().unwrap();

    println!("the locale of the parent thread is again {}", LOCALE.get());
}

以下示例将输出以下内容,假设未设置默认语言环境变量(或环境变量为 en_US

the current locale is en_US
changing locale to de_DE
the locale in the child thread is de_DE
the new locale in the child thread is fr_FR
the locale of the parent thread is again de_DE

依赖关系

~555KB
~12K SLoC