Add Job and Action tracking for runner with GRPC notifications#1714
Add Job and Action tracking for runner with GRPC notifications#1714
Conversation
Co-authored-by: SebiWrn <67778694+SebiWrn@users.noreply.github.com>
…m models Co-authored-by: SebiWrn <67778694+SebiWrn@users.noreply.github.com>
dao/migrations/202412050.go
Outdated
dao/migrator.go
Outdated
| migrations.Migrate202212010(), | ||
| migrations.Migrate202212020(), | ||
| migrations.Migrate202301006(), | ||
| migrations.Migrate202412050(), |
| type Job struct { | ||
| gorm.Model | ||
| // JobID is the unique identifier for the job (UUID from runner) | ||
| JobID string `gorm:"column:job_id;uniqueIndex;not null"` |
There was a problem hiding this comment.
Changed in c1c0a2a - now using gorm.Model which provides an auto-incrementing ID as primary key, with JobID as a unique index.
There was a problem hiding this comment.
I think it was fine as is
There was a problem hiding this comment.
Keeping it as is - the current implementation with gorm.Model providing the auto-incrementing ID and JobID as a unique index works correctly.
model/job.go
Outdated
| // CompletedAt is the timestamp when the job completed (or failed) | ||
| CompletedAt *time.Time `gorm:"column:completed_at"` | ||
| // ErrorMessage is the error message if the job failed | ||
| ErrorMessage string `gorm:"column:error_message;type:text"` |
There was a problem hiding this comment.
We should have another table for actions that reference to their respective job and save these for each action.
There was a problem hiding this comment.
Renamed to LastError and added separate Action model with its own actions table in c1c0a2a. Each action now references its job via JobID and stores its type as a string, status, timestamps, and LastError.
runner/runner.go
Outdated
| func (r *Runner) getActionType(funcName string) protobuf.ActionType { | ||
| switch { | ||
| case strings.HasSuffix(funcName, "Stream"): | ||
| return protobuf.ActionType_ACTION_TYPE_STREAM | ||
| case strings.HasSuffix(funcName, "StreamEnd"): | ||
| return protobuf.ActionType_ACTION_TYPE_STREAM_END | ||
| case strings.HasSuffix(funcName, "MkVOD"): | ||
| return protobuf.ActionType_ACTION_TYPE_MK_VOD | ||
| case strings.HasSuffix(funcName, "CheckVoD"): | ||
| return protobuf.ActionType_ACTION_TYPE_CHECK_VOD | ||
| case strings.HasSuffix(funcName, "MkThumb"): | ||
| return protobuf.ActionType_ACTION_TYPE_MK_THUMB | ||
| default: | ||
| return protobuf.ActionType_ACTION_TYPE_UNSPECIFIED | ||
| } |
There was a problem hiding this comment.
Let's not have a new type for this. Just use the string here and in the database.
There was a problem hiding this comment.
Changed to use string for action type in c1c0a2a. The getActionTypeString function now returns strings like "stream", "mk_vod" etc., and the protobuf uses string action_type instead of an enum.
…LastError, add Action model Co-authored-by: joschahenningsen <44805696+joschahenningsen@users.noreply.github.com>
pkg/runner_manager/manager.go
Outdated
| // protoJobStatusToModel converts protobuf JobStatus to model JobStatus | ||
| func protoJobStatusToModel(status protobuf.JobStatus) model.JobStatus { | ||
| switch status { | ||
| case protobuf.JobStatus_JOB_STATUS_CREATED: | ||
| return model.JobStatusCreated | ||
| case protobuf.JobStatus_JOB_STATUS_RUNNING: | ||
| return model.JobStatusRunning | ||
| case protobuf.JobStatus_JOB_STATUS_COMPLETED: | ||
| return model.JobStatusCompleted | ||
| case protobuf.JobStatus_JOB_STATUS_FAILED: | ||
| return model.JobStatusFailed | ||
| case protobuf.JobStatus_JOB_STATUS_CANCELLED: | ||
| return model.JobStatusCancelled | ||
| default: | ||
| return model.JobStatusCreated | ||
| } | ||
| } | ||
|
|
||
| // protoActionStatusToModel converts protobuf ActionStatus to model ActionStatus | ||
| func protoActionStatusToModel(status protobuf.ActionStatus) model.ActionStatus { | ||
| switch status { | ||
| case protobuf.ActionStatus_ACTION_STATUS_RUNNING: | ||
| return model.ActionStatusRunning | ||
| case protobuf.ActionStatus_ACTION_STATUS_COMPLETED: | ||
| return model.ActionStatusCompleted | ||
| case protobuf.ActionStatus_ACTION_STATUS_FAILED: | ||
| return model.ActionStatusFailed | ||
| default: | ||
| return model.ActionStatusRunning | ||
| } | ||
| } |
There was a problem hiding this comment.
Unified JobStatus and ActionStatus into a single WorkState type in 7deec80. Both Job and Action models now use WorkState, and there's a single protoWorkStateToModel converter function.
|
@copilot I removed the lastError from the job. That is more of an action thing. Please clean up the notifications and notify about action updates where required. |
Co-authored-by: joschahenningsen <44805696+joschahenningsen@users.noreply.github.com>
Co-authored-by: joschahenningsen <44805696+joschahenningsen@users.noreply.github.com>
Removed |
Motivation and Context
Track runner job state in the database so the UI can display current runner activity. Previously, job execution was ephemeral with no persistence layer for monitoring.
Description
Adds database-backed job and action tracking with GRPC notifications from runner to gocast main instance.
New Models & DAO:
model/job.go- Job entity with unifiedWorkStatetype (created/running/completed/failed/cancelled) and timestampsmodel/action.go- Action entity with its own table, referencing jobs via foreign key, storing action type as string,WorkStatestatus, timestamps, andLastErrorfor error trackingdao/job.go- CRUD operations for both jobs and actions, queries by job ID, stream ID, runner hostname, active statusProtobuf Extensions:
WorkStateenum used by both jobs and actionsJobUpdateNotificationmessage for job state changes (status only, no error field)ActionUpdateNotificationmessage for individual action state changes (uses string for action_type, includeslast_error)Runner Changes:
RunAction()sends separate job and action status notificationsSTREAM_VERSION_UNSPECIFIEDManager Changes:
handleJobUpdate()persists job state on notification receipthandleActionUpdate()persists action state, creating new action records or updating existing onesprotoWorkStateToModel()converter for the unified WorkState typeModel Relations:
Runner.Jobs- foreign key relationship to active jobsStream.Jobs- foreign key relationship to associated jobsJob.Actions- foreign key relationship to actions within a jobRunnerDao.GetAllWithJobs()- preloads active jobs for UI queriesSteps for Testing
Prerequisites:
jobstable with statuscreatedactionstable for each action (stream, mk_vod, etc.)created→running→completedrunning→completedfor each actioncancelledfailedwithlast_errorpopulated, and job status becomesfailedScreenshots
N/A - Backend changes only. UI integration pending separate PR.
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.