欢迎回来!在数据流中,我们学习了 dora 应用程序的整体蓝图以及它如何连接各个部分。在节点中,我们深入探讨了这些节点部分,并了解到每个节点通常作为一个独立的进程运行,执行特定的任务,并通过数据流 YAML 中定义的输入和输出进行通信。
现在,让我们探索一种在 Node 内部添加更多结构和可重用性的方法: Operator 操作符 的概念。
假设你有一个负责处理图像的节点。该节点可能需要执行几个不同的步骤:
你可以在一个节点的单一代码实现中编写所有这些逻辑。但是,如果你之后想在另一个节点或不同的数据流中重用“调整图像大小”或“应用滤镜”逻辑,你就必须复制粘贴代码,这并不理想。
这时, Operator 就派上用场了。Operator 是一种较小的模块化逻辑,设计用于在一种名为 Dora Runtime Node 的特殊节点内运行。Operator 允许你将单个节点的工作分解为可重用的独立步骤。
可以将节点想象成工厂车间的工作站(一栋独立的建筑),而操作符则是该工作站内的专用工具或机器。工作站(节点)是独立的单元,但其内部的工作由其工具集(操作符)完成。
让我们快速比较一下:
| 特征 | 自定义节点 | Dora 运行时节点和操作符 |
|---|---|---|
| 运行方式 | 独立节点 | 单进程 |
| 包含 | 一段自定义的代码 | 一个或多个操作符 |
| 逻辑单元 | 整个节点代码 | 单个操作符 |
| 通讯 | 使用 dora Node API 直接与 dora 系统交互 | 节点运行时使用 dora Node API; 操作符使用 dora Operator API |
| 可重用性 | 重用整个 Node 进程 | 重复使用单个操作符逻辑模块 |
因此,虽然自定义节点是其自己独立的程序( .py 、 .rs 可执行文件等),但 Dora 运行时 节点是一个运行 dora-runtime 程序的进程,然后加载和管理数据流 YAML 中指定的一个或多个操作员的代码。
YAML 中定义操作符运算符是在 Dataflow YAML 中节点的定义内定义的。您无需为节点的实现指定单个 path 或 custom 块,而是使用 operators 符块。
让我们想象一下之前的图像处理节点,现在使用操作符来实现。
需要注意的关键事项:
nodes 下的 id ( image-processor-node ) 是 Node 进程的 ID,和之前一样。operators 列表,而不是 path 或 custom 。operators 列表中的每个项目定义了在此节点内运行的操作员 。Operator 都有自己的 id ( 在此节点内唯一)、 source (例如 python 、 shared-library )和指向其代码的 path 。inputs 和 outputs 。source_id/stream_id 。ID( image-processor-node/image ):从外部数据流进入节点的数据被路由到操作员的输入。Operator 的 ID( grayscale-converter/gray_image ):数据在同一节点进程内的 Operator 之间直接流动。Operator 的输出 id 与 Node 的某个 outputs 匹配,则该输出将自动成为该 Node 到外部 Dataflow 的输出( edge-detector/processed_image 变为 image-processor-node/processed_image )。这允许您在单个 Node 进程中定义一个迷你数据流。
就像 Node 的代码使用 dora Node API 一样,Operator 的代码也使用 dora Operator API 。这个 API 更简单,因为 Operator 不需要担心网络连接或进程管理之类的事情;Runtime Node 会处理这些事情。
操作员的主要工作是对事件做出反应。最常见的事件是接收输入数据。
下面是我们的一个示例运算符(grayscale-converter 的 Python 代码的简化概念图,代码片段非常简短):
在此 Python 代码片段中:
Operator 代码的结构为 Python 类(或 Rust 中的函数)。on_event 方法(或函数),每当发生与该操作符有关的事件(例如接收输入或停止信号)时, dora-runtime 就会调用该方法。dora_event 字典包含有关事件的信息(其 type 、 id 、 value 等。我们将在下一章介绍事件流 )。send_output 函数(或方法)由运行时提供,供 Operator 在其定义的输出上发送数据。它接受输出 id 、 data 以及可选的 metadata 。这个模式( on_event -> process -> send_output )是 Operator 逻辑的核心。
当您使用 dora run 和定义了带有操作符的运行时节点的 Dataflow YAML 时,下面是发生情况的简化视图:
dora CLI 和 Dora Daemon / Dora Coordinator 读取数据流 YAML。image-processor-node 标识为一个节点。operators 块,表明它是一个运行时节点。dora-runtime 可执行文件。dora-runtime 读取 image-processor-node 块中的 Operator 定义。source 和 path 加载 grayscale-converter 、 resizer 、 filter 和 edge-detector 的代码。camera/image 到 image-processor-node 的 image 输入。image 输入到 grayscale-converter 操作器的 input_image 输入。grayscale-converter/gray_image 输出到 resizer/input_image 输入。resizer/resized_image 输出到 filter/input_image 输入。filter/filtered_image 输出到 edge-detector/input_image 输入。edge-detector/processed_image 输出到外部 Dataflow 的 image-processor-node/processed_image 输出。dora-runtime 进入事件循环,从外部 Dataflow 接收事件(例如新图片),并根据 YAML 中定义的内部连接,将它们分发给相关的 Operator。当一个 Operator 生成输出时,运行时会将其内部路由到另一个 Operator,或者将其作为 Node 输出发送出去。这是一个简化的序列图:

这显示了数据如何流入单个运行时节点进程,通过运行时在操作员之间内部传递,然后作为节点输出流出。
在本章中,我们了解到 Operator 是运行在 Dora Runtime 节点进程中的模块化逻辑。它们在 Dataflow YAML 的 Node 块中定义,允许您在单个节点内构建复杂的处理流水线。Operator 使用 Operator API 接收输入并发送输出, dora-runtime 负责加载它们、在它们之间建立内部通信,以及在节点的外部输入/输出和 Operator 的输入/输出之间路由数据。这提供了一种创建可复用处理步骤的方法。
现在我们了解了节点和操作符,让我们看看数据在系统中移动的基本概念: Event Stream 事件流 。