#插件 #应用 #事件驱动 #事件 #框架 #套接字 #通信

事件引擎

基于插件架构编写事件驱动应用程序的框架

5 个版本

0.2.0 2022 年 9 月 29 日
0.1.3 2022 年 9 月 28 日
0.1.2 2022 年 9 月 28 日
0.1.1 2022 年 8 月 26 日
0.1.0 2022 年 8 月 20 日

#26#事件驱动

每月 23 次下载

BSD-3-Clause

47KB
731 代码行

事件引擎

事件引擎项目提供了一个框架,用于编写利用插件架构的事件驱动应用程序。使用 event-engine 构建的应用程序是用 Rust 编写的,但可以包括用多种语言编写的插件。

事件对应于可以在套接字上传输的静态类型消息,是应用程序插件之间通信的基本机制。每个应用程序都定义自己的事件类型,包括将事件消息序列化和反序列化为字节的机制。不对事件使用的序列化格式做出假设,不同的事件类型可以采用不同的格式。

插件是应用程序的独立组件,用于创建和消费事件。每个插件定义它感兴趣的事件类型,核心的 event-engine 使用发布-订阅模式将事件消息代理到应用程序的插件。

插件可以是“内部”或“外部”。内部插件在主(Rust)应用程序进程的子线程中运行,并且必须用 Rust 编写。外部插件作为独立的操作系统进程运行,可以用任何语言编写。

所有事件消息通信都通过 zmq 套接字进行,这是 event-engine 管理的。内部插件使用 inproc 套接字发送和接收事件消息,而外部插件使用 TCP 套接字。

Depiction of an example application

用法

使用 event-engine 构建应用程序的主要步骤如下

  1. 为应用程序定义 EventTypeEventevents.rs 模块包含两个需要实现的 trait,分别是 EventTypeEvent
  2. 为应用程序定义插件。这些是创建和消费事件的独立组件。 plugins.rs 模块包含需要实现的 PluginExternalPlugin trait。
  3. 创建一个 event_engine::App 对象,并使用应用程序的插件配置它。例如,
     use event_engine::App;
     // define events and plugins

     // create the App object, register the plugins and run
     fn main() {
         // two Rust plugins
         let msg_producer = MsgProducerPlugin::new();
         let counter = CounterPlugin::new();
         // an external plugin written in python
         let pyplugin = PyPlugin::new();
     
         // main application object
         let app: App = App::new(5559, 5560);
         app.register_plugin(Arc::new(Box::new(msg_producer)))
             .register_plugin(Arc::new(Box::new(counter)))
             .register_external_plugin(Arc::new(Box::new(pyplugin)))
             .run()
             .unwrap();
         ()
     }

对于外部插件,该存储库中的 pyevents 目录包含一个名为 events.py 的小型 Python 模块,该模块被编写用来简化编写 Python 插件的过程。此外,还有一个 Docker 镜像 tapis/pyevents,可用于构建包含 Python 插件的独立容器。

示例

该存储库包含一个完整的应用程序示例,该应用程序由两个(内部)Rust 插件和一个外部 Python 插件组成。应用程序被打包为两个 Docker 容器——包含两个 Rust 插件的主 Rust 应用程序在第一个容器中运行,而 Python 插件在第二个容器中运行。有关更多详细信息,请参阅 example 目录。

设计和架构

如简介中所述,even-engine 框架围绕两个主要概念进行设计

  1. 应用程序中感兴趣的事件将被描述为可以经过套接字传输的类型消息;
  2. 独立的应用程序组件,称为 插件,将注册它们感兴趣接收的事件。

以下各节将更详细地讨论 event-engine 的设计和架构。

ZMQ 套接字和发布-订阅

ZMQ 套接字为 event-engine 提供了基础构建块。ZMQ 套接字公开了一个支持多种传输的单个 API,包括进程内、进程间和 TCP。它还启用了许多高级消息模式,如请求-应答和发布-订阅,同时同时处理诸如自动重连等问题。

在 ZMQ 中,所有套接字都有一个类型,并且套接字类型往往成对工作。event-engine 使用两个套接字类型对来实现其功能:使用 PUB-SUB 套接字允许插件发布事件并接收其他插件生成的事件,而使用 REP-REQ 套接字来同步应用程序开始时的所有插件,以确保没有插件错过发送的初始消息。

引擎为自身以及每个插件创建了套接字对象。套接字类型相互镜像

  • 引擎为自己创建了一个“输出”套接字,该套接字绑定到类型为 PUBinproc URL 和 TCP 端口,并为每个插件创建了一个相应的绑定到相同端点的 SUB 套接字。这是插件接收新事件消息的套接字。

  • 同样,引擎为自己创建了一个“输入”套接字,该套接字绑定到类型为 SUBinproc URL 和 TCP 端口,并为每个插件创建了一个相应的绑定到相同端点的 PUB 套接字。这是插件发布新事件消息的套接字。

  • 它创建了一个类型为 REP 的“同步”套接字,该套接字由引擎使用,并为每个插件创建了一个类型为 REQ 的同步套接字。

同步分为两个步骤:首先,每个插件使用一个 REQ 套接字启动,并在启动后通过此套接字发送一个“准备就绪”消息。然后,插件将阻塞,等待来自引擎的回复。引擎在向每个插件发送“ok”回复(在其相应的 REP 套接字上)之前收集每个已注册插件的“准备就绪”消息。一旦一个插件线程收到“ok”回复,它的启动函数将被执行。

接口

并发

开发 event-engine

工作

依赖关系

~1.5–2.3MB
~46K SLoC