So now we have our second problem: how to deal with late-joining clients or clients that crash and then restart.
For a late (or recovering) client to catch up with a server, it has to get a snapshot of the server’s state. Just as we’ve reduced “message” to mean “a sequenced key-value pair,” we can reduce “state” to mean “a hash table.” To get the server state, a client opens a DEALER socket and asks for it explicitly (Figure 5-4).
Figure 5-4. State replication
To make this work, we have to solve a problem of timing. Getting a state snapshot will take a certain amount of time, possibly fairly long if the snapshot is large. We need to correctly apply updates to the snapshot, but the server won’t know when to start sending us updates. One approach would be to start subscribing, get a first update, and then ask for “state for update N.” This would require the server to store one snapshot for each update, though, which isn’t practical.
Instead, we will do the synchronization in the client, as follows:
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.
The client waits for the server to reply with state, and meanwhile queues all updates. It does this simply by not reading them: ØMQ keeps them queued on the socket queue.
When the client receives its state update, ...