def test_get_not_neighbours(self): n1 = Server('n1', port=8000, id='22cd859d-ee91-4079-a112-000000000001') n2 = Server('n2', port=8000, id='22cd859d-ee91-4079-a112-000000000002') n3 = Server('n3', port=8000, id='22cd859d-ee91-4079-a112-000000000003') n3.route = None r1 = Server('r1', port=8000, id='22cd859d-ee91-4079-a112-000000000011') Route(destination=n1, cost=0) Route(destination=n2, proxy_server_or_gate=n2.gates[0]) Route(destination=r1, proxy_server_or_gate=n1, cost=1) me = Server('me', port=8000, me=True) db.session.add_all([n1, n2, n3, r1, me]) self.assertListEqual([n3, r1], me.get_not_neighbours())
async def _async_discover_new_neighbours( servers: t.List[Server] = None, changed_routes: t.Dict[Server, RouteContainer] = None) -> t.List[Server]: new_neighbours = [] if servers is None: servers = Server.get_not_neighbours() if servers: resp = await asyncio.gather( *[async_check_gates(server) for server in servers], return_exceptions=True) for new_route, server in zip(resp, servers): if new_route: server.set_route(new_route) new_neighbours.append(server) changed_routes[server] = new_route return new_neighbours
async def _async_refresh_route_table( self, discover_new_neighbours=False, check_current_neighbours=False, max_num_discovery=None) -> t.Dict[Server, RouteContainer]: """Gets route tables of all neighbours and updates its own table based on jump weights. Needs a Flask App Context to run. Parameters ---------- discover_new_neighbours: tries to discover new neighbours check_current_neighbours: checks if current neighbours are still neighbours max_num_discovery: maximum number of possible nodes to check as neighbour Returns ------- None """ self.logger.debug('Refresh Route Table') neighbours = Server.get_neighbours(session=self.session) not_neighbours = Server.get_not_neighbours(session=self.session) changed_routes: t.Dict[Server, RouteContainer] = {} not_neighbours_anymore = [] new_neighbours = [] aws = [] if check_current_neighbours: if neighbours: self.logger.debug(f"Checking current neighbours: " + ', '.join([str(s) for s in neighbours])) aws.append( _async_set_current_neighbours(neighbours, changed_routes)) else: self.logger.debug(f"No neighbour to check") if discover_new_neighbours: if not_neighbours[:max_num_discovery]: rs = list(not_neighbours) random.shuffle(rs) target = rs[:max_num_discovery] target.sort(key=lambda s: s.name) self.logger.debug( f"Checking new neighbours{f' (limited to {max_num_discovery})' if max_num_discovery else ''}: " + ', '.join([str(s) for s in target])) aws.append( _async_discover_new_neighbours(target, changed_routes)) else: self.logger.debug("No new neighbours to check") res = await asyncio.gather(*aws, return_exceptions=False) if check_current_neighbours and neighbours: not_neighbours_anymore = res.pop(0) if not_neighbours_anymore: self.logger.info( f"Lost direct connection to the following nodes: " + ', '.join([str(s) for s in not_neighbours_anymore])) if discover_new_neighbours and not_neighbours[:max_num_discovery]: new_neighbours = res.pop(0) if new_neighbours: self.logger.info(f'New neighbours found: ' + ', '.join([str(s) for s in new_neighbours])) else: self.logger.debug("No new neighbours found") # remove routes whose proxy_server is a node that is not a neighbour query = self.session.query(Route).filter( Route.proxy_server_id.in_([ s.id for s in list( set(not_neighbours).union(set(not_neighbours_anymore))) ])) rc = RouteContainer(None, None, None) for route in query.all(): route.set_route(rc) changed_routes[route.destination] = rc self.session.commit() # update neighbour lis neighbours = list( set(neighbours).union(set(new_neighbours)) - set(not_neighbours_anymore)) if neighbours: self.logger.debug( f"Getting routing tables from {', '.join([str(s) for s in neighbours])}" ) responses = await asyncio.gather(*[ ntwrk.async_get(server, 'api_1_0.routes', auth=get_root_auth()) for server in neighbours ]) cr = self._route_table_merge(dict(zip(neighbours, responses))) changed_routes.update(cr) return changed_routes