Fixed wrong full refresh

This commit is contained in:
2026-03-23 22:32:05 +01:00
parent 3bcf50f55f
commit 3ea551bc1a

View File

@@ -37,7 +37,7 @@ def _mk_span_rows(span, depth: int, total_ms: float) -> list:
""" """
rows = [] rows = []
indent = [Div(cls="mf-profiler-span-indent") for _ in range(depth)] indent = [Div(cls="mf-profiler-span-indent") for _ in range(depth)]
if isinstance(span, CumulativeSpan): if isinstance(span, CumulativeSpan):
pct = (span.total_ms / total_ms * 100) if total_ms > 0 else 0 pct = (span.total_ms / total_ms * 100) if total_ms > 0 else 0
duration_cls = _span_duration_cls(span.total_ms) duration_cls = _span_duration_cls(span.total_ms)
@@ -57,7 +57,7 @@ def _mk_span_rows(span, depth: int, total_ms: float) -> list:
cls="mf-profiler-span-row", cls="mf-profiler-span-row",
) )
rows.append(row) rows.append(row)
else: else:
pct = (span.duration_ms / total_ms * 100) if total_ms > 0 else 0 pct = (span.duration_ms / total_ms * 100) if total_ms > 0 else 0
duration_cls = _span_duration_cls(span.duration_ms) duration_cls = _span_duration_cls(span.duration_ms)
@@ -75,7 +75,7 @@ def _mk_span_rows(span, depth: int, total_ms: float) -> list:
rows.append(row) rows.append(row)
for child in span.children: for child in span.children:
rows.extend(_mk_span_rows(child, depth + 1, total_ms)) rows.extend(_mk_span_rows(child, depth + 1, total_ms))
return rows return rows
@@ -111,7 +111,7 @@ class Commands(BaseCommands):
self._owner, self._owner,
self._owner.handle_toggle_detail_view, self._owner.handle_toggle_detail_view,
).htmx(target=f"#{self._id}") ).htmx(target=f"#{self._id}")
def toggle_enable(self): def toggle_enable(self):
return Command( return Command(
"ProfilerToggleEnable", "ProfilerToggleEnable",
@@ -145,7 +145,7 @@ class Commands(BaseCommands):
self._owner, self._owner,
self._owner.handle_select_trace, self._owner.handle_select_trace,
kwargs={"trace_id": trace_id}, kwargs={"trace_id": trace_id},
).htmx(target=f"#{self._id}") ).htmx(target=f"#tr_{trace_id}")
class Profiler(SingleInstance): class Profiler(SingleInstance):
@@ -186,15 +186,24 @@ class Profiler(SingleInstance):
def handle_select_trace(self, trace_id: str): def handle_select_trace(self, trace_id: str):
"""Select a trace row and re-render to show it highlighted.""" """Select a trace row and re-render to show it highlighted."""
if self._selected_id is not None:
old_trace = next(trace for trace in profiler.traces if trace.trace_id == self._selected_id)
else:
old_trace = None
self._selected_id = trace_id self._selected_id = trace_id
return self trace = next(trace for trace in profiler.traces if trace.trace_id == trace_id)
return (self._mk_trace_item(trace),
self._mk_trace_item(old_trace),
self._panel.set_right(self._mk_right_panel(trace)))
def handle_toggle_detail_view(self): def handle_toggle_detail_view(self):
"""Toggle detail panel between tree and pie view.""" """Toggle detail panel between tree and pie view."""
self._detail_view = "pie" if self._detail_view == "tree" else "tree" self._detail_view = "pie" if self._detail_view == "tree" else "tree"
logger.debug(f"Profiler detail view set to {self._detail_view}") logger.debug(f"Profiler detail view set to {self._detail_view}")
return self return self
def handle_refresh(self): def handle_refresh(self):
"""Refresh the trace list without changing selection.""" """Refresh the trace list without changing selection."""
return self return self
@@ -245,32 +254,36 @@ class Profiler(SingleInstance):
id=f"tb_{self._id}", id=f"tb_{self._id}",
) )
def _mk_trace_item(self, trace: ProfilingTrace):
if trace is None:
return None
ts = trace.timestamp.strftime("%H:%M:%S.") + f"{trace.timestamp.microsecond // 1000:03d}"
duration_cls = self._duration_cls(trace.total_duration_ms)
row_cls = "mf-profiler-row mf-profiler-row-selected" if trace.trace_id == self._selected_id else "mf-profiler-row"
return mk.mk(
Div(
Div(
Span(trace.command_name, cls="mf-profiler-cmd"),
Span(trace.command_description, cls="mf-profiler-cmd-description"),
cls="mf-profiler-cmd-cell",
),
Span(f"{trace.total_duration_ms:.1f} ms", cls=f"mf-profiler-duration {duration_cls}"),
Span(ts, cls="mf-profiler-ts"),
cls=row_cls,
id=f"tr_{trace.trace_id}",
),
command=self.commands.select_trace(trace.trace_id),
)
def _mk_trace_list(self): def _mk_trace_list(self):
"""Build the trace list with one clickable row per recorded trace.""" """Build the trace list with one clickable row per recorded trace."""
traces = profiler.traces traces = profiler.traces
if not traces: if not traces:
return Div("No traces recorded.", cls="mf-profiler-empty") return Div("No traces recorded.", cls="mf-profiler-empty")
rows = [] rows = [self._mk_trace_item(trace) for trace in reversed(traces)]
for trace in reversed(traces):
ts = trace.timestamp.strftime("%H:%M:%S.") + f"{trace.timestamp.microsecond // 1000:03d}"
duration_cls = self._duration_cls(trace.total_duration_ms)
row_cls = "mf-profiler-row mf-profiler-row-selected" if trace.trace_id == self._selected_id else "mf-profiler-row"
row = mk.mk(
Div(
Div(
Span(trace.command_name, cls="mf-profiler-cmd"),
Span(trace.command_description, cls="mf-profiler-cmd-description"),
cls="mf-profiler-cmd-cell",
),
Span(f"{trace.total_duration_ms:.1f} ms", cls=f"mf-profiler-duration {duration_cls}"),
Span(ts, cls="mf-profiler-ts"),
cls=row_cls,
),
command=self.commands.select_trace(trace.trace_id),
)
rows.append(row)
return Div( return Div(
Div( Div(
@@ -286,7 +299,7 @@ class Profiler(SingleInstance):
def _mk_detail_placeholder(self): def _mk_detail_placeholder(self):
"""Placeholder shown in the right panel before a trace is selected.""" """Placeholder shown in the right panel before a trace is selected."""
return Div("Select a trace to view details.", cls="mf-profiler-empty") return Div("Select a trace to view details.", cls="mf-profiler-empty")
def _mk_detail_header(self, trace: "ProfilingTrace"): def _mk_detail_header(self, trace: "ProfilingTrace"):
"""Build the detail panel header with title and tree/pie toggle. """Build the detail panel header with title and tree/pie toggle.
@@ -305,12 +318,14 @@ class Profiler(SingleInstance):
tree_cls = "mf-profiler-view-btn mf-profiler-view-btn-active" if self._detail_view == "tree" else "mf-profiler-view-btn" tree_cls = "mf-profiler-view-btn mf-profiler-view-btn-active" if self._detail_view == "tree" else "mf-profiler-view-btn"
pie_cls = "mf-profiler-view-btn mf-profiler-view-btn-active" if self._detail_view == "pie" else "mf-profiler-view-btn" pie_cls = "mf-profiler-view-btn mf-profiler-view-btn-active" if self._detail_view == "pie" else "mf-profiler-view-btn"
toggle = Div( toggle = Div(
mk.icon(text_bullet_list_tree20_filled, command=self.commands.toggle_detail_view(), tooltip="Span tree", cls=tree_cls), mk.icon(text_bullet_list_tree20_filled, command=self.commands.toggle_detail_view(), tooltip="Span tree",
mk.icon(data_pie24_regular, command=self.commands.toggle_detail_view(), tooltip="Pie chart (coming soon)", cls=pie_cls), cls=tree_cls),
mk.icon(data_pie24_regular, command=self.commands.toggle_detail_view(), tooltip="Pie chart (coming soon)",
cls=pie_cls),
cls="mf-profiler-view-toggle", cls="mf-profiler-view-toggle",
) )
return Div(title, toggle, cls="mf-profiler-detail-header") return Div(title, toggle, cls="mf-profiler-detail-header")
def _mk_detail_body(self, trace: "ProfilingTrace"): def _mk_detail_body(self, trace: "ProfilingTrace"):
"""Build the scrollable detail body: metadata, kwargs and span breakdown. """Build the scrollable detail body: metadata, kwargs and span breakdown.
@@ -321,28 +336,28 @@ class Profiler(SingleInstance):
A FT element for the detail body. A FT element for the detail body.
""" """
from types import SimpleNamespace from types import SimpleNamespace
meta_props = Properties( meta_props = Properties(
self, self,
conf=PropertiesConf( conf=PropertiesConf(
obj=trace, obj=trace,
groups={"Metadata": { groups={"Metadata": {
"command": "command_name", "command": "command_name",
"description": "command_description", "description": "command_description",
"duration_ms": "total_duration_ms", "duration_ms": "total_duration_ms",
"timestamp": "timestamp", "timestamp": "timestamp",
}}, }},
), ),
_id="-detail-meta", _id="-detail-meta",
) )
kwargs_obj = SimpleNamespace(**trace.kwargs) if trace.kwargs else SimpleNamespace() kwargs_obj = SimpleNamespace(**trace.kwargs) if trace.kwargs else SimpleNamespace()
kwargs_props = Properties( kwargs_props = Properties(
self, self,
conf=PropertiesConf(obj=kwargs_obj, groups={"kwargs": {"*": ""}}), conf=PropertiesConf(obj=kwargs_obj, groups={"kwargs": {"*": ""}}),
_id="-detail-kwargs", _id="-detail-kwargs",
) )
span_props = None span_props = None
if trace.root_span is not None: if trace.root_span is not None:
span_props = Properties( span_props = Properties(
@@ -354,13 +369,13 @@ class Profiler(SingleInstance):
), ),
_id="-detail-spans", _id="-detail-spans",
) )
if self._detail_view == "pie": if self._detail_view == "pie":
pie_placeholder = Div("Pie chart — coming soon.", cls="mf-profiler-empty") pie_placeholder = Div("Pie chart — coming soon.", cls="mf-profiler-empty")
return Div(meta_props, kwargs_props, pie_placeholder, cls="mf-profiler-detail-body") return Div(meta_props, kwargs_props, pie_placeholder, cls="mf-profiler-detail-body")
return Div(meta_props, kwargs_props, span_props, cls="mf-profiler-detail-body") return Div(meta_props, kwargs_props, span_props, cls="mf-profiler-detail-body")
def _mk_detail_panel(self, trace: "ProfilingTrace"): def _mk_detail_panel(self, trace: "ProfilingTrace"):
"""Build the full detail panel for a selected trace. """Build the full detail panel for a selected trace.
@@ -376,6 +391,14 @@ class Profiler(SingleInstance):
cls="mf-profiler-detail", cls="mf-profiler-detail",
) )
def _mk_right_panel(self, trace: "ProfilingTrace"):
"""Build the right panel with a trace detail view."""
return (
self._mk_detail_panel(trace)
if trace is not None
else self._mk_detail_placeholder()
)
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# Render # Render
# ------------------------------------------------------------------ # ------------------------------------------------------------------
@@ -386,15 +409,9 @@ class Profiler(SingleInstance):
selected_trace = next( selected_trace = next(
(t for t in profiler.traces if t.trace_id == self._selected_id), None (t for t in profiler.traces if t.trace_id == self._selected_id), None
) )
right_panel = (
self._mk_detail_panel(selected_trace)
if selected_trace is not None
else self._mk_detail_placeholder()
)
self._panel.set_main(self._mk_trace_list()) self._panel.set_main(self._mk_trace_list())
self._panel.set_right(right_panel) self._panel.set_right(self._mk_right_panel(selected_trace))
return Div( return Div(
self._mk_toolbar(), self._mk_toolbar(),
self._panel, self._panel,