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

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

读取者

文件客户端像 tail -f 一样跟随流文件,把消息与信标分开,并通过考察信标再向前读取来定位。

文件客户端如何读取流文件,以及它的定位如何找到位置流文件源任务读到末尾,然后等待消息源跳过信标消费者只取它的键的消息订阅每次 next() 一条消息考察信标缩小区域回退到那个信标向前读取直到目标重放:本 crate 自己读取消息源,因此结束出现在最后一条消息之后
以文字阅读本图
  1. 流文件 → 源任务 读到末尾,然后等待: 字节
  2. 源任务 读到末尾,然后等待 → 消息源 跳过信标
  3. 消息源 跳过信标 → 消费者 只取它的键的消息
  4. 消费者 只取它的键的消息 → 订阅 每次 next() 一条消息: next()
  5. 消息源 跳过信标 → 考察信标 缩小区域: 定位
  6. 考察信标 缩小区域 → 回退 到那个信标
  7. 回退 到那个信标 → 向前读取 直到目标
  8. 重放:本 crate 自己读取消息源, 因此结束出现在最后一条消息之后

一个任务把文件读到末尾,然后等待操作系统报告变化。操作系统可能报告得晚,所以等待还设有超时:起初为 1 毫秒,文件一直没有变化时逐步增加到 1024 毫秒。一阵连续写入会重置等待。一个进程中每个文件只有一个监视者,无论它有多少读取者。文件从磁盘上删除后,流随之结束。

在这个任务之上,消息源重新拼合各帧,跳过信标,并把被信标拆开的消息接合起来。消费者保留它的流键的消息,每次调用交出一条。

实时订阅就是这样一个消费者,以实时模式打开,位于末端。它在文件末尾等待下一次写入,而不是就此结束。

重放直接读取消息源,跳过其他键。客户端自带的重放会预读,而且在预读的内容尚未交出时就报告结束,因此本 crate 不使用它。

定位到开头或末端时,直接移动到那里。定位到某个序号或某个时刻时,先考察信标,找到包含它的区域,回退到那个信标,再向前读取:直到第一条序号等于或大于该值的消息,或者第一条严格晚于该时刻的消息。读过文件末尾时,定位被拒绝,消息源回到原来的位置。定位不能中途打断,所以本 crate 在一个单独的任务上执行它,定位一页用图说明了这一点。

文件中没有任何内容记录读取者读到了哪里。因此,重启的服务从它自己保存的位置继续。