英文版本为准
本页译自英文,由模型翻译。若与英文原文存在差异,以英文原文为准。
定位
处理器通过定位句柄移动它自己的文件订阅:驱动任务执行客户端的定位,从旧位置排入队列的内容被丢弃。
以文字阅读本图
- 处理器 seeker.seek(position) → 发给驱动任务的命令 在任何 select! 之外: 发送
- 发给驱动任务的命令 在任何 select! 之外 → FilePosition 转换为客户端的目标 序号包含在内,时刻以纳秒计
- FilePosition 转换为客户端的目标 序号包含在内,时刻以纳秒计 → 客户端的定位 执行到完成
- 客户端的定位 执行到完成 → 已移动: 新的代号: 已移动
- 客户端的定位 执行到完成 → 被拒绝:实时 订阅结束, 重放保持原位: 被拒绝
- 已移动: 新的代号 → 旧代号下 排队的投递 被丢弃
- 旧代号下 排队的投递 被丢弃 → 下一次投递 来自新位置
- 通道已满也不会阻挡定位:驱动任务 在等待空位时仍会处理定位
客户端的定位需要独占消费者,而且不能中途打断。因此,订阅的驱动任务独占消费者,定位以命令的形式到达它。驱动任务把定位执行到完成,不与下一次读取竞争,完成后答复处理器。
FilePosition 转换为客户端的目标。开头和末端直接对应。序号是包含在内的,因此定位到从某次投递读到的位置,会再次投递那条消息。以毫秒计的时刻转换为纳秒,超出范围的值在到达客户端之前就被拒绝。
移动了读取者的定位会开启一个新代号,驱动任务在答复之前公布它。订阅丢弃每个带有更旧代号的投递,因此 seek 返回之后,在旧位置读到的任何内容都不会到达处理器。
被拒绝的定位,例如超过文件下一个写入序号的序号,会让重放留在原处,已读到的内容仍在队列中。实时订阅则会结束:客户端向前读取寻找这条消息,读完了文件。已到达文件末尾的重放仍然可以定位,并从新位置再次投递。
通道已满时,定位照常得到处理。停止从通道取消息的处理器,可能正是在等待定位的那一个,因此比通道更大的积压永远不会阻塞它。关闭之后,每次定位都会被拒绝。
进程内传输以同样的方式移动订阅,拒绝的情形也相同,只是在订阅自己的轮询中完成。