修复若干问题

This commit is contained in:
2026-08-15 02:51:11 +08:00
parent 282768e0ea
commit 04a9156cd6
25 changed files with 631 additions and 176 deletions
+12 -3
View File
@@ -1,9 +1,14 @@
import {Stack,Typography} from "@mui/material";
import type {Gallery_Capture_Session,Gallery_Captured_Frame,Gallery_Render_Plan} from "../protocol/gallery_types";
import type {Gallery_Capture_Session,Gallery_Captured_Frame,Gallery_Render_Plan,Json_Value} from "../protocol/gallery_types";
import {Metric_Grid} from "../common/metric_grid";
import {Json_Viewer} from "../common/json_viewer";
import {format_nanoseconds} from "../protocol/format";
function attachment_value(type:string,content:string):Json_Value {
if(!type.endsWith(".json"))return content;
try{return JSON.parse(content) as Json_Value;}catch{return content;}
}
export function Node_Detail({frame,plan,session,selected_node_id}:{frame:Gallery_Captured_Frame;plan:Gallery_Render_Plan;session:Gallery_Capture_Session;selected_node_id:number|null}) {
const node=plan.nodes.find(item=>item.node_id===selected_node_id);
const execution=frame.node_executions.find(item=>item.node_id===selected_node_id);
@@ -22,6 +27,10 @@ export function Node_Detail({frame,plan,session,selected_node_id}:{frame:Gallery
["Critical",`${((analysis?.critical_path_contribution??0)*100).toFixed(2)}%`],
["Moving avg",format_nanoseconds(history?.moving_average_ns)],
["P95",format_nanoseconds(history?.p95_ns)],
["P99",format_nanoseconds(history?.p99_ns)]
]}/>{execution.metrics&&<Json_Viewer value={execution.metrics}/>}</Stack>;
["P99",format_nanoseconds(history?.p99_ns)],
["CPU avg",format_nanoseconds(history?.average_cpu_ns)],
["CPU P95",format_nanoseconds(history?.p95_cpu_ns)],
["External avg",format_nanoseconds(history?.average_external_ns)],
["External P95",format_nanoseconds(history?.p95_external_ns)]
]}/>{execution.metrics&&<Json_Viewer value={execution.metrics}/>} {execution.attachments.map((attachment,index)=><Stack key={`${attachment.type}:${index}`} spacing={1}><Typography variant="subtitle2">{attachment.type}</Typography><Json_Viewer value={attachment_value(attachment.type,attachment.content)}/></Stack>)}</Stack>;
}
+3 -2
View File
@@ -31,10 +31,11 @@ export interface Gallery_Render_Node {node_id: number; id?: string | number; nam
export interface Gallery_Render_Edge {from: number | string; to: number | string;}
export interface Gallery_Renderable_Cache {owner_id: number; name: string; prepare_cache: string; paint_cache: string;}
export interface Gallery_Render_Plan {version: number; nodes: Gallery_Render_Node[]; edges: Gallery_Render_Edge[]; renderables: Gallery_Renderable_Cache[];}
export interface Gallery_Node_Execution {node_id: number; worker_id: number; start_offset_ns: number; cpu_end_offset_ns: number; external_start_offset_ns: number; external_end_offset_ns: number; end_offset_ns: number; duration_ns: number; cpu_duration_ns: number; external_duration_ns: number; status: "pending"|"ready"|"running"|"waiting_external"|"complete"|"failed"; metrics?: Record<string, Json_Primitive>;}
export interface Gallery_Node_Diagnostic_Attachment {type: string; content: string;}
export interface Gallery_Node_Execution {node_id: number; worker_id: number; start_offset_ns: number; cpu_end_offset_ns: number; external_start_offset_ns: number; external_end_offset_ns: number; end_offset_ns: number; duration_ns: number; cpu_duration_ns: number; external_duration_ns: number; status: "pending"|"ready"|"running"|"waiting_external"|"complete"|"failed"; metrics?: Record<string, Json_Primitive>; attachments: Gallery_Node_Diagnostic_Attachment[];}
export interface Gallery_Node_Analysis {node_id: number; duration_ns: number; cpu_duration_ns: number; external_duration_ns: number; scheduler_wait_ns: number; critical_path_contribution: number; on_critical_path: boolean;}
export interface Gallery_Captured_Frame {frame_id: number; render_plan_version: number; render_duration_ns: number; node_executions: Gallery_Node_Execution[]; analysis?: {total_work_duration_ns?: number; total_external_duration_ns?: number; nodes: Gallery_Node_Analysis[]};}
export interface Gallery_Node_Statistics {node_id: number; moving_average_ns: number; p95_ns: number; p99_ns: number; critical_path_frequency: number;}
export interface Gallery_Node_Statistics {node_id: number; moving_average_ns: number; p95_ns: number; p99_ns: number; average_cpu_ns: number; average_external_ns: number; p95_cpu_ns: number; p95_external_ns: number; critical_path_frequency: number;}
export interface Gallery_Plan_Statistics {render_plan_version: number; frame_count: number; render_average_ns: number; render_p95_ns: number; average_parallelism: number; peak_parallelism: number; scheduler_wait_average_ns: number; nodes: Gallery_Node_Statistics[];}
export interface Gallery_Capture_Session {session_id: number; active: boolean; requested_count: number; captured_count: number; frames: Gallery_Captured_Frame[]; node_statistics: Gallery_Node_Statistics[]; plan_statistics: Gallery_Plan_Statistics[]; summary?: Record<string, Json_Value>;}
export interface Gallery_Performance_Capture {controller: {enabled?: boolean; session_id?: number}; sessions: Gallery_Capture_Session[]; plans: Gallery_Render_Plan[];}
+1 -1
View File
@@ -1,2 +1,2 @@
import {describe,expect,it} from "vitest";import {build_dag_model} from "../../src/dag/dag_model";
describe("DAG view model",()=>{it("uses node_id for current plan and capture overlays",()=>{const plan={version:2,nodes:[{node_id:7,name:"paint",owner:"plot",kind:"paint"}],edges:[],renderables:[]};const frame={frame_id:1,render_plan_version:2,render_duration_ns:10,node_executions:[{node_id:7,worker_id:3,start_offset_ns:0,cpu_end_offset_ns:10,external_start_offset_ns:0,external_end_offset_ns:0,end_offset_ns:10,duration_ns:10,cpu_duration_ns:10,external_duration_ns:0,status:"complete" as const}],analysis:{total_work_duration_ns:10,total_external_duration_ns:0,nodes:[{node_id:7,duration_ns:10,cpu_duration_ns:10,external_duration_ns:0,scheduler_wait_ns:1,critical_path_contribution:1,on_critical_path:true}]}};const model=build_dag_model(plan,frame,[],7);expect(model.nodes[0].id).toBe("7");expect(model.nodes[0].data).toMatchObject({duration_ns:10,worker_id:3,critical:true,selected:true});});});
describe("DAG view model",()=>{it("uses node_id for current plan and capture overlays",()=>{const plan={version:2,nodes:[{node_id:7,name:"paint",owner:"plot",kind:"paint"}],edges:[],renderables:[]};const frame={frame_id:1,render_plan_version:2,render_duration_ns:10,node_executions:[{node_id:7,worker_id:3,start_offset_ns:0,cpu_end_offset_ns:10,external_start_offset_ns:0,external_end_offset_ns:0,end_offset_ns:10,duration_ns:10,cpu_duration_ns:10,external_duration_ns:0,status:"complete" as const,attachments:[]}],analysis:{total_work_duration_ns:10,total_external_duration_ns:0,nodes:[{node_id:7,duration_ns:10,cpu_duration_ns:10,external_duration_ns:0,scheduler_wait_ns:1,critical_path_contribution:1,on_critical_path:true}]}};const model=build_dag_model(plan,frame,[],7);expect(model.nodes[0].id).toBe("7");expect(model.nodes[0].data).toMatchObject({duration_ns:10,worker_id:3,critical:true,selected:true});});});