domain/record, runner: add DurationMS to RunRecord (T2.1, T2.2)

Add DurationMS int64 field to RunRecord and measure wall-clock
start→finish in RunJob; StartOnly jobs record 0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mixeme
2026-06-24 08:09:59 +03:00
parent 183ea1b125
commit 42d73b9eb0
2 changed files with 22 additions and 16 deletions
+9 -8
View File
@@ -4,12 +4,13 @@ package domain
// output is also written to a log file; the in-memory Output copy exists so the
// latest run can be displayed without reopening the log on every repaint.
type RunRecord struct {
Time string `yaml:"time"`
JobID int `yaml:"job_id"`
JobName string `yaml:"job_name"`
Trigger string `yaml:"trigger,omitempty"`
State string `yaml:"state"`
Detail string `yaml:"detail"`
LogFile string `yaml:"log_file,omitempty"`
Output string `yaml:"output,omitempty"`
Time string `yaml:"time"`
JobID int `yaml:"job_id"`
JobName string `yaml:"job_name"`
Trigger string `yaml:"trigger,omitempty"`
State string `yaml:"state"`
Detail string `yaml:"detail"`
LogFile string `yaml:"log_file,omitempty"`
Output string `yaml:"output,omitempty"`
DurationMS int64 `yaml:"duration_ms,omitempty"`
}
+13 -8
View File
@@ -27,9 +27,12 @@ func RunJob(ctx context.Context, job *domain.Job, trigger string, logsDir string
var output string
var state string
var detail string
var durationMS int64
if job.StartOnly {
invocation := jobInvocation(context.Background(), *job)
state, detail, output = startJobOnly(invocation, *job, started)
// StartOnly jobs don't wait for process exit, so no meaningful duration.
durationMS = 0
} else {
var stdoutBuf strings.Builder
var stderrBuf strings.Builder
@@ -44,6 +47,7 @@ func RunJob(ctx context.Context, job *domain.Job, trigger string, logsDir string
err := command.Run()
duration := time.Since(started).Round(time.Millisecond)
durationMS = duration.Milliseconds()
output = formatOutput(stdoutBuf.String(), stderrBuf.String())
state, detail = runStateDetail(err, runCtx.Err(), duration)
}
@@ -56,14 +60,15 @@ func RunJob(ctx context.Context, job *domain.Job, trigger string, logsDir string
// lets the caller fold that record into the job's JobRuntime. Run state no
// longer lives on Job, so there is nothing on the job to mutate here.
return domain.RunRecord{
Time: timestamp,
JobID: job.ID,
JobName: job.Name,
Trigger: trigger,
State: state,
Detail: detail,
LogFile: logFile,
Output: output,
Time: timestamp,
JobID: job.ID,
JobName: job.Name,
Trigger: trigger,
State: state,
Detail: detail,
LogFile: logFile,
Output: output,
DurationMS: durationMS,
}
}