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

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

定位

处理器通过定位句柄移动它自己的文件订阅:驱动任务执行客户端的定位,从旧位置排入队列的内容被丢弃。

来自处理器的定位:命令、客户端的定位,以及它丢弃的投递处理器seeker.seek(position)发给驱动任务的命令在任何 select! 之外FilePosition 转换为客户端的目标序号包含在内,时刻以纳秒计客户端的定位执行到完成已移动:新的代号被拒绝:实时订阅结束,重放保持原位旧代号下排队的投递被丢弃下一次投递来自新位置通道已满也不会阻挡定位:驱动任务在等待空位时仍会处理定位
以文字阅读本图
  1. 处理器 seeker.seek(position) → 发给驱动任务的命令 在任何 select! 之外: 发送
  2. 发给驱动任务的命令 在任何 select! 之外 → FilePosition 转换为客户端的目标 序号包含在内,时刻以纳秒计
  3. FilePosition 转换为客户端的目标 序号包含在内,时刻以纳秒计 → 客户端的定位 执行到完成
  4. 客户端的定位 执行到完成 → 已移动: 新的代号: 已移动
  5. 客户端的定位 执行到完成 → 被拒绝:实时 订阅结束, 重放保持原位: 被拒绝
  6. 已移动: 新的代号 → 旧代号下 排队的投递 被丢弃
  7. 旧代号下 排队的投递 被丢弃 → 下一次投递 来自新位置
  8. 通道已满也不会阻挡定位:驱动任务 在等待空位时仍会处理定位

客户端的定位需要独占消费者,而且不能中途打断。因此,订阅的驱动任务独占消费者,定位以命令的形式到达它。驱动任务把定位执行到完成,不与下一次读取竞争,完成后答复处理器。

FilePosition 转换为客户端的目标。开头和末端直接对应。序号是包含在内的,因此定位到从某次投递读到的位置,会再次投递那条消息。以毫秒计的时刻转换为纳秒,超出范围的值在到达客户端之前就被拒绝。

移动了读取者的定位会开启一个新代号,驱动任务在答复之前公布它。订阅丢弃每个带有更旧代号的投递,因此 seek 返回之后,在旧位置读到的任何内容都不会到达处理器。

被拒绝的定位,例如超过文件下一个写入序号的序号,会让重放留在原处,已读到的内容仍在队列中。实时订阅则会结束:客户端向前读取寻找这条消息,读完了文件。已到达文件末尾的重放仍然可以定位,并从新位置再次投递。

通道已满时,定位照常得到处理。停止从通道取消息的处理器,可能正是在等待定位的那一个,因此比通道更大的积压永远不会阻塞它。关闭之后,每次定位都会被拒绝。

进程内传输以同样的方式移动订阅,拒绝的情形也相同,只是在订阅自己的轮询中完成。