Two key messages: CoalesceNotification: - Notifies a node that one of its request chains has been coalesced with a different one. We can then update our own IDs and ensure that collisions result in RejectedLoop messages rather than deadlocks and timeouts. SubscribeRestarted: - Notifies a subtree of nodes that the parent node is resubscribing and please to let its requests through.
These are two distinct functions! Two distinct SubscribeHandler states: - The node is searching, or is waiting for an upstream node to search. = SEARCHING. - An upstream node has lost a working connection, and is restarting. The node is waiting for that node to find its target, and requests may be routed through the node for that purpose. = RESTARTING. When a node gets a SubscribeRequest: - If it is a loop, it rejects it with RejectLoop - If the node is not subscribing to the desired key, it accepts the request, and forwards it as-is (same ID etc). - If the node is subscribed to the desired key, but upstream is restarting, and the ID on the incoming request is equal to the restart ID published earlier, then the node forwards the request. It creates a new SubscribeSender to handle this. It does not send a CoalesceNotification in any direction, since this is not a coalesce; the upstream node is searching, and it can use any nodes to find root. If the request reaches the parent by some circuitous route, it will be rejected (loop). What about the results of the new subscribesender? If it succeeds, it replaces the current parent. If it fails, the status is relayed to the requestor only. All we have to do is make an interface for status reporting for SubscribeSender. - If the node is already subscribed to the desired key: -- If the root location is acceptable to the requestor, it accepts it. If the node is subscribed successfully, it sends a SubscribeSucceeded with the root location. If the node is waiting for an upstream restart, it forwards the SubscribeRestarted. -- Otherwise it sends an RNF. - If the node is already searching for an upstream node, we coalesce. We send a CoalesceNotification to the requestor, and add the requestor to the list of subscribed nodes. If our current request fails, we try the next one, which will eventually get to the one we just added. So what changes need to be made in the current codebase? - Remove ResubscribeHandler and ResubscribeSender - Remove FNPResubscribeRequest - Make sure that new outgoing subscribe requests register their ID, so that they will be rejected if they loop. - Stop using SubscribeRestarted as a status indicator. Change SubscribeSender and SubscribeHandler: First you have an opportunity for accepted, or quick errors, then you wait for a long timeout for SubscribeSucceeded or SubscribeRestarted. I.e. there is a phase of "waiting for upstream to search" which is not RESTARTING. This will be in runPhase1(). - When upstream goes into restarting, (atomically) check queued requests (SubscribeHandler's) for the restart ID, and set a flag which will cause newly added ones to check. If one matches: - Create a new SubscribeSender. This has a different callback-object argument. To do this: - Factor out all the callbacks from SubscribeSender into an interface object. Implement this directly in SubscribeHandler for the main SubscribeSender. Provide a secondary version for the alternate SubscribeSender's. - Make a distinction in the handleSubscribeRequest code and elsewhere between waiting for upstream to resubscribe, and waiting to find somewhere to subscribe to. Practically, if it is the former, coalesce instead of sending a SubscribeRestarted. -- Matthew J Toseland - toad at amphibian.dyndns.org Freenet Project Official Codemonkey - http://freenetproject.org/ ICTHUS - Nothing is impossible. Our Boss says so. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: Digital signature URL: <https://emu.freenetproject.org/pipermail/tech/attachments/20051019/a34504e2/attachment.pgp>
