ZeroMQ 克隆模式和延迟加入的客户端

ZeroMQ Clone pattern and late-joining client

ZeroMQ 指南在 Getting an Out-of-Band Snapshot 部分描述了

The client first subscribes to updates and then makes a state request. This guarantees that the state is going to be newer than the oldest update it has.

先订阅如何保证客户端会收到比快照状态更新的所有更新?例如

  1. 客户端订阅状态更新
  2. 客户端请求状态快照
  3. 客户端收到状态快照
  4. 服务器发生状态变化
  5. 客户端状态变化订阅完成

所以客户端会错过第 4 步发生的状态变化。这种情况可能吗?

请允许我更全面地描述一下这个过程:

  1. 服务器在更新发生时发布更新
  2. 新客户端订阅更新(客户端SUB到服务器PUB
  3. 新客户端从服务器请求当前状态(客户端DEALER到服务器ROUTER)-(重要:假设此请求到达服务器并开始构建快照所需的时间比 SUB套接字完成连接并订阅更新——这通常是一个合理的假设,但请注意)
  4. 服务器构建当前状态的快照以响应请求
  5. 服务器在更新发生时继续发布更新
  6. 新客户端将他们订阅的所有这些更新排队 - 尚未处理它们(这是 ZMQ "for free" 的一部分)
  7. 服务器发回当前状态(重要If来自客户端的状态请求发生在订阅完成后,那么以下两种情况之一为真:或者(A)新客户端加入后没有新的更新,所以状态只是新客户端之前的历史客户端加入,或 (B) 有新的更新,它们都处于 状态,在客户端的 SUB 套接字中排队。(A) 完全正确,所以我们将关注 (B).)
  8. 新客户端处理状态 - 这使它达到当前状态。
  9. 新客户端开始处理SUB套接字中的消息。如果有的话,我们会根据我们现在拥有的历史记录来检查它们。如果我们已经有此更新(来自状态),我们将丢弃它。如果我们不这样做,这是一条新消息,我们会处理它。
  10. 新客户端继续正常处理消息,所有消息都是最新的并处理所有新消息。

...即使在示例代码中,SUB 套接字直到收到状态后才开始发送 recv() 消息,它仍然从发布者那里获取消息并将它们排队直到它准备好处理它们,所以不存在更新丢失的情况,而是计划和处理消息重复的相反情况。