controller: snapshot history + layout_map + UI grid
snapshot_history.py — async periodic capture per instance:
interval_sec / keep_last (FIFO eviction) / dir configurable
GET /snapshots/{instance}?limit=N → list metadata
GET /snapshots/{instance}/{filename} → image bytes
Persisted в /var/lib/cuda-grid/snapshots/{instance}/<ts>.png
layout_map / layout_filter_target в InstanceCfg — для будущей runtime switch
архитектуры (через streamselect либо filter rework — выбор за Phase 7).
Текущий _set_layout dispatches к layout_filter_target c index из map.
UI:
+ Layout buttons (quad/single/main_plus_preview placeholder)
+ Snapshot history grid с thumbnails (loaded /snapshots/{inst}?limit=24)
+ "Reload history" button
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -219,12 +219,12 @@ class CommandDispatcher:
|
||||
# ─── Layout ────────────────────────────────────────────────────
|
||||
|
||||
async def _set_layout(self, inst: InstanceCfg, layout: str) -> None:
|
||||
if layout not in PREDEFINED_LAYOUTS:
|
||||
if layout not in inst.layout_map:
|
||||
log.warning(
|
||||
"dispatch.unknown_layout",
|
||||
instance=inst.name,
|
||||
layout=layout,
|
||||
available=PREDEFINED_LAYOUTS,
|
||||
available=list(inst.layout_map.keys()),
|
||||
)
|
||||
return
|
||||
|
||||
@@ -232,12 +232,13 @@ class CommandDispatcher:
|
||||
client = self._client(inst)
|
||||
try:
|
||||
reply = await client.send_command(
|
||||
inst.filter_target, "layout", layout
|
||||
inst.layout_filter_target, "map", str(inst.layout_map[layout])
|
||||
)
|
||||
log.info(
|
||||
"dispatch.layout_set",
|
||||
instance=inst.name,
|
||||
layout=layout,
|
||||
index=inst.layout_map[layout],
|
||||
ffmpeg_reply=reply,
|
||||
)
|
||||
except (TimeoutError, Exception) as e:
|
||||
|
||||
Reference in New Issue
Block a user