9个版本

0.2.2 2023年12月18日
0.2.1 2023年11月25日
0.1.5 2023年10月30日
0.1.4 2023年9月15日

#423 in 并发

Download history 3/week @ 2024-06-25

每月下载量 155

AGPL-3.0-or-later

72KB
1K SLoC

Flue是一个高效且安全的actor运行时库。

Flue的目的是成为一个支持库,用于使用进程(具有私有内存的并发执行线程)的并发程序。进程只能通过在彼此之间传递信号进行通信。信号被发送到路由,并通过邮箱接收。如果一个路由组中的任何路由被杀死,该路由组中的所有路由都将被杀死。邮局包含了一组通信进程中的所有路由。能力通过细粒度的权限标志来引用和限制对路由的访问。表是整数地址的不可伪造的能力存储库。

尽管Flue提供了构建基于进程的并发程序的低级别支持框架和数据模型,但它不提供对进程本身的**高级定义**或数据类型。Flue库的用户必须将Flue的组件与他们的应用程序特定的数据模型相结合,以找到他们并发系统的最佳架构。

请注意,信号只能发送到路由,并且邮箱只能通过它们绑定的路由接收信号。

能力可以对其路由执行以下操作,每个操作都由相应的权限标志保护

  1. 杀死:强制终止路由及其路由组中的所有其他路由,防止它们接收任何进一步的消息。
  2. 发送:向由数据(简单的字节缓冲区)和要导入到路由邮箱表中的能力列表组成的**目标路由**发送“消息”信号。
  3. 监控:配置给定的邮箱以监控能力路由。当路由关闭时,无论是主动关闭还是被杀死,邮箱都会收到一个带有无权限能力的“down”信号,指向被监控的路由。如果监控时路由已经关闭,邮箱将立即收到down信号。
  4. 链接:将给定的路由组链接到能力路由组。当任一路由组死亡时,另一个也将被杀死。如果任一组已死亡,另一组将立即被杀死。可以通过**解除链接**两个路由组来在任何时候删除链接。与监控不同,两个路由组之间的链接即使在链接的能力路由关闭后也会持续存在。

能力也可能被“降级”到新的能力,该能力指向相同的路由,但权限是原始能力的一个子集。这可以用来通过限制发送到该进程的路由能力的权限标志来限制其他进程对路由的访问。

Flue是为高效执行可能不受信任的进程代码而设计的,因此为了支持运行该代码,Flue的安全模型有以下公理

  • 只有当一个路由的能力被明确地传递给一个进程时,一个进程才能访问该路由。您可以通过限制传递给它的能力来在细粒度上对进程进行沙箱隔离。
  • 能力只能从其他能力创建,要么与原始权限集相同,要么是原始权限集的子集。不受信任的进程无法进行权限提升。

下面是一个框图,展示了两个各自拥有邮箱和对对方邮箱能力的进程,有助于解释基于Flue的完整actor系统的心理模型

        Process A              Post Office               Process B
┌───────────────────────┐    ┌─────────────┐     ┌───────────────────────┐
│         Table         │    │             │     │         Table         │
│ ┌───────────────────┐ │    │ ┌─────────┐ │     │ ┌───────────────────┐ │
│ │                   │ │    │ │         │ │     │ │                   │ │
│ │ ┌───────────────┐ │ │ ┌──┼─► Route B ├─┼───┐ │ │ ┌───────────────┐ │ │
│ │ │ Capability A  ├─┼─┼─┘  │ │         │ │   │ │ │ │ Capability B  ├─┼─┼─┐
│ │ └───────────────┘ │ │    │ └─────────┘ │   │ │ │ └───────────────┘ │ │ │
│ │                   │ │    │             │   │ │ │                   │ │ │
│ └────────▲──────────┘ │    │ ┌─────────┐ │   │ │ └────────▲──────────┘ │ │
│          │            │    │ │         │ │   │ │          │            │ │
│   ┌──────┴───────┐    │ ┌──┼─┤ Route A ◄─┼─┐ │ │   ┌──────┴───────┐    │ │
│   │   Mailbox A  ◄────┼─┘  │ │         │ │ │ └─┼───►   Mailbox B  │    │ │
│   └──────────────┘    │    │ └─────────┘ │ │   │   └──────────────┘    │ │
│                       │    │             │ │   │                       │ │
└───────────────────────┘    └─────────────┘ │   └───────────────────────┘ │
                                             │                             │
                                             └─────────────────────────────┘

两个进程共享一个邮局,邮箱A和B在该邮箱中有相关路由A和B。能力A属于进程A的表,并引用路由B,能力B存在于进程B的表中,并引用路由A。邮箱A和B引用它们关联的进程表,以便当它们接收到能力时,可以将这些能力插入到进程的表中。

要使用能力A从进程A向进程B发送消息信号,Flue将对该消息执行以下步骤

  1. 进程A的表确认能力A确实有发送消息的权限。
  2. 进程A的表将消息发送到邮局中路由B的地址。
  3. 邮局通过地址查找路由B,找到邮箱B的无拷贝消息通道,并使用它来发送消息。
  4. 消息在邮箱B的队列中等待,直到邮箱B接收它。
  5. 邮箱B处理该消息,并将其中包含的任何能力插入到进程B的表中。

依赖关系

~3–9MB
~68K SLoC