True persistent passive requests
A true
passive requests implementation, which not only reduces polling latency, but also eliminates the need to send re-requests.
Requests will have a passive-request flag, just like with simpler implementations.
For each key which we have passive requests for, we record:
- The key.
- The list of nodes subscribed to that key, which we will forward the data to if it passes through this node.
- The nodes that we routed the request to last time, which we would route it to now if we got a normal request for it. This is essentially a persistent route.
- Any "peer" nodes; nodes which already had the request when we routed to them.
Just as with the simpler version, if a subscriber node disconnects, we remove it, and check whether there are any subscribers left.
If we get the data, we forward it to all of the above nodes.
If a routed-to node disconnects, we re-route the request to the next-best node which isn't already in the route according to routing. The problem is, we need to do this without causing loops which will persist forever even though there are no real subscribers. How do we do this?
If the node locations change, or a new node is added, so that we need to re-route, again we do so.
The objective is to keep an up-to-date route. Any nodes which would not be part of the request path for a regular request shouldn't be part of the (outgoing) persistent route.
But we also have to have a persistent tree of requestors. What we cannot do is have one ID per requestor, and all of them persist, right up to the most specialized node, because that might mean it recording hundreds of thousands of IDs, and worse, each of them would have to route a request to it. (This is what happens now actually, if a large number of nodes all make requests for a key that doesn't exist... that's half the justification for passive requests, see
the page).
There has been much said on the mailing list about this, which should be added here.