def _connect_via_local(self, inport, outport): """ Both connecting ports are local, just connect them """ _log.analyze(self.node.id, "+", {}) inport.set_queue(queue.get(inport, peer_port=outport)) outport.set_queue(queue.get(outport, peer_port=inport)) ein = endpoint.LocalInEndpoint(inport, outport) eout = endpoint.LocalOutEndpoint(outport, inport) if ein.use_monitor(): self.node.monitor.register_endpoint(ein) if eout.use_monitor(): self.node.monitor.register_endpoint(eout) invalid_endpoint = outport.attach_endpoint(eout) if invalid_endpoint: if invalid_endpoint.use_monitor(): self.node.monitor.unregister_endpoint(invalid_endpoint) invalid_endpoint.destroy() invalid_endpoint = inport.attach_endpoint(ein) if invalid_endpoint: if invalid_endpoint.use_monitor(): self.node.monitor.unregister_endpoint(invalid_endpoint) invalid_endpoint.destroy() # Update storage self.node.storage.add_port(inport, self.node.id, inport.owner.id) self.node.storage.add_port(outport, self.node.id, outport.owner.id)
def create_port(self): port = DummyPort() port.properties = { 'routing': self.routing, "direction": "out", 'nbr_peers': self.num_peers } return queue.get(port)
def connection_request(self): """ A request from a peer to connect a port""" _log.analyze(self.node.id, "+", self.kwargs, peer_node_id=self.peer_port_meta.node_id) try: payload = self.kwargs['payload'] except: return response.CalvinResponse(False) if 'tunnel_id' not in payload: raise NotImplementedError() tunnel = self.token_tunnel.tunnels[self.peer_port_meta.node_id] if tunnel.id != payload['tunnel_id']: # For some reason does the tunnel id not match the one we have to connect to the peer # Likely due to that we have not yet received a tunnel request from the peer that replace our tunnel id # Can happen when race of simultaneous link setup and commands can be received out of order _log.analyze(self.node.id, "+ WRONG TUNNEL", payload, peer_node_id=self.peer_port_meta.node_id) return response.CalvinResponse(response.GONE) self.port.set_queue( queue.get(self.port, peer_port_meta=self.peer_port_meta)) if self.port.direction == "in": endp = endpoint.TunnelInEndpoint(self.port, tunnel, self.peer_port_meta.node_id, self.peer_port_meta.port_id, self.node.sched.trigger_loop) else: endp = endpoint.TunnelOutEndpoint(self.port, tunnel, self.peer_port_meta.node_id, self.peer_port_meta.port_id, self.node.sched.trigger_loop) if endp.use_monitor(): self.node.monitor.register_endpoint(endp) invalid_endpoint = self.port.attach_endpoint(endp) # Remove previous endpoint if invalid_endpoint: if invalid_endpoint.use_monitor(): self.node.monitor.unregister_endpoint(invalid_endpoint) invalid_endpoint.destroy() # Update storage self.node.storage.add_port(self.port, self.node.id, self.port.owner.id) _log.analyze(self.node.id, "+ OK", payload, peer_node_id=self.peer_port_meta.node_id) return response.CalvinResponse(response.OK, {'port_id': self.port.id})
def connection_request(self): """ A request from a peer to connect a port""" _log.analyze(self.node.id, "+", self.kwargs, peer_node_id=self.peer_port_meta.node_id) try: payload = self.kwargs['payload'] except: return response.CalvinResponse(False) if 'tunnel_id' not in payload: raise NotImplementedError() tunnel = self.token_tunnel.tunnels[self.peer_port_meta.node_id] if tunnel.id != payload['tunnel_id']: # For some reason does the tunnel id not match the one we have to connect to the peer # Likely due to that we have not yet received a tunnel request from the peer that replace our tunnel id # Can happen when race of simultaneous link setup and commands can be received out of order _log.analyze(self.node.id, "+ WRONG TUNNEL", payload, peer_node_id=self.peer_port_meta.node_id) return response.CalvinResponse(response.GONE) self.port.set_queue(queue.get(self.port, peer_port_meta=self.peer_port_meta)) if self.port.direction == "in": endp = endpoint.TunnelInEndpoint(self.port, tunnel, self.peer_port_meta.node_id, self.peer_port_meta.port_id, self.node.sched.trigger_loop) else: endp = endpoint.TunnelOutEndpoint(self.port, tunnel, self.peer_port_meta.node_id, self.peer_port_meta.port_id, self.node.sched.trigger_loop) if endp.use_monitor(): self.node.monitor.register_endpoint(endp) invalid_endpoint = self.port.attach_endpoint(endp) # Remove previous endpoint if invalid_endpoint: if invalid_endpoint.use_monitor(): self.node.monitor.unregister_endpoint(invalid_endpoint) invalid_endpoint.destroy() # Update storage self.node.storage.add_port(self.port, self.node.id, self.port.owner.id) _log.analyze(self.node.id, "+ OK", payload, peer_node_id=self.peer_port_meta.node_id) return response.CalvinResponse(response.OK, {'port_id': self.port.id})
def create_port(routing): port = DummyPort() port.properties = {'routing': routing, "direction": "in"} return queue.get(port)
def _connected_via_tunnel(self, reply): """ Gets called when remote responds to our request for port connection """ _log.analyze(self.node.id, "+ " + str(reply), {'local_port': self.port, 'peer_port': self.peer_port_meta}, peer_node_id=self.peer_port_meta.node_id, tb=True) if reply in [response.BAD_REQUEST, response.NOT_FOUND, response.GATEWAY_TIMEOUT]: # Other end did not accept our port connection request if self.peer_port_meta.retries < 2 and self.peer_port_meta.node_id: # Maybe it is on another node now lets retry and lookup the port # FIXME: Could the port have moved to our node and we need to check local??? self.peer_port_meta.retry(CalvinCB(self.connect)) return if self.callback: self.callback(status=response.CalvinResponse(response.NOT_FOUND), actor_id=self.port.owner.id, port_name=self.port.name, port_id=self.port.id, peer_node_id=self.peer_port_meta.node_id, peer_actor_id=self.peer_port_meta.actor_id, peer_port_name=self.peer_port_meta.port_name, peer_port_id=self.peer_port_meta.port_id) return if reply == response.GONE: # Other end did not accept our port connection request, likely due to they have not got the message # about the tunnel in time _log.analyze(self.node.id, "+ RETRY", {'local_port': self.port, 'peer_port': self.peer_port_meta}, peer_node_id=self.peer_port_meta.node_id) if self.peer_port_meta.retries < 3: self.peer_port_meta.retries += 1 # Status here just indicate that we should have a tunnel self._connect_via_tunnel(status=response.CalvinResponse(True)) return else: if self.callback: self.callback(status=response.CalvinResponse(False), actor_id=self.port.owner.id, port_name=self.port.name, port_id=self.port.id, peer_node_id=self.peer_port_meta.node_id, peer_actor_id=self.peer_port_meta.actor_id, peer_port_name=self.peer_port_meta.port_name, peer_port_id=self.peer_port_meta.port_id) return # Set up the port's endpoint tunnel = self.token_tunnel.tunnels[self.peer_port_meta.node_id] self.port.set_queue(queue.get(self.port, peer_port_meta=self.peer_port_meta)) if self.port.direction == 'in': endp = endpoint.TunnelInEndpoint(self.port, tunnel, self.peer_port_meta.node_id, reply.data['port_id'], self.node.sched.trigger_loop) else: endp = endpoint.TunnelOutEndpoint(self.port, tunnel, self.peer_port_meta.node_id, reply.data['port_id'], self.node.sched.trigger_loop) if endp.use_monitor(): # register into main loop self.node.monitor.register_endpoint(endp) invalid_endpoint = self.port.attach_endpoint(endp) # remove previous endpoint if invalid_endpoint: if invalid_endpoint.use_monitor(): self.node.monitor.unregister_endpoint(invalid_endpoint) invalid_endpoint.destroy() # Done connecting the port if self.callback: self.callback(status=response.CalvinResponse(True), actor_id=self.port.owner.id, port_name=self.port.name, port_id=self.port.id, peer_node_id=self.peer_port_meta.node_id, peer_actor_id=self.peer_port_meta.actor_id, peer_port_name=self.peer_port_meta.port_name, peer_port_id=self.peer_port_meta.port_id) # Update storage self.node.storage.add_port(self.port, self.node.id, self.port.owner.id)
def _connected_via_tunnel(self, reply): """ Gets called when remote responds to our request for port connection """ _log.analyze(self.node.id, "+ " + str(reply), { 'local_port': self.port, 'peer_port': self.peer_port_meta }, peer_node_id=self.peer_port_meta.node_id, tb=True) if reply in [ response.BAD_REQUEST, response.NOT_FOUND, response.GATEWAY_TIMEOUT ]: # Other end did not accept our port connection request if self.peer_port_meta.retries < 2 and self.peer_port_meta.node_id: # Maybe it is on another node now lets retry and lookup the port # FIXME: Could the port have moved to our node and we need to check local??? self.peer_port_meta.retry(CalvinCB(self.connect)) return if self.callback: self.callback(status=response.CalvinResponse( response.NOT_FOUND), actor_id=self.port.owner.id, port_name=self.port.name, port_id=self.port.id, peer_node_id=self.peer_port_meta.node_id, peer_actor_id=self.peer_port_meta.actor_id, peer_port_name=self.peer_port_meta.port_name, peer_port_id=self.peer_port_meta.port_id) return if reply == response.GONE: # Other end did not accept our port connection request, likely due to they have not got the message # about the tunnel in time _log.analyze(self.node.id, "+ RETRY", { 'local_port': self.port, 'peer_port': self.peer_port_meta }, peer_node_id=self.peer_port_meta.node_id) if self.peer_port_meta.retries < 3: self.peer_port_meta.retries += 1 # Status here just indicate that we should have a tunnel self._connect_via_tunnel(status=response.CalvinResponse(True)) return else: if self.callback: self.callback(status=response.CalvinResponse(False), actor_id=self.port.owner.id, port_name=self.port.name, port_id=self.port.id, peer_node_id=self.peer_port_meta.node_id, peer_actor_id=self.peer_port_meta.actor_id, peer_port_name=self.peer_port_meta.port_name, peer_port_id=self.peer_port_meta.port_id) return # Set up the port's endpoint tunnel = self.token_tunnel.tunnels[self.peer_port_meta.node_id] self.port.set_queue( queue.get(self.port, peer_port_meta=self.peer_port_meta)) if self.port.direction == 'in': endp = endpoint.TunnelInEndpoint(self.port, tunnel, self.peer_port_meta.node_id, reply.data['port_id'], self.node.sched.trigger_loop) else: endp = endpoint.TunnelOutEndpoint(self.port, tunnel, self.peer_port_meta.node_id, reply.data['port_id'], self.node.sched.trigger_loop) if endp.use_monitor(): # register into main loop self.node.monitor.register_endpoint(endp) invalid_endpoint = self.port.attach_endpoint(endp) # remove previous endpoint if invalid_endpoint: if invalid_endpoint.use_monitor(): self.node.monitor.unregister_endpoint(invalid_endpoint) invalid_endpoint.destroy() # Done connecting the port if self.callback: self.callback(status=response.CalvinResponse(True), actor_id=self.port.owner.id, port_name=self.port.name, port_id=self.port.id, peer_node_id=self.peer_port_meta.node_id, peer_actor_id=self.peer_port_meta.actor_id, peer_port_name=self.peer_port_meta.port_name, peer_port_id=self.peer_port_meta.port_id) # Update storage self.node.storage.add_port(self.port, self.node.id, self.port.owner.id)
def create_port(routing="collect-unordered"): port = DummyPort() port.properties = {'routing': routing, "direction": "in"} return queue.get(port)
def create_port(self): port = DummyPort() port.properties = {'routing': self.routing, "direction": "out", 'nbr_peers': self.num_peers} return queue.get(port)
def create_port(): port = DummyPort() port.properties = {'routing': "dispatch-ordered", "direction": "out"} return queue.get(port)
def _connected_via_tunnel(self, reply): """ Gets called when remote responds to our request for port connection """ _log.analyze(self.node.id, "+ " + str(reply), { 'local_port': self.port, 'peer_port': self.peer_port_meta }, peer_node_id=self.peer_port_meta.node_id, tb=True) if reply in [ response.BAD_REQUEST, response.NOT_FOUND, response.GATEWAY_TIMEOUT ]: # Other end did not accept our port connection request if self.peer_port_meta.retries < 2 and self.peer_port_meta.node_id: # Maybe it is on another node now lets retry and lookup the port # FIXME: Could the port have moved to our node and we need to check local??? self.peer_port_meta.retry(CalvinCB(self.connect)) return self.async_reply( status=response.CalvinResponse(response.NOT_FOUND)) return if reply == response.GONE: # Other end did not accept our port connection request, likely due to they have not got the message # about the tunnel in time _log.analyze(self.node.id, "+ RETRY", { 'local_port': self.port, 'peer_port': self.peer_port_meta }, peer_node_id=self.peer_port_meta.node_id) if self.peer_port_meta.retries < 3: self.peer_port_meta.retries += 1 # Status here just indicate that we should have a tunnel self._connect_via_tunnel(status=response.CalvinResponse(True)) else: self.async_reply(status=response.CalvinResponse(False)) return # Update our peer port's properties with newly recieved information if self.peer_port_meta.properties is None: self.peer_port_meta.properties = reply.data.get( 'port_properties', {}) else: self.peer_port_meta.properties.update( reply.data.get('port_properties', {})) # Set up the port's endpoint tunnel = self.token_tunnel.tunnels[self.peer_port_meta.node_id] self.port.set_queue( queue.get(self.port, peer_port_meta=self.peer_port_meta)) cls = endpoint.TunnelInEndpoint if self.port.direction == 'in' else endpoint.TunnelOutEndpoint endp = cls(self.port, tunnel, self.peer_port_meta.node_id, reply.data['port_id'], self.peer_port_meta.properties, self.node.sched) invalid_endpoint = self.port.attach_endpoint(endp) invalid_endpoint.unregister(self.node.sched) invalid_endpoint.destroy() endp.register(self.node.sched) # Done connecting the port self.async_reply(status=response.CalvinResponse(True)) # Update storage self.node.storage.add_port(self.port, self.node.id, self.port.owner.id)