mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-23 03:12:22 +03:00
perf: parallelize batch NIO creation across nodes
create_batch_nios bound NIOs in a serial for-loop, so during project open every builtin L2 node (ethernet_switch/hub/cloud/nat) started its uBridge one at a time (~0.5s each for fork + AF_UNIX connect). Group entries by node and bind in parallel with asyncio.gather — mirroring update_batch_nios — so independent uBridge processes start concurrently. Within a node, entries stay serial to respect the per-node uBridge command lock.
This commit is contained in:
parent
958aa59d7e
commit
1dd334caff
@ -245,21 +245,36 @@ async def create_batch_nios(
|
|||||||
binding in memory; started nodes additionally wire uBridge.
|
binding in memory; started nodes additionally wire uBridge.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
added = 0
|
# Group entries by node so different nodes' uBridge processes are wired
|
||||||
|
# in parallel (each node has its own AF_UNIX socket). Within a node
|
||||||
|
# entries are serial to respect the per-node uBridge command lock.
|
||||||
|
# This is what makes builtin L2 nodes (ethernet_switch/hub/cloud/nat)
|
||||||
|
# start their uBridge concurrently during project open instead of one
|
||||||
|
# at a time (~0.5s each for fork + socket connect).
|
||||||
|
per_node = {}
|
||||||
for entry in batch.nios:
|
for entry in batch.nios:
|
||||||
node = project.get_node(entry.node_id)
|
per_node.setdefault(entry.node_id, []).append(entry)
|
||||||
nio_settings = jsonable_encoder(entry.nio, exclude_unset=True)
|
|
||||||
# Dynamips.create_nio(self, node, nio_settings) is async and takes an
|
async def _create_one_node(node_id, entries):
|
||||||
# extra positional 'node'. Detect via bound-method parameter count:
|
node = project.get_node(node_id)
|
||||||
# standard == 1, Dynamips == 2. Await the async variant.
|
# Dynamips.create_nio(self, node, nio_settings) is async and takes
|
||||||
|
# an extra positional 'node'; other managers' create_nio(nio_settings)
|
||||||
|
# is synchronous. Detect once per node via bound-method parameter
|
||||||
|
# count (standard == 1, Dynamips == 2) and await the async variant.
|
||||||
sig = inspect.signature(node.manager.create_nio)
|
sig = inspect.signature(node.manager.create_nio)
|
||||||
if len(sig.parameters) >= 2:
|
dynamips_style = len(sig.parameters) >= 2
|
||||||
nio = await node.manager.create_nio(node, nio_settings)
|
for entry in entries:
|
||||||
else:
|
nio_settings = jsonable_encoder(entry.nio, exclude_unset=True)
|
||||||
nio = node.manager.create_nio(nio_settings)
|
if dynamips_style:
|
||||||
await _add_nio_binding(node, entry.adapter_number, entry.port_number, nio)
|
nio = await node.manager.create_nio(node, nio_settings)
|
||||||
added += 1
|
else:
|
||||||
return {"added": added}
|
nio = node.manager.create_nio(nio_settings)
|
||||||
|
await _add_nio_binding(node, entry.adapter_number, entry.port_number, nio)
|
||||||
|
|
||||||
|
await asyncio.gather(
|
||||||
|
*[_create_one_node(nid, ents) for nid, ents in per_node.items()]
|
||||||
|
)
|
||||||
|
return {"added": len(batch.nios)}
|
||||||
|
|
||||||
|
|
||||||
@router.put(
|
@router.put(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user