# Application asks to route a message (technically, the Application Adapter, but we do without for now) On Receipt of ROUTE(key, msg) from APPLICATION do: requestID = RoutingStrategy.initNewRequest(key) connectedOverlays = RoutingStrategy.getConnectedOverlays(key, requestID) directOverlayNodes = RoutingStrategy.getDirectOverlayGatewayNodes(key, requestID) for overlay in connectedOverlays: send ROUTE(key, msg) to overlay.submodule for sNode in directOverlayNodes: send SYNAPSE_REQUEST(key, msg, requestID, RoutingStrategy.getRoutingState(key, requestID)) to sNode # We have been rotuing a message in one of the overlay, extract information, publish own offer On Receipt of NOTIFY(key, sourceNode) from OVERLAY_SUBMODULE[N] do: if (isSynapseNode(sourceNode)) SynapseTable.refresh(sourceNode, sourceNode.connectedOverlayList) if (RoutingStrategy.canSendOfferTo(sourceNode)) #canSendOffer() can check different cryteria (overlay access, connectivity, reputation, transmission queue...) send SYNAPSE_OFFER(key, OVERLAY_SUBMODULE[N].networkID, connectedOverlayList) to sourceNode; # Message routed, embedded an RPC request, a response has been routed back. On Receipt of RPC_RESPONSE(key, response, nonce) form OVERLAY_SUBMODULE[N].node do: # We can have several different requests for the same key, get the appropriate RequestID requestID = NonceRequestIDTable.getRequestID(nonce) if (myRequest(requestID)) # I am the one who initiated the request, collect the result CacheTable[requestID].add(respose) if (RoutingStrategy.routingFinished(requestID)) #No more requests to wait for send CacheTable.createReponse(requestID) to Application return else # I have to route the response back to the reqeusting nodes for requestNode in RoutingTable.getRequestNodes(requestID) send SYNAPSE_RESPONSE(key, requestID, response) to requestNode RoutingTable.removeRequestingNode(requestNode, requestID) #I received a SYNAPSE_OFFER from a gateway node On Receipt of SYNAPSE_OFFER(key, netID, overlayList) from sNode do: # First, update the SynapseTable, ALWAYS SynapseTable.refresh(sNode, overlayList) # If I can use opportunistic routing, send a SYNAPSE_REQUEST if (RoutingStrategy.isOpportunistic) requestList = RoutingTable.getPendingConnectedRequests(key, netID) #I can have different requests for the same key in the same overlay for requestID in requestList do: SYNAPSE_REQUEST = RoutingStrategy.createSynapseRequest(key, requestID) #Here I can specify the targetOverlays RoutingTable.addPendingNode(sNode, requestID, SYNAPSE_REQUEST.nonce) send SYNAPSE_REQUEST to sNode On Receipt of SYNAPSE_REQUEST(key, requestID, message, routingState) from sNode do: RoutingTable.addRequestingNode(sNode, requestID) connectedOverlays = RoutingStrategy.getConnectedOverlays(key, requestID, routingState) directOverlayNodes = RoutingStrategy.getDirectOverlayGatewayNodes(key, requestID, routingState) for overlay in connectedOverlays: send ROUTE(key, msg) to overlay.submodule for sNode in directOverlayNodes: send SYNAPSE_REQUEST(key, msg, requestID, RoutingStrategy.getRoutingState(key, requestID, routingState)) to sNode On Receipt of SYNAPSE_RESPONSE(key, requestID, response) from sNode do: if (myRequest(requestID)) # I am the one who initiated the request, collect the result CacheTable[requestID].add(respose) if (RoutingStrategy.routingFinished(requestID)) #No more requests to wait for send CacheTable.createReponse(requestID) to Application return else # I have to route the response back to the reqeusting nodes for requestNode in RoutingTable.getRequestNodes(requestID) send SYNAPSE_RESPONSE(key, requestID, response) to requestNode RoutingTable.removeRequestingNode(requestNode, requestID)