Expose process ID

This commit is contained in:
Ingo Oppermann
2025-07-07 12:09:20 +02:00
parent 643dd8386c
commit 15a0f4dbc5
8 changed files with 35 additions and 37 deletions

View File

@@ -1608,12 +1608,6 @@ const docTemplate = `{
"summary": "List of processes in the cluster", "summary": "List of processes in the cluster",
"operationId": "cluster-3-get-all-processes", "operationId": "cluster-3-get-all-processes",
"parameters": [ "parameters": [
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{ {
"type": "string", "type": "string",
"description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.", "description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.",
@@ -3456,12 +3450,6 @@ const docTemplate = `{
"summary": "List all known processes", "summary": "List all known processes",
"operationId": "process-3-get-all", "operationId": "process-3-get-all",
"parameters": [ "parameters": [
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{ {
"type": "string", "type": "string",
"description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.", "description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.",
@@ -7483,6 +7471,9 @@ const docTemplate = `{
"type": "integer", "type": "integer",
"format": "int64" "format": "int64"
}, },
"domain": {
"type": "string"
},
"exit_state": { "exit_state": {
"type": "string" "type": "string"
}, },
@@ -7528,6 +7519,10 @@ const docTemplate = `{
"order": { "order": {
"type": "string" "type": "string"
}, },
"pid": {
"type": "integer",
"format": "int32"
},
"progress": { "progress": {
"$ref": "#/definitions/api.Progress" "$ref": "#/definitions/api.Progress"
}, },

View File

@@ -1601,12 +1601,6 @@
"summary": "List of processes in the cluster", "summary": "List of processes in the cluster",
"operationId": "cluster-3-get-all-processes", "operationId": "cluster-3-get-all-processes",
"parameters": [ "parameters": [
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{ {
"type": "string", "type": "string",
"description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.", "description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.",
@@ -3449,12 +3443,6 @@
"summary": "List all known processes", "summary": "List all known processes",
"operationId": "process-3-get-all", "operationId": "process-3-get-all",
"parameters": [ "parameters": [
{
"type": "string",
"description": "Domain to act on",
"name": "domain",
"in": "query"
},
{ {
"type": "string", "type": "string",
"description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.", "description": "Comma separated list of fields (config, state, report, metadata) that will be part of the output. If empty, all fields will be part of the output.",
@@ -7476,6 +7464,9 @@
"type": "integer", "type": "integer",
"format": "int64" "format": "int64"
}, },
"domain": {
"type": "string"
},
"exit_state": { "exit_state": {
"type": "string" "type": "string"
}, },
@@ -7521,6 +7512,10 @@
"order": { "order": {
"type": "string" "type": "string"
}, },
"pid": {
"type": "integer",
"format": "int32"
},
"progress": { "progress": {
"$ref": "#/definitions/api.Progress" "$ref": "#/definitions/api.Progress"
}, },

View File

@@ -1522,6 +1522,8 @@ definitions:
created_at: created_at:
format: int64 format: int64
type: integer type: integer
domain:
type: string
exit_state: exit_state:
type: string type: string
exited_at: exited_at:
@@ -1553,6 +1555,9 @@ definitions:
type: integer type: integer
order: order:
type: string type: string
pid:
format: int32
type: integer
progress: progress:
$ref: '#/definitions/api.Progress' $ref: '#/definitions/api.Progress'
reconnect_seconds: reconnect_seconds:
@@ -3895,10 +3900,6 @@ paths:
description: List of processes in the cluster description: List of processes in the cluster
operationId: cluster-3-get-all-processes operationId: cluster-3-get-all-processes
parameters: parameters:
- description: Domain to act on
in: query
name: domain
type: string
- description: Comma separated list of fields (config, state, report, metadata) - description: Comma separated list of fields (config, state, report, metadata)
that will be part of the output. If empty, all fields will be part of the that will be part of the output. If empty, all fields will be part of the
output. output.
@@ -5109,10 +5110,6 @@ paths:
listed processes. listed processes.
operationId: process-3-get-all operationId: process-3-get-all
parameters: parameters:
- description: Domain to act on
in: query
name: domain
type: string
- description: Comma separated list of fields (config, state, report, metadata) - description: Comma separated list of fields (config, state, report, metadata)
that will be part of the output. If empty, all fields will be part of the that will be part of the output. If empty, all fields will be part of the
output. output.

View File

@@ -366,6 +366,7 @@ type ProcessState struct {
LimitMode string `json:"limit_mode"` LimitMode string `json:"limit_mode"`
Resources ProcessUsage `json:"resources"` Resources ProcessUsage `json:"resources"`
Command []string `json:"command"` Command []string `json:"command"`
PID int32 `json:"pid" format:"int32"`
} }
// Unmarshal converts a core ffmpeg process state to a state in API representation // Unmarshal converts a core ffmpeg process state to a state in API representation
@@ -385,6 +386,7 @@ func (s *ProcessState) Unmarshal(state *app.State) {
s.LimitMode = state.LimitMode s.LimitMode = state.LimitMode
s.Resources.Unmarshal(&state.Resources) s.Resources.Unmarshal(&state.Resources)
s.Command = state.Command s.Command = state.Command
s.PID = state.PID
s.Progress.Unmarshal(&state.Progress) s.Progress.Unmarshal(&state.Progress)
} }

View File

@@ -13,6 +13,7 @@ import (
"os/exec" "os/exec"
"runtime" "runtime"
"sync" "sync"
"sync/atomic"
"syscall" "syscall"
"time" "time"
"unicode/utf8" "unicode/utf8"
@@ -204,7 +205,7 @@ type process struct {
args []string args []string
cmdArgs []string cmdArgs []string
cmd *exec.Cmd cmd *exec.Cmd
pid int32 pid atomic.Int32
stdout io.ReadCloser stdout io.ReadCloser
state struct { state struct {
state stateType state stateType
@@ -265,6 +266,8 @@ func New(config Config) (Process, error) {
resources: config.Resources, resources: config.Resources,
} }
p.pid.Store(-1)
if p.resources == nil { if p.resources == nil {
return nil, fmt.Errorf("resources are required") return nil, fmt.Errorf("resources are required")
} }
@@ -516,7 +519,7 @@ func (p *process) Status() Status {
order := p.getOrder() order := p.getOrder()
s := Status{ s := Status{
PID: p.pid, PID: p.pid.Load(),
State: state.String(), State: state.String(),
States: states, States: states,
Order: order, Order: order,
@@ -707,6 +710,8 @@ func (p *process) start() error {
return err return err
} }
p.pid.Store(int32(p.cmd.Process.Pid))
// Start the stop timeout if enabled // Start the stop timeout if enabled
if p.timeout > time.Duration(0) { if p.timeout > time.Duration(0) {
p.stopTimerLock.Lock() p.stopTimerLock.Lock()
@@ -724,9 +729,7 @@ func (p *process) start() error {
p.stopTimerLock.Unlock() p.stopTimerLock.Unlock()
} }
p.pid = int32(p.cmd.Process.Pid) if proc, err := p.resources.Process(p.pid.Load()); err == nil {
if proc, err := p.resources.Process(p.pid); err == nil {
p.limits.Start(proc) p.limits.Start(proc)
} }
@@ -1057,6 +1060,7 @@ func (p *process) waiter() {
} }
p.setState(state) p.setState(state)
p.pid.Store(-1)
p.logger.Info().Log("Stopped") p.logger.Info().Log("Stopped")
p.debuglogger.WithField("log", p.parser.Log()).Debug().Log("Stopped") p.debuglogger.WithField("log", p.parser.Log()).Debug().Log("Stopped")

View File

@@ -312,6 +312,7 @@ type State struct {
LimitMode string // How the process is limited (hard or soft) LimitMode string // How the process is limited (hard or soft)
Resources ProcessUsage // Current resource usage, include CPU, memory and GPU consumption Resources ProcessUsage // Current resource usage, include CPU, memory and GPU consumption
Command []string // ffmpeg command line parameters Command []string // ffmpeg command line parameters
PID int32 // System process ID
} }
type ProcessUsageCPU struct { type ProcessUsageCPU struct {

View File

@@ -112,6 +112,7 @@ func (r *Report) MarshalParser() (parse.Report, []parse.ReportHistoryEntry) {
type ReportHistorySearchResult struct { type ReportHistorySearchResult struct {
ProcessID string ProcessID string
Domain string
Reference string Reference string
ExitState string ExitState string
ExitedAt time.Time ExitedAt time.Time

View File

@@ -243,6 +243,8 @@ func (t *task) State() (*app.State, error) {
state.Progress.Input = assignConfigID(state.Progress.Input, t.config.Input) state.Progress.Input = assignConfigID(state.Progress.Input, t.config.Input)
state.Progress.Output = assignConfigID(state.Progress.Output, t.config.Output) state.Progress.Output = assignConfigID(state.Progress.Output, t.config.Output)
state.PID = status.PID
return state, nil return state, nil
} }
@@ -312,6 +314,7 @@ func (t *task) SearchReportHistory(state string, from, to *time.Time) []app.Repo
for _, f := range presult { for _, f := range presult {
result = append(result, app.ReportHistorySearchResult{ result = append(result, app.ReportHistorySearchResult{
ProcessID: t.id, ProcessID: t.id,
Domain: t.domain,
Reference: t.reference, Reference: t.reference,
ExitState: f.ExitState, ExitState: f.ExitState,
CreatedAt: f.CreatedAt, CreatedAt: f.CreatedAt,