跳到主要内容
英文版本为准

本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。

路径

一条消息在 RustStream 服务中的路径,分别在流文件和管道上:读取者、通道、处理器、应答和写入。

一条需要应答的消息的路径,分别在流文件和管道上流文件管道客户端消费者读取文件驱动任务打上代号容量 64 的通道FileSubscriber丢弃旧代号组批在 batch(n) 下FileContext,然后解码订阅者的处理器#[subscriber] fnFilePublisher有消息头时套信封追加、刷写写入文件stdin 线程解析这一行读取任务属于该订阅容量 64 的通道StdioSubscriber每次轮询一条消息组批在 batch(n) 下解码订阅者的处理器#[subscriber] fnStdioPublisher需要时套信封stdout 线程写出这一行
以文字阅读本图
  1. 流文件: 客户端消费者 读取文件; 驱动任务 打上代号; 容量 64 的通道; FileSubscriber 丢弃旧代号; 组批 在 batch(n) 下; FileContext, 然后解码; 订阅者的处理器 #[subscriber] fn; FilePublisher 有消息头时套信封; 追加、刷写 写入文件
  2. 管道: stdin 线程 解析这一行; 读取任务 属于该订阅; 容量 64 的通道; StdioSubscriber 每次轮询一条消息; 组批 在 batch(n) 下; 解码; 订阅者的处理器 #[subscriber] fn; StdioPublisher 需要时套信封; stdout 线程 写出这一行
  3. 客户端消费者 读取文件 → 驱动任务 打上代号
  4. 驱动任务 打上代号 → 容量 64 的通道
  5. 容量 64 的通道 → FileSubscriber 丢弃旧代号
  6. FileSubscriber 丢弃旧代号 → 组批 在 batch(n) 下
  7. 组批 在 batch(n) 下 → FileContext, 然后解码
  8. FileContext, 然后解码 → 订阅者的处理器 #[subscriber] fn
  9. 订阅者的处理器 #[subscriber] fn → FilePublisher 有消息头时套信封
  10. FilePublisher 有消息头时套信封 → 追加、刷写 写入文件
  11. stdin 线程 解析这一行 → 读取任务 属于该订阅
  12. 读取任务 属于该订阅 → 容量 64 的通道
  13. 容量 64 的通道 → StdioSubscriber 每次轮询一条消息
  14. StdioSubscriber 每次轮询一条消息 → 组批 在 batch(n) 下
  15. 组批 在 batch(n) 下 → 解码
  16. 解码 → 订阅者的处理器 #[subscriber] fn
  17. 订阅者的处理器 #[subscriber] fn → StdioPublisher 需要时套信封
  18. StdioPublisher 需要时套信封 → stdout 线程 写出这一行

订阅的任务走在处理器前面读取。它从客户端取出每条消息,打开信封,把载荷复制到自己的缓冲区里。它把消息的编号写进 stream-sequence 消息头,然后把这次投递排入容量最多为 64 的通道。处理器从这个通道读取,因此在处理当前消息的同时,下一条消息已经从文件中读出。

在文件上,每次投递都带有读取者读到它时所处的代号。定位开启一个新代号,订阅丢弃在旧代号下排队的内容。投递还持有对订阅定位器的一个共享引用,因此为每条消息构建上下文只是增加引用计数。

处理器的应答编码进分发循环复用的缓冲区。发布者把这些字节复制进交给客户端的消息。只有在消息带有消息头时,或者在管道上一行会改变载荷时,发布者才用信封把它们包起来。文件发布在追加内容刷写到文件之后返回。写入订阅所读文件的应答,会被它的读取者跳过,因为它属于另一个流键。

投递在应答之后结算。在两种传输上,ack 和 nack 都报告自己不受支持,结算一页用图说明了这一点。