mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-24 11:52:23 +03:00
perf: batch update/delete marker-def fan-out too (full project-level)
per-def operations are project-level — create, update AND delete all
modify the marker policy on every link — so all three must batch, not
just create.
Extend memory_only to update_marker and stop_marker (merge/delete into
_markers + refresh _link_data, no per-link HTTP), and route
update_marker_definition and delete_marker_definition through the same
two-phase path as create: memory-only per link, then one
PUT /projects/{id}/nios/batch per compute.
Trade-off: a full reapply resets every marker's pcap on the link (the
old precise update_marker/stop_marker preserved sibling pcaps). For
project-level policy changes this is acceptable — real-time insight
matters more than pcap continuity, and batching turns 5000+ round-trips
into one per compute.
This commit is contained in:
parent
48991f2d29
commit
57558508bf
1
.gitignore
vendored
1
.gitignore
vendored
@ -86,3 +86,4 @@ venv
|
|||||||
gns3server/agent/gns3_copilot/cache/tiktoken/
|
gns3server/agent/gns3_copilot/cache/tiktoken/
|
||||||
|
|
||||||
gns3.log
|
gns3.log
|
||||||
|
/configs/
|
||||||
|
|||||||
@ -1158,23 +1158,25 @@ class Project:
|
|||||||
# data_link_type decides which links host an inherited copy (serial
|
# data_link_type decides which links host an inherited copy (serial
|
||||||
# links are skipped unless a WAN encapsulation is chosen), so a change
|
# links are skipped unless a WAN encapsulation is chosen), so a change
|
||||||
# needs a full re-fan-out: drop every copy, then re-apply.
|
# needs a full re-fan-out: drop every copy, then re-apply.
|
||||||
await self._marker_apply_concurrently(
|
for link in affected:
|
||||||
affected,
|
try:
|
||||||
lambda link: link.stop_marker(f"global-{name}", inherited=True, dump=False),
|
await link.stop_marker(f"global-{name}", inherited=True, dump=False, memory_only=True)
|
||||||
lambda link, e: f"Failed to remove inherited marker global-{name} from link {link.id}: {e}",
|
except ControllerError as e:
|
||||||
)
|
log.warning("Failed to remove inherited marker global-%s from link %s: %s", name, link.id, e)
|
||||||
await self._apply_def_to_all_links(name)
|
await self._apply_def_to_all_links(name)
|
||||||
else:
|
else:
|
||||||
# Sync: update every inherited copy across all links.
|
# Sync: update every inherited copy across all links in memory, then
|
||||||
await self._marker_apply_concurrently(
|
# batch-push to computes (one PUT /nios/batch per compute).
|
||||||
affected,
|
for link in affected:
|
||||||
lambda link: link.update_marker(
|
try:
|
||||||
f"global-{name}", bpf=d["bpf"], tag=d.get("tag"), direction=d.get("direction"),
|
await link.update_marker(
|
||||||
color=d.get("color"), highlight_duration=d.get("highlight_duration"), inherited=True,
|
f"global-{name}", bpf=d["bpf"], tag=d.get("tag"), direction=d.get("direction"),
|
||||||
dump=False
|
color=d.get("color"), highlight_duration=d.get("highlight_duration"), inherited=True,
|
||||||
),
|
dump=False, memory_only=True
|
||||||
lambda link, e: f"Failed to sync marker global-{name} on link {link.id}: {e}",
|
)
|
||||||
)
|
except ControllerError as e:
|
||||||
|
log.warning("Failed to sync marker global-%s on link %s: %s", name, link.id, e)
|
||||||
|
await self._batch_update_link_nios(affected)
|
||||||
self.dump()
|
self.dump()
|
||||||
self.emit_notification("project.updated", self.asdict())
|
self.emit_notification("project.updated", self.asdict())
|
||||||
|
|
||||||
@ -1195,12 +1197,13 @@ class Project:
|
|||||||
if f"global-{name}" in link.markers
|
if f"global-{name}" in link.markers
|
||||||
and link.markers[f"global-{name}"].get("inherited_from") == name
|
and link.markers[f"global-{name}"].get("inherited_from") == name
|
||||||
]
|
]
|
||||||
await self._marker_apply_concurrently(
|
for link in affected:
|
||||||
affected,
|
try:
|
||||||
lambda link: link.stop_marker(f"global-{name}", inherited=True),
|
await link.stop_marker(f"global-{name}", inherited=True, memory_only=True)
|
||||||
# A missing compute or broken link shouldn't block the delete.
|
except ControllerError as e:
|
||||||
lambda link, e: f"Failed to remove inherited marker global-{name} from link {link.id}: {e}",
|
# A missing compute or broken link shouldn't block the delete.
|
||||||
)
|
log.warning("Failed to remove inherited marker global-%s from link %s: %s", name, link.id, e)
|
||||||
|
await self._batch_update_link_nios(affected)
|
||||||
|
|
||||||
self.dump()
|
self.dump()
|
||||||
self.emit_notification("project.updated", self.asdict())
|
self.emit_notification("project.updated", self.asdict())
|
||||||
|
|||||||
@ -497,7 +497,7 @@ class UDPLink(Link):
|
|||||||
self._link_data[1]["markers"] = node2_markers
|
self._link_data[1]["markers"] = node2_markers
|
||||||
self._link_data[1]["suspend"] = self._suspended
|
self._link_data[1]["suspend"] = self._suspended
|
||||||
|
|
||||||
async def stop_marker(self, name, inherited=False, dump=True):
|
async def stop_marker(self, name, inherited=False, dump=True, memory_only=False):
|
||||||
"""
|
"""
|
||||||
Remove a traffic-insight marker from this link.
|
Remove a traffic-insight marker from this link.
|
||||||
|
|
||||||
@ -522,6 +522,12 @@ class UDPLink(Link):
|
|||||||
|
|
||||||
capture_node_id = self._markers[name].get("capture_node_id")
|
capture_node_id = self._markers[name].get("capture_node_id")
|
||||||
del self._markers[name]
|
del self._markers[name]
|
||||||
|
if memory_only:
|
||||||
|
# Project-level def-delete fan-out: marker is gone from _markers;
|
||||||
|
# refresh _link_data so the batch dispatch drops it from uBridge
|
||||||
|
# via full reapply. No per-link delete round-trip, notification or dump.
|
||||||
|
self._refresh_link_data()
|
||||||
|
return
|
||||||
# Remove the marker filter + its pcap on the capture node directly — NOT a
|
# Remove the marker filter + its pcap on the capture node directly — NOT a
|
||||||
# full NIO reapply (which would reset_packet_filters and close/reopen every
|
# full NIO reapply (which would reset_packet_filters and close/reopen every
|
||||||
# sibling marker's pcap). delete_packet_filter removes just this filter;
|
# sibling marker's pcap). delete_packet_filter removes just this filter;
|
||||||
@ -541,7 +547,7 @@ class UDPLink(Link):
|
|||||||
if dump:
|
if dump:
|
||||||
self._project.dump()
|
self._project.dump()
|
||||||
|
|
||||||
async def update_marker(self, name, bpf=None, tag=None, enabled=None, direction=_UNSET, color=None, highlight_duration=None, inherited=False, dump=True):
|
async def update_marker(self, name, bpf=None, tag=None, enabled=None, direction=_UNSET, color=None, highlight_duration=None, inherited=False, dump=True, memory_only=False):
|
||||||
"""
|
"""
|
||||||
Update an existing marker's fields and push to uBridge fine-grained — no
|
Update an existing marker's fields and push to uBridge fine-grained — no
|
||||||
full NIO reapply, so sibling markers' pcaps stay open. bpf/tag/direction
|
full NIO reapply, so sibling markers' pcaps stay open. bpf/tag/direction
|
||||||
@ -590,6 +596,13 @@ class UDPLink(Link):
|
|||||||
if direction is not _UNSET:
|
if direction is not _UNSET:
|
||||||
marker_info["direction"] = direction # None = clear back to both directions
|
marker_info["direction"] = direction # None = clear back to both directions
|
||||||
|
|
||||||
|
if memory_only:
|
||||||
|
# Project-level def sync fan-out: state is already merged into
|
||||||
|
# _markers; just refresh _link_data so the batch dispatch carries
|
||||||
|
# it. No per-link uBridge rebuild, notification or dump.
|
||||||
|
self._refresh_link_data()
|
||||||
|
return
|
||||||
|
|
||||||
# Push to uBridge fine-grained — NO full NIO reapply (which would
|
# Push to uBridge fine-grained — NO full NIO reapply (which would
|
||||||
# reset_packet_filters and close/reopen every sibling marker's pcap):
|
# reset_packet_filters and close/reopen every sibling marker's pcap):
|
||||||
# * bpf/tag/direction changed → rebuild just this filter (delete + add),
|
# * bpf/tag/direction changed → rebuild just this filter (delete + add),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user