|
@@ -7,7 +7,7 @@ from typing import List, Dict, Callable, Tuple, Coroutine
|
|
from exo.networking.discovery import Discovery
|
|
from exo.networking.discovery import Discovery
|
|
from exo.networking.peer_handle import PeerHandle
|
|
from exo.networking.peer_handle import PeerHandle
|
|
from exo.topology.device_capabilities import DeviceCapabilities, device_capabilities, UNKNOWN_DEVICE_CAPABILITIES
|
|
from exo.topology.device_capabilities import DeviceCapabilities, device_capabilities, UNKNOWN_DEVICE_CAPABILITIES
|
|
-from exo.helpers import DEBUG, DEBUG_DISCOVERY, get_all_ip_addresses
|
|
|
|
|
|
+from exo.helpers import DEBUG, DEBUG_DISCOVERY, get_all_ip_addresses_and_interfaces, get_interface_priority_and_type
|
|
|
|
|
|
|
|
|
|
class ListenProtocol(asyncio.DatagramProtocol):
|
|
class ListenProtocol(asyncio.DatagramProtocol):
|
|
@@ -41,7 +41,7 @@ class UDPDiscovery(Discovery):
|
|
node_port: int,
|
|
node_port: int,
|
|
listen_port: int,
|
|
listen_port: int,
|
|
broadcast_port: int,
|
|
broadcast_port: int,
|
|
- create_peer_handle: Callable[[str, str, DeviceCapabilities], PeerHandle],
|
|
|
|
|
|
+ create_peer_handle: Callable[[str, str, str, DeviceCapabilities], PeerHandle],
|
|
broadcast_interval: int = 1,
|
|
broadcast_interval: int = 1,
|
|
discovery_timeout: int = 30,
|
|
discovery_timeout: int = 30,
|
|
device_capabilities: DeviceCapabilities = UNKNOWN_DEVICE_CAPABILITIES,
|
|
device_capabilities: DeviceCapabilities = UNKNOWN_DEVICE_CAPABILITIES,
|
|
@@ -87,27 +87,27 @@ class UDPDiscovery(Discovery):
|
|
while True:
|
|
while True:
|
|
# Explicitly broadcasting on all assigned ips since broadcasting on `0.0.0.0` on MacOS does not broadcast over
|
|
# Explicitly broadcasting on all assigned ips since broadcasting on `0.0.0.0` on MacOS does not broadcast over
|
|
# the Thunderbolt bridge when other connection modalities exist such as WiFi or Ethernet
|
|
# the Thunderbolt bridge when other connection modalities exist such as WiFi or Ethernet
|
|
- for addr in get_all_ip_addresses():
|
|
|
|
|
|
+ for addr, interface_name in get_all_ip_addresses_and_interfaces():
|
|
|
|
+ interface_priority, _ = get_interface_priority_and_type(interface_name)
|
|
message = json.dumps({
|
|
message = json.dumps({
|
|
"type": "discovery",
|
|
"type": "discovery",
|
|
"node_id": self.node_id,
|
|
"node_id": self.node_id,
|
|
"grpc_port": self.node_port,
|
|
"grpc_port": self.node_port,
|
|
"device_capabilities": self.device_capabilities.to_dict(),
|
|
"device_capabilities": self.device_capabilities.to_dict(),
|
|
- "priority": 1, # For now, every interface has the same priority. We can make this better by prioriting interfaces based on bandwidth, latency, and jitter e.g. prioritise Thunderbolt over WiFi.
|
|
|
|
|
|
+ "priority": interface_priority, # TODO: Prioritise interfaces based on bandwidth, latency, and jitter e.g. prioritise Thunderbolt over WiFi.
|
|
|
|
+ "interface_name": interface_name,
|
|
})
|
|
})
|
|
- if DEBUG_DISCOVERY >= 3: print(f"Broadcasting presence at ({addr}): {message}")
|
|
|
|
|
|
+ if DEBUG_DISCOVERY >= 3: print(f"Broadcasting presence at ({addr} - {interface_name} - {interface_priority}): {message}")
|
|
|
|
|
|
transport = None
|
|
transport = None
|
|
try:
|
|
try:
|
|
transport, _ = await asyncio.get_event_loop().create_datagram_endpoint(lambda: BroadcastProtocol(message, self.broadcast_port), local_addr=(addr, 0), family=socket.AF_INET)
|
|
transport, _ = await asyncio.get_event_loop().create_datagram_endpoint(lambda: BroadcastProtocol(message, self.broadcast_port), local_addr=(addr, 0), family=socket.AF_INET)
|
|
- if DEBUG_DISCOVERY >= 3:
|
|
|
|
- print(f"Broadcasting presence at ({addr})")
|
|
|
|
|
|
+ if DEBUG_DISCOVERY >= 3: print(f"Broadcasting presence at ({addr} - {interface_name} - {interface_priority})")
|
|
except Exception as e:
|
|
except Exception as e:
|
|
- print(f"Error in broadcast presence ({addr}): {e}")
|
|
|
|
|
|
+ print(f"Error in broadcast presence ({addr} - {interface_name} - {interface_priority}): {e}")
|
|
finally:
|
|
finally:
|
|
if transport:
|
|
if transport:
|
|
- try:
|
|
|
|
- transport.close()
|
|
|
|
|
|
+ try: transport.close()
|
|
except Exception as e:
|
|
except Exception as e:
|
|
if DEBUG_DISCOVERY >= 2: print(f"Error closing transport: {e}")
|
|
if DEBUG_DISCOVERY >= 2: print(f"Error closing transport: {e}")
|
|
if DEBUG_DISCOVERY >= 2: traceback.print_exc()
|
|
if DEBUG_DISCOVERY >= 2: traceback.print_exc()
|
|
@@ -144,6 +144,7 @@ class UDPDiscovery(Discovery):
|
|
peer_host = addr[0]
|
|
peer_host = addr[0]
|
|
peer_port = message["grpc_port"]
|
|
peer_port = message["grpc_port"]
|
|
peer_prio = message["priority"]
|
|
peer_prio = message["priority"]
|
|
|
|
+ peer_interface_name = message["interface_name"]
|
|
device_capabilities = DeviceCapabilities(**message["device_capabilities"])
|
|
device_capabilities = DeviceCapabilities(**message["device_capabilities"])
|
|
|
|
|
|
if peer_id not in self.known_peers or self.known_peers[peer_id][0].addr() != f"{peer_host}:{peer_port}":
|
|
if peer_id not in self.known_peers or self.known_peers[peer_id][0].addr() != f"{peer_host}:{peer_port}":
|
|
@@ -153,7 +154,7 @@ class UDPDiscovery(Discovery):
|
|
if DEBUG >= 1:
|
|
if DEBUG >= 1:
|
|
print(f"Ignoring peer {peer_id} at {peer_host}:{peer_port} with priority {peer_prio} because we already know about a peer with higher or equal priority: {existing_peer_prio}")
|
|
print(f"Ignoring peer {peer_id} at {peer_host}:{peer_port} with priority {peer_prio} because we already know about a peer with higher or equal priority: {existing_peer_prio}")
|
|
return
|
|
return
|
|
- new_peer_handle = self.create_peer_handle(peer_id, f"{peer_host}:{peer_port}", device_capabilities)
|
|
|
|
|
|
+ new_peer_handle = self.create_peer_handle(peer_id, f"{peer_host}:{peer_port}", peer_interface_name, device_capabilities)
|
|
if not await new_peer_handle.health_check():
|
|
if not await new_peer_handle.health_check():
|
|
if DEBUG >= 1: print(f"Peer {peer_id} at {peer_host}:{peer_port} is not healthy. Skipping.")
|
|
if DEBUG >= 1: print(f"Peer {peer_id} at {peer_host}:{peer_port} is not healthy. Skipping.")
|
|
return
|
|
return
|