← back to Exo
subprocess fork fix
31d7bc2df6df7adea338186e5fb4c0a748b739eb · 2024-12-07 16:49:58 +0000 · Alex Cheema
Files touched
M exo/helpers.pyM exo/networking/udp/udp_discovery.pyM exo/orchestration/standard_node.py
Diff
commit 31d7bc2df6df7adea338186e5fb4c0a748b739eb
Author: Alex Cheema <alexcheema123@gmail.com>
Date: Sat Dec 7 16:49:58 2024 +0000
subprocess fork fix
---
exo/helpers.py | 25 ++++++++++++++-----------
exo/networking/udp/udp_discovery.py | 2 +-
exo/orchestration/standard_node.py | 2 +-
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/exo/helpers.py b/exo/helpers.py
index 65e52084..5abc50cd 100644
--- a/exo/helpers.py
+++ b/exo/helpers.py
@@ -8,9 +8,11 @@ import platform
import psutil
import uuid
import netifaces
+import subprocess
from pathlib import Path
import tempfile
import json
+from concurrent.futures import ThreadPoolExecutor
DEBUG = int(os.getenv("DEBUG", default="0"))
DEBUG_DISCOVERY = int(os.getenv("DEBUG_DISCOVERY", default="0"))
@@ -23,6 +25,9 @@ exo_text = r"""
\___/_/\_\___/
"""
+# Single shared thread pool for subprocess operations
+subprocess_pool = ThreadPoolExecutor(max_workers=4, thread_name_prefix="subprocess_worker")
+
def get_system_info():
if psutil.MACOS:
@@ -239,10 +244,15 @@ def get_all_ip_addresses_and_interfaces():
async def get_macos_interface_type(ifname: str) -> Optional[Tuple[int, str]]:
try:
- proc = await asyncio.create_subprocess_exec('system_profiler', 'SPNetworkDataType', '-json',
- stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
- output, _ = await proc.communicate()
- data = json.loads(output.decode('utf-8'))
+ # Use the shared subprocess_pool
+ output = await asyncio.get_running_loop().run_in_executor(subprocess_pool, lambda: subprocess.run(
+ ['system_profiler', 'SPNetworkDataType', '-json'],
+ capture_output=True,
+ text=True,
+ close_fds=True
+ ).stdout)
+
+ data = json.loads(output)
for interface in data.get('SPNetworkDataType', []):
if interface.get('interface') == ifname:
@@ -250,21 +260,14 @@ async def get_macos_interface_type(ifname: str) -> Optional[Tuple[int, str]]:
type_name = interface.get('type', '').lower()
name = interface.get('_name', '').lower()
- # Thunderbolt interfaces
if 'thunderbolt' in name:
return (5, "Thunderbolt")
-
- # Ethernet adapters
if hardware == 'ethernet' or type_name == 'ethernet':
if 'usb' in name:
return (4, "Ethernet [USB]")
return (4, "Ethernet")
-
- # WiFi/AirPort
if hardware == 'airport' or type_name == 'airport' or 'wi-fi' in name:
return (3, "WiFi")
-
- # VPN interfaces
if type_name == 'vpn':
return (1, "External Virtual")
diff --git a/exo/networking/udp/udp_discovery.py b/exo/networking/udp/udp_discovery.py
index 1909b1f4..168ebbee 100644
--- a/exo/networking/udp/udp_discovery.py
+++ b/exo/networking/udp/udp_discovery.py
@@ -42,7 +42,7 @@ class UDPDiscovery(Discovery):
listen_port: int,
broadcast_port: int,
create_peer_handle: Callable[[str, str, str, DeviceCapabilities], PeerHandle],
- broadcast_interval: int = 1,
+ broadcast_interval: int = 2.5,
discovery_timeout: int = 30,
device_capabilities: DeviceCapabilities = UNKNOWN_DEVICE_CAPABILITIES,
allowed_node_ids: List[str] = None,
diff --git a/exo/orchestration/standard_node.py b/exo/orchestration/standard_node.py
index b5064482..9ecc2ffc 100644
--- a/exo/orchestration/standard_node.py
+++ b/exo/orchestration/standard_node.py
@@ -58,7 +58,7 @@ class StandardNode(Node):
await self.update_peers(wait_for_peers)
await self.collect_topology(set())
if DEBUG >= 2: print(f"Collected topology: {self.topology}")
- asyncio.create_task(self.periodic_topology_collection(1.0))
+ asyncio.create_task(self.periodic_topology_collection(2.0))
async def stop(self) -> None:
await self.discovery.stop()
← 56842a27 ignore topology merges from the non-owner
·
back to Exo
·
prio mac check for interface 24130da4 →