From c877ed87a62ccd03254ff95f7315038e1e75df26 Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Tue, 11 Aug 2026 08:29:39 +0800 Subject: [PATCH] log: add marker fan-out timing for project-open and interactive def-change Distinguish the two marker-policy fan-out paths in the log so we can tell which is slow: - apply_defs_to_new_link (project-open finalize): logs def count + link count + elapsed, only when marker_definitions is non-empty. - _marker_apply_concurrently (interactive create/update/delete def): logs link count + elapsed per fan-out. --- gns3server/controller/project.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/gns3server/controller/project.py b/gns3server/controller/project.py index 54ea44265..965252428 100644 --- a/gns3server/controller/project.py +++ b/gns3server/controller/project.py @@ -1260,6 +1260,14 @@ class Project: :param fail_msg: callable ``(link, error) -> log message`` """ + links = list(links) + if not links: + return + _t0 = time.time() + log.info( + "Project '%s' [%s]: fanning out marker operation to %d links...", + self._name, self._id, len(links) + ) sem = asyncio.Semaphore(32) async def guarded(link): @@ -1270,6 +1278,10 @@ class Project: log.warning(fail_msg(link, e)) await asyncio.gather(*(guarded(link) for link in links)) + log.info( + "Project '%s' [%s]: marker fan-out done in %.2fs", + self._name, self._id, time.time() - _t0 + ) @property def snapshots(self): @@ -1795,10 +1807,19 @@ class Project: n["port"].link = link link._created = True self.emit_notification("link.created", link.asdict()) - if valid: + if valid and self._marker_definitions: + _marker_t0 = time.time() + log.info( + "Project '%s' [%s]: applying %d marker definition(s) to %d links...", + self._name, self._id, len(self._marker_definitions), len(valid) + ) await asyncio.gather( *[self.apply_defs_to_new_link(link) for link, _ in valid] ) + log.info( + "Project '%s' [%s]: marker inheritance done in %.2fs", + self._name, self._id, time.time() - _marker_t0 + ) log.info("Project '%s' [%s]: created %d links", self._name, self._id, len(valid)) # Release any pre-allocated UDP ports that were not consumed by links for compute_id, ports in self._preallocated_udp_ports.items():