mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-27 10:42:28 +02:00
perf: dedicated 500-worker thread pool for ubridge batch I/O
Replace the default asyncio executor (capped at ~32 threads) with a dedicated ThreadPoolExecutor sized for large-topology parallelism. When 500 nodes each call _connect_nio, up to 500 OS threads can now send blocking ubridge commands in parallel — no longer serialised by either the event loop or a small thread pool. - ubridge_hypervisor: module-level _ubridge_sync_pool (max_workers=500) - docker_vm._connect_nio: dispatches to the dedicated pool instead of the default executor
This commit is contained in:
parent
05934fa8e8
commit
b155980402
@ -38,6 +38,7 @@ from gns3server.utils.hostname import is_rfc1123_hostname_valid
|
|||||||
from gns3server.utils import macaddress_to_int, int_to_macaddress
|
from gns3server.utils import macaddress_to_int, int_to_macaddress
|
||||||
|
|
||||||
from gns3server.compute.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError
|
from gns3server.compute.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError
|
||||||
|
from gns3server.compute.ubridge.ubridge_hypervisor import _ubridge_sync_pool
|
||||||
from ..base_node import BaseNode
|
from ..base_node import BaseNode
|
||||||
|
|
||||||
from ..adapters.ethernet_adapter import EthernetAdapter
|
from ..adapters.ethernet_adapter import EthernetAdapter
|
||||||
@ -1242,7 +1243,7 @@ class DockerVM(BaseNode):
|
|||||||
async with getattr(self, lock_name):
|
async with getattr(self, lock_name):
|
||||||
loop = asyncio.get_running_loop()
|
loop = asyncio.get_running_loop()
|
||||||
await loop.run_in_executor(
|
await loop.run_in_executor(
|
||||||
None, # default thread-pool executor
|
_ubridge_sync_pool, # dedicated 500-worker thread pool
|
||||||
self._ubridge_hypervisor.send_batch_sync,
|
self._ubridge_hypervisor.send_batch_sync,
|
||||||
commands,
|
commands,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -19,12 +19,23 @@ import time
|
|||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import threading
|
import threading
|
||||||
|
import concurrent.futures
|
||||||
|
|
||||||
from gns3server.utils.asyncio import locking
|
from gns3server.utils.asyncio import locking
|
||||||
from .ubridge_error import UbridgeError
|
from .ubridge_error import UbridgeError
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Dedicated thread pool for blocking ubridge socket I/O. Every node gets
|
||||||
|
# its own ubridge process + socket, so N nodes can send commands in true
|
||||||
|
# OS-thread parallelism. The default asyncio executor caps at ~32 threads;
|
||||||
|
# sizing for the large-topology case (2500+ links → thousands of NIO add
|
||||||
|
# calls across hundreds of nodes).
|
||||||
|
_ubridge_sync_pool = concurrent.futures.ThreadPoolExecutor(
|
||||||
|
max_workers=500,
|
||||||
|
thread_name_prefix="ubridge-sync",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class UBridgeHypervisor:
|
class UBridgeHypervisor:
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user