英文版本为准
本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。
路径
一条消息在 RustStream 服务中的路径,分别在流文件和管道上:读取者、通道、处理器、应答和写入。
以文字阅读本图
- 流文件: 客户端消费者 读取文件; 驱动任务 打上代号; 容量 64 的通道; FileSubscriber 丢弃旧代号; 组批 在 batch(n) 下; FileContext, 然后解码; 订阅者的处理器 #[subscriber] fn; FilePublisher 有消息头时套信封; 追加、刷写 写入文件
- 管道: stdin 线程 解析这一行; 读取任务 属于该订阅; 容量 64 的通道; StdioSubscriber 每次轮询一条消息; 组批 在 batch(n) 下; 解码; 订阅者的处理器 #[subscriber] fn; StdioPublisher 需要时套信封; stdout 线程 写出这一行
- 客户端消费者 读取文件 → 驱动任务 打上代号
- 驱动任务 打上代号 → 容量 64 的通道
- 容量 64 的通道 → FileSubscriber 丢弃旧代号
- FileSubscriber 丢弃旧代号 → 组批 在 batch(n) 下
- 组批 在 batch(n) 下 → FileContext, 然后解码
- FileContext, 然后解码 → 订阅者的处理器 #[subscriber] fn
- 订阅者的处理器 #[subscriber] fn → FilePublisher 有消息头时套信封
- FilePublisher 有消息头时套信封 → 追加、刷写 写入文件
- stdin 线程 解析这一行 → 读取任务 属于该订阅
- 读取任务 属于该订阅 → 容量 64 的通道
- 容量 64 的通道 → StdioSubscriber 每次轮询一条消息
- StdioSubscriber 每次轮询一条消息 → 组批 在 batch(n) 下
- 组批 在 batch(n) 下 → 解码
- 解码 → 订阅者的处理器 #[subscriber] fn
- 订阅者的处理器 #[subscriber] fn → StdioPublisher 需要时套信封
- StdioPublisher 需要时套信封 → stdout 线程 写出这一行
订阅的任务走在处理器前面读取。它从客户端取出每条消息,打开信封,把载荷复制到自己的缓冲区里。它把消息的编号写进 stream-sequence 消息头,然后把这次投递排入容量最多为 64 的通道。处理器从这个通道读取,因此在处理当前消息的同时,下一条消息已经从文件中读出。
在文件上,每次投递都带有读取者读到它时所处的代号。定位开启一个新代号,订阅丢弃在旧代号下排队的内容。投递还持有对订阅定位器的一个共享引用,因此为每条消息构建上下文只是增加引用计数。
处理器的应答编码进分发循环复用的缓冲区。发布者把这些字节复制进交给客户端的消息。只有在消息带有消息头时,或者在管道上一行会改变载荷时,发布者才用信封把它们包起来。文件发布在追加内容刷写到文件之后返回。写入订阅所读文件的应答,会被它的读取者跳过,因为它属于另一个流键。
投递在应答之后结算。在两种传输上,ack 和 nack 都报告自己不受支持,结算一页用图说明了这一点。