feat: finish met nonlinear ui workflow
This commit is contained in:
@@ -74,9 +74,16 @@ function fmtClock(value: Date): string {
|
||||
|
||||
function fmtDuration(seconds: number): string {
|
||||
if (!Number.isFinite(seconds)) return "--";
|
||||
if (seconds < 60) return `${seconds}s`;
|
||||
if (seconds < 3600) return `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
|
||||
return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`;
|
||||
const safeSeconds = Math.max(0, seconds);
|
||||
if (safeSeconds === 0) return "0s";
|
||||
if (safeSeconds < 0.01) return "<0.01s";
|
||||
if (safeSeconds < 0.1) return `${safeSeconds.toFixed(2)}s`;
|
||||
if (safeSeconds < 1) return `${safeSeconds.toFixed(1)}s`;
|
||||
if (safeSeconds < 10 && !Number.isInteger(safeSeconds)) return `${safeSeconds.toFixed(1)}s`;
|
||||
if (safeSeconds < 60) return `${Math.round(safeSeconds)}s`;
|
||||
const wholeSeconds = Math.floor(safeSeconds);
|
||||
if (wholeSeconds < 3600) return `${Math.floor(wholeSeconds / 60)}m ${wholeSeconds % 60}s`;
|
||||
return `${Math.floor(wholeSeconds / 3600)}h ${Math.floor((wholeSeconds % 3600) / 60)}m`;
|
||||
}
|
||||
|
||||
function fmtBytes(value: any): string {
|
||||
@@ -125,7 +132,7 @@ function taskElapsedSeconds(task: any): number | null {
|
||||
const terminal = ["succeeded", "failed"].includes(String(task?.status || "").toLowerCase());
|
||||
const ended = terminal ? timeMs(task?.updatedAt) : Date.now();
|
||||
if (ended === null) return null;
|
||||
return Math.max(0, Math.floor((ended - started) / 1000));
|
||||
return Math.max(0, (ended - started) / 1000);
|
||||
}
|
||||
|
||||
function taskFailureReason(task: any): string {
|
||||
|
||||
@@ -27,6 +27,7 @@ function fmtPercent(value: any): string {
|
||||
}
|
||||
|
||||
function fmtDuration(seconds: any): string {
|
||||
if (seconds === null || seconds === undefined || seconds === "") return "--";
|
||||
const value = Number(seconds);
|
||||
if (!Number.isFinite(value)) return "--";
|
||||
if (value < 60) return `${Math.max(0, Math.round(value))}s`;
|
||||
@@ -129,6 +130,21 @@ function jobDuration(job: any): string {
|
||||
return job.startedAt && job.finishedAt ? fmtDuration((Date.parse(job.finishedAt) - Date.parse(job.startedAt)) / 1000) : "--";
|
||||
}
|
||||
|
||||
function jobEtaSeconds(job: any): number | null {
|
||||
const progress = job.progress || {};
|
||||
if (progress.etaSeconds !== null && progress.etaSeconds !== undefined && progress.etaSeconds !== "") {
|
||||
const reported = Number(progress.etaSeconds);
|
||||
if (Number.isFinite(reported)) return Math.max(0, reported);
|
||||
}
|
||||
const currentEpoch = Number(progress.currentEpoch);
|
||||
const epochTarget = Number(progress.epochTarget ?? job.epochTarget);
|
||||
const startedAt = Date.parse(job.startedAt || "");
|
||||
if (!Number.isFinite(currentEpoch) || currentEpoch <= 0 || !Number.isFinite(epochTarget) || epochTarget <= currentEpoch || !Number.isFinite(startedAt)) return null;
|
||||
const elapsedSeconds = Math.max(0, (Date.now() - startedAt) / 1000);
|
||||
if (elapsedSeconds <= 0) return null;
|
||||
return Math.max(0, (elapsedSeconds / currentEpoch) * (epochTarget - currentEpoch));
|
||||
}
|
||||
|
||||
function statusLabel(status: string): string {
|
||||
if (status === "staged") return "待启动";
|
||||
if (status === "queued") return "排队中";
|
||||
@@ -291,7 +307,7 @@ export function MetNonlinearPage({ microservices, onRaw, apiBaseUrl = "/api" }:
|
||||
h("span", null, `${progress.currentEpoch ?? "--"} / ${progress.epochTarget ?? job.epochTarget ?? "--"}`),
|
||||
h("div", { className: "met-progress" }, h("span", { style: { width: fmtPercent(progress.progressPercent) } })),
|
||||
),
|
||||
h("td", null, job.status === "succeeded" || job.status === "failed" || job.status === "canceled" ? jobDuration(job) : fmtDuration(progress.etaSeconds)),
|
||||
h("td", null, job.status === "succeeded" || job.status === "failed" || job.status === "canceled" ? jobDuration(job) : (job.status === "running" ? `ETA ${fmtDuration(jobEtaSeconds(job))}` : "--")),
|
||||
h("td", null, job.gpuName || "--"),
|
||||
h("td", null, job.exitCode ?? "--"),
|
||||
h("td", null, fmtDate(job.updatedAt)),
|
||||
|
||||
Reference in New Issue
Block a user