From ec540e47a7095541beddf9ee735cfb12b2c565c6 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Thu, 30 May 2024 21:17:26 +0800 Subject: [PATCH 01/29] Manager: draft task and job status transition; regenerated openapi with pause-requested status; start frontend work --- addon/flamenco/manager/docs/JobStatus.md | 2 +- addon/flamenco/manager/model/job_status.py | 9 +- go.mod | 1 + go.sum | 2 + .../task_state_machine/task_state_machine.go | 73 ++- pkg/api/flamenco-openapi.yaml | 1 + pkg/api/openapi_spec.gen.go | 454 +++++++++--------- pkg/api/openapi_types.gen.go | 2 + web/app/src/components/jobs/JobActionsBar.vue | 3 + web/app/src/manager-api/model/JobStatus.js | 7 + web/app/src/stores/tasks.js | 3 + 11 files changed, 323 insertions(+), 234 deletions(-) diff --git a/addon/flamenco/manager/docs/JobStatus.md b/addon/flamenco/manager/docs/JobStatus.md index c7e1da07..2c1d142b 100644 --- a/addon/flamenco/manager/docs/JobStatus.md +++ b/addon/flamenco/manager/docs/JobStatus.md @@ -4,7 +4,7 @@ ## Properties Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**value** | **str** | | must be one of ["active", "canceled", "completed", "failed", "paused", "queued", "cancel-requested", "requeueing", "under-construction", ] +**value** | **str** | | must be one of ["active", "canceled", "completed", "failed", "paused", "pause-requested", "queued", "cancel-requested", "requeueing", "under-construction", ] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/addon/flamenco/manager/model/job_status.py b/addon/flamenco/manager/model/job_status.py index f1e535fe..bcde8127 100644 --- a/addon/flamenco/manager/model/job_status.py +++ b/addon/flamenco/manager/model/job_status.py @@ -57,6 +57,7 @@ class JobStatus(ModelSimple): 'COMPLETED': "completed", 'FAILED': "failed", 'PAUSED': "paused", + 'PAUSE-REQUESTED': "pause-requested", 'QUEUED': "queued", 'CANCEL-REQUESTED': "cancel-requested", 'REQUEUEING': "requeueing", @@ -112,10 +113,10 @@ class JobStatus(ModelSimple): Note that value can be passed either in args or in kwargs, but not in both. Args: - args[0] (str):, must be one of ["active", "canceled", "completed", "failed", "paused", "queued", "cancel-requested", "requeueing", "under-construction", ] # noqa: E501 + args[0] (str):, must be one of ["active", "canceled", "completed", "failed", "paused", "pause-requested", "queued", "cancel-requested", "requeueing", "under-construction", ] # noqa: E501 Keyword Args: - value (str):, must be one of ["active", "canceled", "completed", "failed", "paused", "queued", "cancel-requested", "requeueing", "under-construction", ] # noqa: E501 + value (str):, must be one of ["active", "canceled", "completed", "failed", "paused", "pause-requested", "queued", "cancel-requested", "requeueing", "under-construction", ] # noqa: E501 _check_type (bool): if True, values for parameters in openapi_types will be type checked and a TypeError will be raised if the wrong type is input. @@ -202,10 +203,10 @@ class JobStatus(ModelSimple): Note that value can be passed either in args or in kwargs, but not in both. Args: - args[0] (str):, must be one of ["active", "canceled", "completed", "failed", "paused", "queued", "cancel-requested", "requeueing", "under-construction", ] # noqa: E501 + args[0] (str):, must be one of ["active", "canceled", "completed", "failed", "paused", "pause-requested", "queued", "cancel-requested", "requeueing", "under-construction", ] # noqa: E501 Keyword Args: - value (str):, must be one of ["active", "canceled", "completed", "failed", "paused", "queued", "cancel-requested", "requeueing", "under-construction", ] # noqa: E501 + value (str):, must be one of ["active", "canceled", "completed", "failed", "paused", "pause-requested", "queued", "cancel-requested", "requeueing", "under-construction", ] # noqa: E501 _check_type (bool): if True, values for parameters in openapi_types will be type checked and a TypeError will be raised if the wrong type is input. diff --git a/go.mod b/go.mod index b621f8cc..f6335774 100644 --- a/go.mod +++ b/go.mod @@ -59,6 +59,7 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.1 // indirect + golang.org/toolchain v0.0.1-go1.9rc2.windows-amd64 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/go.sum b/go.sum index 17976c6d..e7ce247b 100644 --- a/go.sum +++ b/go.sum @@ -190,6 +190,8 @@ github.com/ziflex/lecho/v3 v3.1.0 h1:65bSzSc0yw7EEhi44lMnkOI877ZzbE7tGDWfYCQXZwI github.com/ziflex/lecho/v3 v3.1.0/go.mod h1:dwQ6xCAKmSBHhwZ6XmiAiDptD7iklVkW7xQYGUncX0Q= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +golang.org/toolchain v0.0.1-go1.9rc2.windows-amd64 h1:1f9RozPx9d/MkNM8NMgJDmTj6WNwWPixB1qIWVz5ORc= +golang.org/toolchain v0.0.1-go1.9rc2.windows-amd64/go.mod h1:8wlg68NqwW7eMnI1aABk/C2pDYXj8mrMY4TyRfiLeS0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 2bdb673e..085837aa 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -119,8 +119,7 @@ func (sm *StateMachine) updateJobAfterTaskStatusChange( return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusCompleted, api.JobStatusRequeueing, "task was queued") case api.TaskStatusPaused: - // Pausing a task has no impact on the job. - return nil + return sm.updateJobOnTaskStatusPaused(ctx, logger, job) case api.TaskStatusCanceled: return sm.updateJobOnTaskStatusCanceled(ctx, logger, job) @@ -183,6 +182,38 @@ func (sm *StateMachine) updateJobOnTaskStatusCanceled(ctx context.Context, logge return nil } +// updateJobOnTaskStatusPaused conditionally escalates the pausing of a task to pause the job. +func (sm *StateMachine) updateJobOnTaskStatusPaused(ctx context.Context, logger zerolog.Logger, job *persistence.Job) error { + // If no more tasks can run, pause the job. + numRunnable, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, + api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed) + if err != nil { + return err + } + if numRunnable == 0 { + logger.Info().Msg("paused task was last runnable task of job, pausing job") + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "paused task was last runnable task of job, pausing job") + } + + if job.Status == api.JobStatusPauseRequested { + // if the job is in pause-requested state, and all other tasks are paused, + // then the job can be paused. + numPaused, numTotal, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusPaused) + if err != nil { + return err + } + if numPaused == numTotal { + logger.Info().Msg("all tasks of job are paused, job is paused") + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks paused") + } + } else { + // if the job is not in pause-requested state, then some error occurred and the job should be failed. + logger.Info().Msg("task cannot be changed to paused when job is not in pause-requested state") + } + + return nil +} + // updateJobOnTaskStatusFailed conditionally escalates the failure of a task to fail the entire job. func (sm *StateMachine) updateJobOnTaskStatusFailed(ctx context.Context, logger zerolog.Logger, job *persistence.Job) error { // Count the number of failed tasks. If it is over the threshold, fail the job. @@ -385,6 +416,13 @@ func (sm *StateMachine) updateTasksAfterJobStatusChange( massTaskUpdate: true, }, err + case api.JobStatusPauseRequested: + jobStatus, err := sm.pauseTasks(ctx, logger, job) + return tasksUpdateResult{ + followingJobStatus: jobStatus, + massTaskUpdate: true, + }, err + case api.JobStatusRequeueing: jobStatus, err := sm.requeueTasks(ctx, logger, job, oldJobStatus) return tasksUpdateResult{ @@ -438,6 +476,37 @@ func (sm *StateMachine) cancelTasks( return "", nil } +func (sm *StateMachine) pauseTasks( + ctx context.Context, logger zerolog.Logger, job *persistence.Job, +) (api.JobStatus, error) { + logger.Info().Msg("pausing tasks of job") + + // Any task that might run in the future should get paused. + // Active jobs should remain active until finished + taskStatusesToPause := []api.TaskStatus{ + api.TaskStatusActive, + api.TaskStatusQueued, + api.TaskStatusCanceled, + } + err := sm.persist.UpdateJobsTaskStatusesConditional( + ctx, job, taskStatusesToPause, api.TaskStatusPaused, + fmt.Sprintf("Manager paused this task because the job got status %q.", job.Status), + ) + if err != nil { + return "", fmt.Errorf("pausing tasks of job %s: %w", job.UUID, err) + } + + // If pause was requested, it has now happened, so the job can transition. + if job.Status == api.JobStatusPauseRequested { + logger.Info().Msg("all tasks of job paused, job can go to 'paused' status") + return api.JobStatusPaused, nil + } + + // This could mean pause was triggered by failure of the job, in which case the + // job is already in the correct status. + return "", nil +} + // requeueTasks re-queues all tasks of the job. // // This function assumes that the current job status is "requeueing". diff --git a/pkg/api/flamenco-openapi.yaml b/pkg/api/flamenco-openapi.yaml index 8f19c6bd..491dbd25 100644 --- a/pkg/api/flamenco-openapi.yaml +++ b/pkg/api/flamenco-openapi.yaml @@ -1680,6 +1680,7 @@ components: - completed - failed - paused + - pause-requested - queued - cancel-requested - requeueing diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index 671be5ea..2de53300 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -19,233 +19,233 @@ import ( var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/api/openapi_types.gen.go b/pkg/api/openapi_types.gen.go index 80b49695..251670e2 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -84,6 +84,8 @@ const ( JobStatusFailed JobStatus = "failed" + JobStatusPauseRequested JobStatus = "pause-requested" + JobStatusPaused JobStatus = "paused" JobStatusQueued JobStatus = "queued" diff --git a/web/app/src/components/jobs/JobActionsBar.vue b/web/app/src/components/jobs/JobActionsBar.vue index 615ffae7..eeb24eb9 100644 --- a/web/app/src/components/jobs/JobActionsBar.vue +++ b/web/app/src/components/jobs/JobActionsBar.vue @@ -8,6 +8,9 @@ + diff --git a/web/app/src/manager-api/model/JobStatus.js b/web/app/src/manager-api/model/JobStatus.js index 169d161e..546532d6 100644 --- a/web/app/src/manager-api/model/JobStatus.js +++ b/web/app/src/manager-api/model/JobStatus.js @@ -54,6 +54,13 @@ export default class JobStatus { "paused" = "paused"; + /** + * value: "pause-requested" + * @const + */ + "pause-requested" = "pause-requested"; + + /** * value: "queued" * @const diff --git a/web/app/src/stores/tasks.js b/web/app/src/stores/tasks.js index afcdf393..b5e1bdb4 100644 --- a/web/app/src/stores/tasks.js +++ b/web/app/src/stores/tasks.js @@ -18,6 +18,9 @@ export const useTasks = defineStore('tasks', { activeTaskID: '', }), getters: { + canPause() { + return this._anyTaskWithStatus(['active', 'queued', 'cancelled']); + }, canCancel() { return this._anyTaskWithStatus(['queued', 'active', 'soft-failed']); }, -- 2.30.2 From 562f77bd7475332f16370439829e34bc1f81e7fe Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 1 Jun 2024 17:09:52 +0800 Subject: [PATCH 02/29] Manager: basic test case for paused status with all queued tasks --- .../task_state_machine_test.go | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/internal/manager/task_state_machine/task_state_machine_test.go b/internal/manager/task_state_machine/task_state_machine_test.go index e936bd23..476a4ded 100644 --- a/internal/manager/task_state_machine/task_state_machine_test.go +++ b/internal/manager/task_state_machine/task_state_machine_test.go @@ -336,6 +336,29 @@ func TestJobCancelWithSomeCompletedTasks(t *testing.T) { require.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusCancelRequested, "someone wrote a unittest")) } +func TestJobPauseWithAllQueuedTasks(t *testing.T) { + mockCtrl, ctx, sm, mocks := taskStateMachineTestFixtures(t) + defer mockCtrl.Finish() + + task1 := taskWithStatus(api.JobStatusActive, api.TaskStatusQueued) + task2 := taskOfSameJob(task1, api.TaskStatusQueued) + task3 := taskOfSameJob(task2, api.TaskStatusQueued) + job := task3.Job + + mocks.expectSaveJobWithStatus(t, job, api.JobStatusPauseRequested) + + // Expect pausing of the job to trigger pausing of all its queued tasks. + mocks.persist.EXPECT().UpdateJobsTaskStatuses(ctx, job, api.TaskStatusPaused, + "Paused because job transitioned status from \"active\" to \"paused\"") + + mocks.expectSaveJobWithStatus(t, job, api.JobStatusPaused) + + mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusActive, api.JobStatusPauseRequested) + mocks.expectBroadcastJobChange(job, api.JobStatusPauseRequested, api.JobStatusPaused) + + require.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusPauseRequested, "someone wrote a unittest")) +} + func TestCheckStuck(t *testing.T) { mockCtrl, ctx, sm, mocks := taskStateMachineTestFixtures(t) defer mockCtrl.Finish() -- 2.30.2 From 716f86c0f42322df6644ae7a8d31efd1018d4866 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 1 Jun 2024 17:13:11 +0800 Subject: [PATCH 03/29] Manager: leave out updateJobOnTaskStatusPaused --- .../task_state_machine/task_state_machine.go | 34 +------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 085837aa..2b4c2663 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -119,7 +119,7 @@ func (sm *StateMachine) updateJobAfterTaskStatusChange( return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusCompleted, api.JobStatusRequeueing, "task was queued") case api.TaskStatusPaused: - return sm.updateJobOnTaskStatusPaused(ctx, logger, job) + return nil case api.TaskStatusCanceled: return sm.updateJobOnTaskStatusCanceled(ctx, logger, job) @@ -182,38 +182,6 @@ func (sm *StateMachine) updateJobOnTaskStatusCanceled(ctx context.Context, logge return nil } -// updateJobOnTaskStatusPaused conditionally escalates the pausing of a task to pause the job. -func (sm *StateMachine) updateJobOnTaskStatusPaused(ctx context.Context, logger zerolog.Logger, job *persistence.Job) error { - // If no more tasks can run, pause the job. - numRunnable, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, - api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed) - if err != nil { - return err - } - if numRunnable == 0 { - logger.Info().Msg("paused task was last runnable task of job, pausing job") - return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "paused task was last runnable task of job, pausing job") - } - - if job.Status == api.JobStatusPauseRequested { - // if the job is in pause-requested state, and all other tasks are paused, - // then the job can be paused. - numPaused, numTotal, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusPaused) - if err != nil { - return err - } - if numPaused == numTotal { - logger.Info().Msg("all tasks of job are paused, job is paused") - return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks paused") - } - } else { - // if the job is not in pause-requested state, then some error occurred and the job should be failed. - logger.Info().Msg("task cannot be changed to paused when job is not in pause-requested state") - } - - return nil -} - // updateJobOnTaskStatusFailed conditionally escalates the failure of a task to fail the entire job. func (sm *StateMachine) updateJobOnTaskStatusFailed(ctx context.Context, logger zerolog.Logger, job *persistence.Job) error { // Count the number of failed tasks. If it is over the threshold, fail the job. -- 2.30.2 From e30832aab4dd4bb4992531cc97bc051773146159 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 1 Jun 2024 17:18:22 +0800 Subject: [PATCH 04/29] Manager: taskStatusesToPause should include soft-failed --- internal/manager/task_state_machine/task_state_machine.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 2b4c2663..5520331c 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -455,6 +455,7 @@ func (sm *StateMachine) pauseTasks( api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusCanceled, + api.TaskStatusSoftFailed, } err := sm.persist.UpdateJobsTaskStatusesConditional( ctx, job, taskStatusesToPause, api.TaskStatusPaused, -- 2.30.2 From a84097e59f6578622e211ecb475a468cc03152ee Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 1 Jun 2024 17:27:06 +0800 Subject: [PATCH 05/29] Manager: improve error handling of pauseTasks() --- internal/manager/task_state_machine/task_state_machine.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 5520331c..3992ded7 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -5,6 +5,7 @@ package task_state_machine import ( "context" "fmt" + "projects.blender.org/studio/flamenco/pkg/website" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -471,9 +472,9 @@ func (sm *StateMachine) pauseTasks( return api.JobStatusPaused, nil } - // This could mean pause was triggered by failure of the job, in which case the - // job is already in the correct status. - return "", nil + // This could mean state transition entered a non-recoverable error state. + log.Warn().Str("jobStatus", string(job.Status)).Msgf("unexpected job status in StateMachine::pauseTasks(), please report this at %s", website.BugReportURL) + return "", fmt.Errorf("unexpected job status %q in StateMachine::pauseTasks()", job.Status) } // requeueTasks re-queues all tasks of the job. -- 2.30.2 From ba454cd4a0ba7ed244a7fb92622031f3ff21baca Mon Sep 17 00:00:00 2001 From: David Zhang Date: Tue, 4 Jun 2024 21:55:46 +0800 Subject: [PATCH 06/29] Webapp: interactive `Pause Job` button --- web/app/src/components/jobs/JobActionsBar.vue | 3 +++ web/app/src/stores/jobs.js | 6 ++++++ web/app/src/stores/tasks.js | 3 --- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/web/app/src/components/jobs/JobActionsBar.vue b/web/app/src/components/jobs/JobActionsBar.vue index eeb24eb9..d69deff6 100644 --- a/web/app/src/components/jobs/JobActionsBar.vue +++ b/web/app/src/components/jobs/JobActionsBar.vue @@ -72,6 +72,9 @@ export default { onButtonRequeue() { return this._handleJobActionPromise(this.jobs.requeueJobs(), 'requeueing'); }, + onButtonPause() { + return this._handleJobActionPromise(this.jobs.pauseJobs(), 'marked for pausing'); + }, _handleJobActionPromise(promise, description) { return promise.then(() => { diff --git a/web/app/src/stores/jobs.js b/web/app/src/stores/jobs.js index 84c31552..3e524717 100644 --- a/web/app/src/stores/jobs.js +++ b/web/app/src/stores/jobs.js @@ -33,6 +33,9 @@ export const useJobs = defineStore('jobs', { canRequeue() { return this._anyJobWithStatus(['canceled', 'completed', 'failed', 'paused']); }, + canPause() { + return this._anyJobWithStatus(['active', 'queued', 'canceled']); + }, }, actions: { setIsJobless(isJobless) { @@ -74,6 +77,9 @@ export const useJobs = defineStore('jobs', { cancelJobs() { return this._setJobStatus('cancel-requested'); }, + pauseJobs() { + return this._setJobStatus('pause-requested'); + }, requeueJobs() { return this._setJobStatus('requeueing'); }, diff --git a/web/app/src/stores/tasks.js b/web/app/src/stores/tasks.js index b5e1bdb4..afcdf393 100644 --- a/web/app/src/stores/tasks.js +++ b/web/app/src/stores/tasks.js @@ -18,9 +18,6 @@ export const useTasks = defineStore('tasks', { activeTaskID: '', }), getters: { - canPause() { - return this._anyTaskWithStatus(['active', 'queued', 'cancelled']); - }, canCancel() { return this._anyTaskWithStatus(['queued', 'active', 'soft-failed']); }, -- 2.30.2 From 050c779995b3c20ccd92b5056511ec5046c1ca92 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Fri, 7 Jun 2024 01:05:03 +0800 Subject: [PATCH 07/29] Manager: improve state transition logic --- .../task_state_machine/task_state_machine.go | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 3992ded7..44f18647 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -5,8 +5,6 @@ package task_state_machine import ( "context" "fmt" - "projects.blender.org/studio/flamenco/pkg/website" - "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -120,6 +118,7 @@ func (sm *StateMachine) updateJobAfterTaskStatusChange( return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusCompleted, api.JobStatusRequeueing, "task was queued") case api.TaskStatusPaused: + // Pausing a task has no impact on the job. return nil case api.TaskStatusCanceled: @@ -214,10 +213,19 @@ func (sm *StateMachine) updateJobOnTaskStatusCompleted(ctx context.Context, logg if err != nil { return err } + numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) + if err != nil { + return err + } if numComplete == numTotal { logger.Info().Msg("all tasks of job are completed, job is completed") return sm.JobStatusChange(ctx, job, api.JobStatusCompleted, "all tasks completed") } + if numActive == 0 && job.Status == api.JobStatusPauseRequested { + // there is no active task, and the job is in pause-requested status, so we can pause the job + logger.Info().Msg("all tasks of job are completed, job is paused") + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") + } logger.Info(). Int("taskNumTotal", numTotal). Int("taskNumComplete", numComplete). @@ -453,7 +461,6 @@ func (sm *StateMachine) pauseTasks( // Any task that might run in the future should get paused. // Active jobs should remain active until finished taskStatusesToPause := []api.TaskStatus{ - api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusCanceled, api.TaskStatusSoftFailed, @@ -466,15 +473,7 @@ func (sm *StateMachine) pauseTasks( return "", fmt.Errorf("pausing tasks of job %s: %w", job.UUID, err) } - // If pause was requested, it has now happened, so the job can transition. - if job.Status == api.JobStatusPauseRequested { - logger.Info().Msg("all tasks of job paused, job can go to 'paused' status") - return api.JobStatusPaused, nil - } - - // This could mean state transition entered a non-recoverable error state. - log.Warn().Str("jobStatus", string(job.Status)).Msgf("unexpected job status in StateMachine::pauseTasks(), please report this at %s", website.BugReportURL) - return "", fmt.Errorf("unexpected job status %q in StateMachine::pauseTasks()", job.Status) + return api.JobStatusPauseRequested, nil } // requeueTasks re-queues all tasks of the job. -- 2.30.2 From 71c7715eab7dbe04c458b9413c480e582621afd7 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Fri, 7 Jun 2024 14:35:09 +0800 Subject: [PATCH 08/29] Manager: cancelling tasks should not cause a pause-requested job to be cancelled --- .../task_state_machine/task_state_machine.go | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 44f18647..6810a2fc 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -169,7 +169,7 @@ func (sm *StateMachine) jobStatusIfAThenB( func (sm *StateMachine) updateJobOnTaskStatusCanceled(ctx context.Context, logger zerolog.Logger, job *persistence.Job) error { // If no more tasks can run, cancel the job. numRunnable, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, - api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed) + api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed, api.TaskStatusPaused) if err != nil { return err } @@ -179,6 +179,16 @@ func (sm *StateMachine) updateJobOnTaskStatusCanceled(ctx context.Context, logge return sm.JobStatusChange(ctx, job, api.JobStatusCanceled, "canceled task was last runnable task of job, canceling job") } + numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) + if err != nil { + return err + } + if numActive == 0 && job.Status == api.JobStatusPauseRequested { + // there is no active task, and the job is in pause-requested status, so we can pause the job + logger.Info().Msg("all tasks of job are completed, job is paused") + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") + } + return nil } @@ -203,6 +213,16 @@ func (sm *StateMachine) updateJobOnTaskStatusFailed(ctx context.Context, logger } // If the job didn't fail, this failure indicates that at least the job is active. failLogger.Info().Msg("task failed, but not enough to fail the job") + + numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) + if err != nil { + return err + } + if numActive == 0 && job.Status == api.JobStatusPauseRequested { + // there is no active task, and the job is in pause-requested status, so we can pause the job + logger.Info().Msg("all tasks of job are completed, job is paused") + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") + } return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusQueued, api.JobStatusActive, "task failed, but not enough to fail the job") } @@ -473,6 +493,16 @@ func (sm *StateMachine) pauseTasks( return "", fmt.Errorf("pausing tasks of job %s: %w", job.UUID, err) } + // If pausing was requested, it has now happened, so the job can transition. + numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) + if err != nil { + return "", fmt.Errorf("error when accessing number of active tasks") + } + if job.Status == api.JobStatusPauseRequested && numActive == 0 { + logger.Info().Msg("all tasks of job paused, job can go to 'paused' status") + return api.JobStatusPaused, nil + } + return api.JobStatusPauseRequested, nil } -- 2.30.2 From 0e523a9b3132873e46e874005231ea906c64c88b Mon Sep 17 00:00:00 2001 From: David Zhang Date: Fri, 7 Jun 2024 16:28:16 +0800 Subject: [PATCH 09/29] Manager: passing TestTaskStatusChangeActiveToCompleted --- internal/manager/task_state_machine/task_state_machine_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/manager/task_state_machine/task_state_machine_test.go b/internal/manager/task_state_machine/task_state_machine_test.go index 476a4ded..7ee71850 100644 --- a/internal/manager/task_state_machine/task_state_machine_test.go +++ b/internal/manager/task_state_machine/task_state_machine_test.go @@ -76,6 +76,7 @@ func TestTaskStatusChangeActiveToCompleted(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task, "task changed status active -> completed") mocks.expectBroadcastTaskChange(task, api.TaskStatusActive, api.TaskStatusCompleted) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusCompleted).Return(1, 3, nil) // 1 of 3 complete. + mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusActive).Return(2, 3, nil) // 2 of 3 active. require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusCompleted)) // Second task hickup: T: active > soft-failed --> J: active > active @@ -89,6 +90,7 @@ func TestTaskStatusChangeActiveToCompleted(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task2, "task changed status soft-failed -> completed") mocks.expectBroadcastTaskChange(task2, api.TaskStatusSoftFailed, api.TaskStatusCompleted) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusCompleted).Return(2, 3, nil) // 2 of 3 complete. + mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusActive).Return(1, 3, nil) // 1 of 3 active. require.NoError(t, sm.TaskStatusChange(ctx, task2, api.TaskStatusCompleted)) // Third task completing: T: active > completed --> J: active > completed @@ -96,6 +98,7 @@ func TestTaskStatusChangeActiveToCompleted(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task3, "task changed status active -> completed") mocks.expectBroadcastTaskChange(task3, api.TaskStatusActive, api.TaskStatusCompleted) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusCompleted).Return(3, 3, nil) // 3 of 3 complete. + mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusActive).Return(0, 3, nil) // 0 of 3 active. mocks.expectSaveJobWithStatus(t, task.Job, api.JobStatusCompleted) mocks.expectBroadcastJobChange(task.Job, api.JobStatusActive, api.JobStatusCompleted) -- 2.30.2 From 1c35617cb151e739082d19d5907e86218c8bba73 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Thu, 13 Jun 2024 00:18:33 +0800 Subject: [PATCH 10/29] Manager: fix manager warning --- internal/manager/task_state_machine/task_state_machine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 6810a2fc..7ec9c033 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -397,7 +397,7 @@ func (sm *StateMachine) updateTasksAfterJobStatusChange( // Every case in this switch MUST return, for sanity sake. switch job.Status { - case api.JobStatusCompleted, api.JobStatusCanceled: + case api.JobStatusCompleted, api.JobStatusCanceled, api.JobStatusPaused: // Nothing to do; this will happen as a response to all tasks receiving this status. return tasksUpdateResult{}, nil -- 2.30.2 From c3af84f6a66756fc327dec14fc393f3da9edc484 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Fri, 14 Jun 2024 20:14:46 +0900 Subject: [PATCH 11/29] Manager: pass TestTaskStatusChangeQueuedToFailed and TestTaskStatusChangeCancelSingleTask --- .../manager/task_state_machine/task_state_machine_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine_test.go b/internal/manager/task_state_machine/task_state_machine_test.go index f0bcd3bb..8380c2af 100644 --- a/internal/manager/task_state_machine/task_state_machine_test.go +++ b/internal/manager/task_state_machine/task_state_machine_test.go @@ -116,6 +116,7 @@ func TestTaskStatusChangeQueuedToFailed(t *testing.T) { mocks.expectBroadcastTaskChange(task, api.TaskStatusQueued, api.TaskStatusFailed) mocks.expectSaveJobWithStatus(t, task.Job, api.JobStatusActive) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusFailed).Return(1, 100, nil) // 1 out of 100 failed. + mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusActive).Return(0, 100, nil) // 0 out of 100 active. mocks.expectBroadcastJobChange(task.Job, api.JobStatusQueued, api.JobStatusActive) require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusFailed)) @@ -188,8 +189,10 @@ func TestTaskStatusChangeCancelSingleTask(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task, "task changed status active -> canceled") mocks.expectBroadcastTaskChange(task, api.TaskStatusActive, api.TaskStatusCanceled) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, - api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed). + api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed, api.TaskStatusPaused). Return(1, 2, nil) + mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, + api.TaskStatusActive).Return(0, 2, nil) require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusCanceled)) // T2: queued > cancelled --> J: cancel-requested > canceled @@ -197,7 +200,7 @@ func TestTaskStatusChangeCancelSingleTask(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task2, "task changed status queued -> canceled") mocks.expectBroadcastTaskChange(task2, api.TaskStatusQueued, api.TaskStatusCanceled) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, - api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed). + api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed, api.TaskStatusPaused). Return(0, 2, nil) mocks.expectSaveJobWithStatus(t, job, api.JobStatusCanceled) mocks.expectBroadcastJobChange(task.Job, api.JobStatusCancelRequested, api.JobStatusCanceled) -- 2.30.2 From c32a591e5566531f2bf64aa61504afaa14f89790 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 15 Jun 2024 11:52:21 -0400 Subject: [PATCH 12/29] Manager: disallow task cancellation when the job has `pause-requested` status --- web/app/src/stores/tasks.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/web/app/src/stores/tasks.js b/web/app/src/stores/tasks.js index afcdf393..99f16f5c 100644 --- a/web/app/src/stores/tasks.js +++ b/web/app/src/stores/tasks.js @@ -2,6 +2,7 @@ import { defineStore } from 'pinia'; import * as API from '@/manager-api'; import { getAPIClient } from '@/api-client'; +import { useJobs } from '@/stores/jobs'; const jobsAPI = new API.JobsApi(getAPIClient()); @@ -19,6 +20,14 @@ export const useTasks = defineStore('tasks', { }), getters: { canCancel() { + const jobs = useJobs(); + const activeJob = jobs.activeJob; + + // Check if the job status is 'pause-requested' + if (activeJob && activeJob.status === 'pause-requested') { + return false; + } + // Allow cancellation for specified task statuses return this._anyTaskWithStatus(['queued', 'active', 'soft-failed']); }, canRequeue() { -- 2.30.2 From 5a4e225a6b9cc424a96f89446e61294bec9d69f5 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Tue, 18 Jun 2024 13:36:07 -0400 Subject: [PATCH 13/29] Manager: keep the newline between built-in packages and 3rd party packages --- internal/manager/task_state_machine/task_state_machine.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 7ec9c033..1abefe24 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -5,6 +5,7 @@ package task_state_machine import ( "context" "fmt" + "github.com/rs/zerolog" "github.com/rs/zerolog/log" -- 2.30.2 From 4b4511f9b6d87788a78e6bb56ec1cc377d1e6e3b Mon Sep 17 00:00:00 2001 From: David Zhang Date: Tue, 18 Jun 2024 16:12:59 -0400 Subject: [PATCH 14/29] Manager: reorder updateJobOnTaskStatusCanceled logic --- .../task_state_machine/task_state_machine.go | 22 ++++++++++++------- .../task_state_machine_test.go | 2 -- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 1abefe24..7c4700cf 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -180,16 +180,22 @@ func (sm *StateMachine) updateJobOnTaskStatusCanceled(ctx context.Context, logge return sm.JobStatusChange(ctx, job, api.JobStatusCanceled, "canceled task was last runnable task of job, canceling job") } - numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) - if err != nil { - return err - } - if numActive == 0 && job.Status == api.JobStatusPauseRequested { - // there is no active task, and the job is in pause-requested status, so we can pause the job - logger.Info().Msg("all tasks of job are completed, job is paused") - return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") + // Deal with the special case when the job is in pause-requested status. + if job.Status != api.JobStatusPauseRequested { + return nil + } else { + numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) + if err != nil { + return err + } + if numActive == 0 { + // there is no active task, and the job is in pause-requested status, so we can pause the job + logger.Info().Msg("all tasks of job are completed, job is paused") + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") + } } + // Execution should not reach here. return nil } diff --git a/internal/manager/task_state_machine/task_state_machine_test.go b/internal/manager/task_state_machine/task_state_machine_test.go index 8380c2af..da150724 100644 --- a/internal/manager/task_state_machine/task_state_machine_test.go +++ b/internal/manager/task_state_machine/task_state_machine_test.go @@ -191,8 +191,6 @@ func TestTaskStatusChangeCancelSingleTask(t *testing.T) { mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed, api.TaskStatusPaused). Return(1, 2, nil) - mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, - api.TaskStatusActive).Return(0, 2, nil) require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusCanceled)) // T2: queued > cancelled --> J: cancel-requested > canceled -- 2.30.2 From c13cc884cec764161d314b4632a2ed2a6135b3b3 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Tue, 18 Jun 2024 16:16:32 -0400 Subject: [PATCH 15/29] Webapp: end comment with a period --- web/app/src/stores/tasks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/src/stores/tasks.js b/web/app/src/stores/tasks.js index 99f16f5c..67803473 100644 --- a/web/app/src/stores/tasks.js +++ b/web/app/src/stores/tasks.js @@ -23,11 +23,11 @@ export const useTasks = defineStore('tasks', { const jobs = useJobs(); const activeJob = jobs.activeJob; - // Check if the job status is 'pause-requested' + // Check if the job status is 'pause-requested'. if (activeJob && activeJob.status === 'pause-requested') { return false; } - // Allow cancellation for specified task statuses + // Allow cancellation for specified task statuses. return this._anyTaskWithStatus(['queued', 'active', 'soft-failed']); }, canRequeue() { -- 2.30.2 From a569a1ce00d50d18196cc17d613cc9362713e942 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Tue, 18 Jun 2024 16:27:24 -0400 Subject: [PATCH 16/29] Manager: pauseTasks keeps cancelled tasks as cancelled --- internal/manager/task_state_machine/task_state_machine.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 7c4700cf..f0042688 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -486,10 +486,9 @@ func (sm *StateMachine) pauseTasks( logger.Info().Msg("pausing tasks of job") // Any task that might run in the future should get paused. - // Active jobs should remain active until finished + // Active tasks should remain active until finished. taskStatusesToPause := []api.TaskStatus{ api.TaskStatusQueued, - api.TaskStatusCanceled, api.TaskStatusSoftFailed, } err := sm.persist.UpdateJobsTaskStatusesConditional( -- 2.30.2 From 05a1388106f82e9083031b27e79da4b2d5d80653 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Tue, 18 Jun 2024 16:31:08 -0400 Subject: [PATCH 17/29] Webapp: update canCancel to properly expose bugs --- web/app/src/stores/tasks.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/web/app/src/stores/tasks.js b/web/app/src/stores/tasks.js index 67803473..351dff6e 100644 --- a/web/app/src/stores/tasks.js +++ b/web/app/src/stores/tasks.js @@ -23,10 +23,17 @@ export const useTasks = defineStore('tasks', { const jobs = useJobs(); const activeJob = jobs.activeJob; - // Check if the job status is 'pause-requested'. - if (activeJob && activeJob.status === 'pause-requested') { + if (!activeJob) { + console.warn('no active job, unable to determine whether the active task is cancellable'); return false; } + + if (activeJob.status == 'pause-requested') { + // Cancelling a task should not be possible while the job is being paused. + // In the future this might be supported, see issue #104315. + return false; + } + // Allow cancellation for specified task statuses. return this._anyTaskWithStatus(['queued', 'active', 'soft-failed']); }, -- 2.30.2 From 01754e9e3c2ef7ad0a8d6440311ddbbf1745004a Mon Sep 17 00:00:00 2001 From: David Zhang Date: Tue, 18 Jun 2024 16:47:55 -0400 Subject: [PATCH 18/29] Manager: correct logger message and reorder logic --- .../task_state_machine/task_state_machine.go | 53 ++++++++++++------- .../task_state_machine_test.go | 4 -- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index f0042688..c46621f3 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -189,13 +189,12 @@ func (sm *StateMachine) updateJobOnTaskStatusCanceled(ctx context.Context, logge return err } if numActive == 0 { - // there is no active task, and the job is in pause-requested status, so we can pause the job - logger.Info().Msg("all tasks of job are completed, job is paused") + // There is no active task, and the job is in pause-requested status, so we can pause the job. + logger.Info().Msg("No more active tasks, job is paused") return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") } } - // Execution should not reach here. return nil } @@ -221,15 +220,21 @@ func (sm *StateMachine) updateJobOnTaskStatusFailed(ctx context.Context, logger // If the job didn't fail, this failure indicates that at least the job is active. failLogger.Info().Msg("task failed, but not enough to fail the job") - numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) - if err != nil { - return err - } - if numActive == 0 && job.Status == api.JobStatusPauseRequested { - // there is no active task, and the job is in pause-requested status, so we can pause the job - logger.Info().Msg("all tasks of job are completed, job is paused") - return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") + if job.Status != api.JobStatusPauseRequested { + return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusQueued, api.JobStatusActive, + "task failed, but not enough to fail the job") + } else { + numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) + if err != nil { + return err + } + if numActive == 0 { + // There is no active task, and the job is in pause-requested status, so we can pause the job. + failLogger.Info().Msg("No more active tasks, job is paused") + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") + } } + return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusQueued, api.JobStatusActive, "task failed, but not enough to fail the job") } @@ -240,19 +245,29 @@ func (sm *StateMachine) updateJobOnTaskStatusCompleted(ctx context.Context, logg if err != nil { return err } - numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) - if err != nil { - return err - } if numComplete == numTotal { logger.Info().Msg("all tasks of job are completed, job is completed") return sm.JobStatusChange(ctx, job, api.JobStatusCompleted, "all tasks completed") } - if numActive == 0 && job.Status == api.JobStatusPauseRequested { - // there is no active task, and the job is in pause-requested status, so we can pause the job - logger.Info().Msg("all tasks of job are completed, job is paused") - return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") + + if job.Status != api.JobStatusPauseRequested { + logger.Info(). + Int("taskNumTotal", numTotal). + Int("taskNumComplete", numComplete). + Msg("task completed; there are more tasks to do") + return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusQueued, api.JobStatusActive, "no more tasks to do") + } else { + numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) + if err != nil { + return err + } + if numActive == 0 { + // There is no active task, and the job is in pause-requested status, so we can pause the job. + logger.Info().Msg("No more active tasks, job is paused") + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") + } } + logger.Info(). Int("taskNumTotal", numTotal). Int("taskNumComplete", numComplete). diff --git a/internal/manager/task_state_machine/task_state_machine_test.go b/internal/manager/task_state_machine/task_state_machine_test.go index da150724..bec7c9fc 100644 --- a/internal/manager/task_state_machine/task_state_machine_test.go +++ b/internal/manager/task_state_machine/task_state_machine_test.go @@ -76,7 +76,6 @@ func TestTaskStatusChangeActiveToCompleted(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task, "task changed status active -> completed") mocks.expectBroadcastTaskChange(task, api.TaskStatusActive, api.TaskStatusCompleted) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusCompleted).Return(1, 3, nil) // 1 of 3 complete. - mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusActive).Return(2, 3, nil) // 2 of 3 active. require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusCompleted)) // Second task hickup: T: active > soft-failed --> J: active > active @@ -90,7 +89,6 @@ func TestTaskStatusChangeActiveToCompleted(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task2, "task changed status soft-failed -> completed") mocks.expectBroadcastTaskChange(task2, api.TaskStatusSoftFailed, api.TaskStatusCompleted) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusCompleted).Return(2, 3, nil) // 2 of 3 complete. - mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusActive).Return(1, 3, nil) // 1 of 3 active. require.NoError(t, sm.TaskStatusChange(ctx, task2, api.TaskStatusCompleted)) // Third task completing: T: active > completed --> J: active > completed @@ -98,7 +96,6 @@ func TestTaskStatusChangeActiveToCompleted(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task3, "task changed status active -> completed") mocks.expectBroadcastTaskChange(task3, api.TaskStatusActive, api.TaskStatusCompleted) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusCompleted).Return(3, 3, nil) // 3 of 3 complete. - mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusActive).Return(0, 3, nil) // 0 of 3 active. mocks.expectSaveJobWithStatus(t, task.Job, api.JobStatusCompleted) mocks.expectBroadcastJobChange(task.Job, api.JobStatusActive, api.JobStatusCompleted) @@ -116,7 +113,6 @@ func TestTaskStatusChangeQueuedToFailed(t *testing.T) { mocks.expectBroadcastTaskChange(task, api.TaskStatusQueued, api.TaskStatusFailed) mocks.expectSaveJobWithStatus(t, task.Job, api.JobStatusActive) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusFailed).Return(1, 100, nil) // 1 out of 100 failed. - mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, task.Job, api.TaskStatusActive).Return(0, 100, nil) // 0 out of 100 active. mocks.expectBroadcastJobChange(task.Job, api.JobStatusQueued, api.JobStatusActive) require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusFailed)) -- 2.30.2 From d510eb390ca155929d83bba0a1b630e1aee5b6f9 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Wed, 19 Jun 2024 11:21:15 -0400 Subject: [PATCH 19/29] Manager: reorder logic --- .../task_state_machine/task_state_machine.go | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index c46621f3..cc446f9c 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -181,9 +181,7 @@ func (sm *StateMachine) updateJobOnTaskStatusCanceled(ctx context.Context, logge } // Deal with the special case when the job is in pause-requested status. - if job.Status != api.JobStatusPauseRequested { - return nil - } else { + if job.Status == api.JobStatusPauseRequested { numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) if err != nil { return err @@ -220,10 +218,7 @@ func (sm *StateMachine) updateJobOnTaskStatusFailed(ctx context.Context, logger // If the job didn't fail, this failure indicates that at least the job is active. failLogger.Info().Msg("task failed, but not enough to fail the job") - if job.Status != api.JobStatusPauseRequested { - return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusQueued, api.JobStatusActive, - "task failed, but not enough to fail the job") - } else { + if job.Status == api.JobStatusPauseRequested { numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) if err != nil { return err @@ -250,13 +245,7 @@ func (sm *StateMachine) updateJobOnTaskStatusCompleted(ctx context.Context, logg return sm.JobStatusChange(ctx, job, api.JobStatusCompleted, "all tasks completed") } - if job.Status != api.JobStatusPauseRequested { - logger.Info(). - Int("taskNumTotal", numTotal). - Int("taskNumComplete", numComplete). - Msg("task completed; there are more tasks to do") - return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusQueued, api.JobStatusActive, "no more tasks to do") - } else { + if job.Status == api.JobStatusPauseRequested { numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) if err != nil { return err -- 2.30.2 From 7835cb8c6da646a3c8b136b4f2faff90cc2d7e50 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Wed, 19 Jun 2024 19:29:18 -0400 Subject: [PATCH 20/29] OAPI: add "submit_as_paused" field to SubmittedJob --- pkg/api/flamenco-openapi.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/api/flamenco-openapi.yaml b/pkg/api/flamenco-openapi.yaml index 491dbd25..c68c8701 100644 --- a/pkg/api/flamenco-openapi.yaml +++ b/pkg/api/flamenco-openapi.yaml @@ -1867,6 +1867,11 @@ components: Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. + "submit_as_paused": + type: boolean + description: > + Whether to submit this job as paused. This is useful for jobs that + need manual intervention before they can be started. required: [name, type, priority, submitter_platform] example: type: "simple-blender-render" -- 2.30.2 From 86ddeb50e9170fff8d9ec7488d973492f667757c Mon Sep 17 00:00:00 2001 From: David Zhang Date: Wed, 19 Jun 2024 19:45:00 -0400 Subject: [PATCH 21/29] OAPI: Regenerate code --- addon/flamenco/manager/docs/Job.md | 1 + addon/flamenco/manager/docs/JobsApi.md | 2 + addon/flamenco/manager/docs/SubmittedJob.md | 1 + addon/flamenco/manager/model/job.py | 4 + addon/flamenco/manager/model/submitted_job.py | 4 + pkg/api/openapi_spec.gen.go | 245 +++++++++--------- pkg/api/openapi_types.gen.go | 3 + web/app/src/manager-api/model/Job.js | 14 + web/app/src/manager-api/model/SubmittedJob.js | 9 + 9 files changed, 161 insertions(+), 122 deletions(-) diff --git a/addon/flamenco/manager/docs/Job.md b/addon/flamenco/manager/docs/Job.md index cc3a8eb5..6e60df14 100644 --- a/addon/flamenco/manager/docs/Job.md +++ b/addon/flamenco/manager/docs/Job.md @@ -18,6 +18,7 @@ Name | Type | Description | Notes **metadata** | [**JobMetadata**](JobMetadata.md) | | [optional] **storage** | [**JobStorageInfo**](JobStorageInfo.md) | | [optional] **worker_tag** | **str** | Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [optional] +**submit_as_paused** | **bool** | Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. | [optional] **delete_requested_at** | **datetime** | If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/addon/flamenco/manager/docs/JobsApi.md b/addon/flamenco/manager/docs/JobsApi.md index e17890e1..7ca7ee5e 100644 --- a/addon/flamenco/manager/docs/JobsApi.md +++ b/addon/flamenco/manager/docs/JobsApi.md @@ -1296,6 +1296,7 @@ with flamenco.manager.ApiClient() as api_client: shaman_checkout_id="shaman_checkout_id_example", ), worker_tag="worker_tag_example", + submit_as_paused=True, ) # SubmittedJob | Job to submit # example passing only required values which don't have defaults set @@ -1378,6 +1379,7 @@ with flamenco.manager.ApiClient() as api_client: shaman_checkout_id="shaman_checkout_id_example", ), worker_tag="worker_tag_example", + submit_as_paused=True, ) # SubmittedJob | Job to check # example passing only required values which don't have defaults set diff --git a/addon/flamenco/manager/docs/SubmittedJob.md b/addon/flamenco/manager/docs/SubmittedJob.md index e3b22b0d..a6ea4728 100644 --- a/addon/flamenco/manager/docs/SubmittedJob.md +++ b/addon/flamenco/manager/docs/SubmittedJob.md @@ -14,6 +14,7 @@ Name | Type | Description | Notes **metadata** | [**JobMetadata**](JobMetadata.md) | | [optional] **storage** | [**JobStorageInfo**](JobStorageInfo.md) | | [optional] **worker_tag** | **str** | Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [optional] +**submit_as_paused** | **bool** | Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/addon/flamenco/manager/model/job.py b/addon/flamenco/manager/model/job.py index 6918b169..27855f61 100644 --- a/addon/flamenco/manager/model/job.py +++ b/addon/flamenco/manager/model/job.py @@ -111,6 +111,7 @@ class Job(ModelComposed): 'metadata': (JobMetadata,), # noqa: E501 'storage': (JobStorageInfo,), # noqa: E501 'worker_tag': (str,), # noqa: E501 + 'submit_as_paused': (bool,), # noqa: E501 'delete_requested_at': (datetime,), # noqa: E501 } @@ -134,6 +135,7 @@ class Job(ModelComposed): 'metadata': 'metadata', # noqa: E501 'storage': 'storage', # noqa: E501 'worker_tag': 'worker_tag', # noqa: E501 + 'submit_as_paused': 'submit_as_paused', # noqa: E501 'delete_requested_at': 'delete_requested_at', # noqa: E501 } @@ -190,6 +192,7 @@ class Job(ModelComposed): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 + submit_as_paused (bool): Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. . [optional] # noqa: E501 delete_requested_at (datetime): If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. . [optional] # noqa: E501 """ @@ -305,6 +308,7 @@ class Job(ModelComposed): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 + submit_as_paused (bool): Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. . [optional] # noqa: E501 delete_requested_at (datetime): If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. . [optional] # noqa: E501 """ diff --git a/addon/flamenco/manager/model/submitted_job.py b/addon/flamenco/manager/model/submitted_job.py index ce91ed25..3a195eb0 100644 --- a/addon/flamenco/manager/model/submitted_job.py +++ b/addon/flamenco/manager/model/submitted_job.py @@ -100,6 +100,7 @@ class SubmittedJob(ModelNormal): 'metadata': (JobMetadata,), # noqa: E501 'storage': (JobStorageInfo,), # noqa: E501 'worker_tag': (str,), # noqa: E501 + 'submit_as_paused': (bool,), # noqa: E501 } @cached_property @@ -117,6 +118,7 @@ class SubmittedJob(ModelNormal): 'metadata': 'metadata', # noqa: E501 'storage': 'storage', # noqa: E501 'worker_tag': 'worker_tag', # noqa: E501 + 'submit_as_paused': 'submit_as_paused', # noqa: E501 } read_only_vars = { @@ -171,6 +173,7 @@ class SubmittedJob(ModelNormal): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 + submit_as_paused (bool): Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. . [optional] # noqa: E501 """ priority = kwargs.get('priority', 50) @@ -268,6 +271,7 @@ class SubmittedJob(ModelNormal): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 + submit_as_paused (bool): Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. . [optional] # noqa: E501 """ priority = kwargs.get('priority', 50) diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index 2de53300..071828d9 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -124,128 +124,129 @@ var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/api/openapi_types.gen.go b/pkg/api/openapi_types.gen.go index 251670e2..4e9e990f 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -711,6 +711,9 @@ type SubmittedJob struct { // Storage info of a job, which Flamenco can use to remove job-related files when necessary. Storage *JobStorageInfo `json:"storage,omitempty"` + // Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. + SubmitAsPaused *bool `json:"submit_as_paused,omitempty"` + // Operating system of the submitter. This is used to recognise two-way variables. This should be a lower-case version of the platform, like "linux", "windows", "darwin", "openbsd", etc. Should be ompatible with Go's `runtime.GOOS`; run `go tool dist list` to get a list of possible platforms. // As a special case, the platform "manager" can be given, which will be interpreted as "the Manager's platform". This is mostly to make test/debug scripts easier, as they can use a static document on all platforms. SubmitterPlatform string `json:"submitter_platform"` diff --git a/web/app/src/manager-api/model/Job.js b/web/app/src/manager-api/model/Job.js index a5bab8d8..79ae10b6 100644 --- a/web/app/src/manager-api/model/Job.js +++ b/web/app/src/manager-api/model/Job.js @@ -100,6 +100,9 @@ class Job { if (data.hasOwnProperty('worker_tag')) { obj['worker_tag'] = ApiClient.convertToType(data['worker_tag'], 'String'); } + if (data.hasOwnProperty('submit_as_paused')) { + obj['submit_as_paused'] = ApiClient.convertToType(data['submit_as_paused'], 'Boolean'); + } if (data.hasOwnProperty('id')) { obj['id'] = ApiClient.convertToType(data['id'], 'String'); } @@ -175,6 +178,12 @@ Job.prototype['storage'] = undefined; */ Job.prototype['worker_tag'] = undefined; +/** + * Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. + * @member {Boolean} submit_as_paused + */ +Job.prototype['submit_as_paused'] = undefined; + /** * UUID of the Job * @member {String} id @@ -253,6 +262,11 @@ SubmittedJob.prototype['storage'] = undefined; * @member {String} worker_tag */ SubmittedJob.prototype['worker_tag'] = undefined; +/** + * Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. + * @member {Boolean} submit_as_paused + */ +SubmittedJob.prototype['submit_as_paused'] = undefined; // Implement JobAllOf interface: /** * UUID of the Job diff --git a/web/app/src/manager-api/model/SubmittedJob.js b/web/app/src/manager-api/model/SubmittedJob.js index fb0d29ed..0fe0274f 100644 --- a/web/app/src/manager-api/model/SubmittedJob.js +++ b/web/app/src/manager-api/model/SubmittedJob.js @@ -84,6 +84,9 @@ class SubmittedJob { if (data.hasOwnProperty('worker_tag')) { obj['worker_tag'] = ApiClient.convertToType(data['worker_tag'], 'String'); } + if (data.hasOwnProperty('submit_as_paused')) { + obj['submit_as_paused'] = ApiClient.convertToType(data['submit_as_paused'], 'Boolean'); + } } return obj; } @@ -141,6 +144,12 @@ SubmittedJob.prototype['storage'] = undefined; */ SubmittedJob.prototype['worker_tag'] = undefined; +/** + * Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. + * @member {Boolean} submit_as_paused + */ +SubmittedJob.prototype['submit_as_paused'] = undefined; + -- 2.30.2 From 8f067da901a148e4cb2a8bbb45cce17a45c4a118 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Thu, 20 Jun 2024 15:08:21 -0400 Subject: [PATCH 22/29] Manager: wrap job pause condition inside a function --- .../task_state_machine/task_state_machine.go | 67 ++++++++++--------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index cc446f9c..6e0113cb 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -166,11 +166,26 @@ func (sm *StateMachine) jobStatusIfAThenB( return sm.JobStatusChange(ctx, job, thenStatus, reason) } +func (sm *StateMachine) shouldJobBePaused(ctx context.Context, logger zerolog.Logger, job *persistence.Job) (bool, error) { + if job.Status == api.JobStatusPauseRequested { + numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) + if err != nil { + return false, err + } + if numActive == 0 { + // There is no active task, and the job is in pause-requested status, so we can pause the job. + logger.Info().Msg("No more active tasks, job is paused") + return true, nil + } + } + return false, nil +} + // updateJobOnTaskStatusCanceled conditionally escalates the cancellation of a task to cancel the job. func (sm *StateMachine) updateJobOnTaskStatusCanceled(ctx context.Context, logger zerolog.Logger, job *persistence.Job) error { // If no more tasks can run, cancel the job. numRunnable, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, - api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed, api.TaskStatusPaused) + api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed) if err != nil { return err } @@ -181,16 +196,12 @@ func (sm *StateMachine) updateJobOnTaskStatusCanceled(ctx context.Context, logge } // Deal with the special case when the job is in pause-requested status. - if job.Status == api.JobStatusPauseRequested { - numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) - if err != nil { - return err - } - if numActive == 0 { - // There is no active task, and the job is in pause-requested status, so we can pause the job. - logger.Info().Msg("No more active tasks, job is paused") - return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") - } + toBePaused, err := sm.shouldJobBePaused(ctx, logger, job) + if err != nil { + return err + } + if toBePaused { + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "no more active tasks after task cancellation") } return nil @@ -218,16 +229,13 @@ func (sm *StateMachine) updateJobOnTaskStatusFailed(ctx context.Context, logger // If the job didn't fail, this failure indicates that at least the job is active. failLogger.Info().Msg("task failed, but not enough to fail the job") - if job.Status == api.JobStatusPauseRequested { - numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) - if err != nil { - return err - } - if numActive == 0 { - // There is no active task, and the job is in pause-requested status, so we can pause the job. - failLogger.Info().Msg("No more active tasks, job is paused") - return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") - } + // Deal with the special case when the job is in pause-requested status. + toBePaused, err := sm.shouldJobBePaused(ctx, logger, job) + if err != nil { + return err + } + if toBePaused { + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "no more active tasks after task failure") } return sm.jobStatusIfAThenB(ctx, logger, job, api.JobStatusQueued, api.JobStatusActive, @@ -245,16 +253,13 @@ func (sm *StateMachine) updateJobOnTaskStatusCompleted(ctx context.Context, logg return sm.JobStatusChange(ctx, job, api.JobStatusCompleted, "all tasks completed") } - if job.Status == api.JobStatusPauseRequested { - numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) - if err != nil { - return err - } - if numActive == 0 { - // There is no active task, and the job is in pause-requested status, so we can pause the job. - logger.Info().Msg("No more active tasks, job is paused") - return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "all tasks completed") - } + // Deal with the special case when the job is in pause-requested status. + toBePaused, err := sm.shouldJobBePaused(ctx, logger, job) + if err != nil { + return err + } + if toBePaused { + return sm.JobStatusChange(ctx, job, api.JobStatusPaused, "no more active tasks after task completion") } logger.Info(). -- 2.30.2 From 009ad23da133f9391218229ce8cc7f4d51860239 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Thu, 20 Jun 2024 15:13:43 -0400 Subject: [PATCH 23/29] Manager: all original test cases passed --- .../manager/task_state_machine/task_state_machine_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine_test.go b/internal/manager/task_state_machine/task_state_machine_test.go index bec7c9fc..f48f50a6 100644 --- a/internal/manager/task_state_machine/task_state_machine_test.go +++ b/internal/manager/task_state_machine/task_state_machine_test.go @@ -185,7 +185,7 @@ func TestTaskStatusChangeCancelSingleTask(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task, "task changed status active -> canceled") mocks.expectBroadcastTaskChange(task, api.TaskStatusActive, api.TaskStatusCanceled) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, - api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed, api.TaskStatusPaused). + api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed). Return(1, 2, nil) require.NoError(t, sm.TaskStatusChange(ctx, task, api.TaskStatusCanceled)) @@ -194,7 +194,7 @@ func TestTaskStatusChangeCancelSingleTask(t *testing.T) { mocks.expectWriteTaskLogTimestamped(t, task2, "task changed status queued -> canceled") mocks.expectBroadcastTaskChange(task2, api.TaskStatusQueued, api.TaskStatusCanceled) mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, - api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed, api.TaskStatusPaused). + api.TaskStatusActive, api.TaskStatusQueued, api.TaskStatusSoftFailed). Return(0, 2, nil) mocks.expectSaveJobWithStatus(t, job, api.JobStatusCanceled) mocks.expectBroadcastJobChange(task.Job, api.JobStatusCancelRequested, api.JobStatusCanceled) -- 2.30.2 From 484f746f92da3912e02b67f672fa3fc2e1979068 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Thu, 20 Jun 2024 15:56:18 -0400 Subject: [PATCH 24/29] Manager: add more test cases for paused status --- .../task_state_machine/task_state_machine.go | 4 +- .../task_state_machine_test.go | 77 +++++++++++++++++-- 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/internal/manager/task_state_machine/task_state_machine.go b/internal/manager/task_state_machine/task_state_machine.go index 6e0113cb..d0bcd596 100644 --- a/internal/manager/task_state_machine/task_state_machine.go +++ b/internal/manager/task_state_machine/task_state_machine.go @@ -509,11 +509,11 @@ func (sm *StateMachine) pauseTasks( } // If pausing was requested, it has now happened, so the job can transition. - numActive, _, err := sm.persist.CountTasksOfJobInStatus(ctx, job, api.TaskStatusActive) + toBePaused, err := sm.shouldJobBePaused(ctx, logger, job) if err != nil { return "", fmt.Errorf("error when accessing number of active tasks") } - if job.Status == api.JobStatusPauseRequested && numActive == 0 { + if toBePaused { logger.Info().Msg("all tasks of job paused, job can go to 'paused' status") return api.JobStatusPaused, nil } diff --git a/internal/manager/task_state_machine/task_state_machine_test.go b/internal/manager/task_state_machine/task_state_machine_test.go index f48f50a6..531bd7ca 100644 --- a/internal/manager/task_state_machine/task_state_machine_test.go +++ b/internal/manager/task_state_machine/task_state_machine_test.go @@ -340,7 +340,7 @@ func TestJobPauseWithAllQueuedTasks(t *testing.T) { mockCtrl, ctx, sm, mocks := taskStateMachineTestFixtures(t) defer mockCtrl.Finish() - task1 := taskWithStatus(api.JobStatusActive, api.TaskStatusQueued) + task1 := taskWithStatus(api.JobStatusQueued, api.TaskStatusQueued) task2 := taskOfSameJob(task1, api.TaskStatusQueued) task3 := taskOfSameJob(task2, api.TaskStatusQueued) job := task3.Job @@ -348,17 +348,82 @@ func TestJobPauseWithAllQueuedTasks(t *testing.T) { mocks.expectSaveJobWithStatus(t, job, api.JobStatusPauseRequested) // Expect pausing of the job to trigger pausing of all its queued tasks. - mocks.persist.EXPECT().UpdateJobsTaskStatuses(ctx, job, api.TaskStatusPaused, - "Paused because job transitioned status from \"active\" to \"paused\"") - + mocks.persist.EXPECT().UpdateJobsTaskStatusesConditional(ctx, job, + []api.TaskStatus{ + api.TaskStatusQueued, + api.TaskStatusSoftFailed, + }, + api.TaskStatusPaused, + "Manager paused this task because the job got status \"pause-requested\".", + ) + mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, + api.TaskStatusActive). + Return(0, 3, nil) mocks.expectSaveJobWithStatus(t, job, api.JobStatusPaused) - - mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusActive, api.JobStatusPauseRequested) + mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusQueued, api.JobStatusPauseRequested) mocks.expectBroadcastJobChange(job, api.JobStatusPauseRequested, api.JobStatusPaused) require.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusPauseRequested, "someone wrote a unittest")) } +func TestJobPauseWithSomeCompletedTasks(t *testing.T) { + mockCtrl, ctx, sm, mocks := taskStateMachineTestFixtures(t) + defer mockCtrl.Finish() + + task1 := taskWithStatus(api.JobStatusQueued, api.TaskStatusCompleted) + task2 := taskOfSameJob(task1, api.TaskStatusQueued) + task3 := taskOfSameJob(task2, api.TaskStatusQueued) + job := task3.Job + + mocks.expectSaveJobWithStatus(t, job, api.JobStatusPauseRequested) + + // Expect pausing of the job to trigger pausing of all its queued tasks. + mocks.persist.EXPECT().UpdateJobsTaskStatusesConditional(ctx, job, + []api.TaskStatus{ + api.TaskStatusQueued, + api.TaskStatusSoftFailed, + }, + api.TaskStatusPaused, + "Manager paused this task because the job got status \"pause-requested\".", + ) + mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, + api.TaskStatusActive). + Return(0, 3, nil) + mocks.expectSaveJobWithStatus(t, job, api.JobStatusPaused) + mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusQueued, api.JobStatusPauseRequested) + mocks.expectBroadcastJobChange(job, api.JobStatusPauseRequested, api.JobStatusPaused) + + require.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusPauseRequested, "someone wrote a unittest")) +} + +func TestJobPauseWithSomeActiveTasks(t *testing.T) { + mockCtrl, ctx, sm, mocks := taskStateMachineTestFixtures(t) + defer mockCtrl.Finish() + + task1 := taskWithStatus(api.JobStatusActive, api.TaskStatusActive) + task2 := taskOfSameJob(task1, api.TaskStatusCompleted) + task3 := taskOfSameJob(task2, api.TaskStatusQueued) + job := task3.Job + + mocks.expectSaveJobWithStatus(t, job, api.JobStatusPauseRequested) + + // Expect pausing of the job to trigger pausing of all its queued tasks. + mocks.persist.EXPECT().UpdateJobsTaskStatusesConditional(ctx, job, + []api.TaskStatus{ + api.TaskStatusQueued, + api.TaskStatusSoftFailed, + }, + api.TaskStatusPaused, + "Manager paused this task because the job got status \"pause-requested\".", + ) + mocks.persist.EXPECT().CountTasksOfJobInStatus(ctx, job, + api.TaskStatusActive). + Return(1, 3, nil) + mocks.expectBroadcastJobChangeWithTaskRefresh(job, api.JobStatusActive, api.JobStatusPauseRequested) + + require.NoError(t, sm.JobStatusChange(ctx, job, api.JobStatusPauseRequested, "someone wrote a unittest")) +} + func TestCheckStuck(t *testing.T) { mockCtrl, ctx, sm, mocks := taskStateMachineTestFixtures(t) defer mockCtrl.Finish() -- 2.30.2 From 56fdf15e2ba8b2adab3bdce2b8fbf1fb0033486c Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 22 Jun 2024 09:04:15 -0400 Subject: [PATCH 25/29] OAPI: change "submit_as_paused" to "initial_status" --- pkg/api/flamenco-openapi.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/api/flamenco-openapi.yaml b/pkg/api/flamenco-openapi.yaml index c68c8701..127c060c 100644 --- a/pkg/api/flamenco-openapi.yaml +++ b/pkg/api/flamenco-openapi.yaml @@ -1867,11 +1867,11 @@ components: Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. - "submit_as_paused": - type: boolean + "initial_status": + type: string description: > - Whether to submit this job as paused. This is useful for jobs that - need manual intervention before they can be started. + Initial status of the job. If not given, the job will start in the + 'queued' status. Currently only 'queued' and 'paused' are supported. required: [name, type, priority, submitter_platform] example: type: "simple-blender-render" -- 2.30.2 From 5a242095d9b13bbc2b15c27f67e3ef97dc0067d4 Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 22 Jun 2024 09:05:46 -0400 Subject: [PATCH 26/29] OAPI: Regenerate code --- addon/flamenco/manager/docs/Job.md | 2 +- addon/flamenco/manager/docs/JobsApi.md | 4 +- addon/flamenco/manager/docs/SubmittedJob.md | 2 +- addon/flamenco/manager/model/job.py | 8 +- addon/flamenco/manager/model/submitted_job.py | 8 +- pkg/api/openapi_spec.gen.go | 458 +++++++++--------- pkg/api/openapi_types.gen.go | 6 +- web/app/src/manager-api/model/Job.js | 16 +- web/app/src/manager-api/model/SubmittedJob.js | 10 +- 9 files changed, 257 insertions(+), 257 deletions(-) diff --git a/addon/flamenco/manager/docs/Job.md b/addon/flamenco/manager/docs/Job.md index 6e60df14..1b58f2e4 100644 --- a/addon/flamenco/manager/docs/Job.md +++ b/addon/flamenco/manager/docs/Job.md @@ -18,7 +18,7 @@ Name | Type | Description | Notes **metadata** | [**JobMetadata**](JobMetadata.md) | | [optional] **storage** | [**JobStorageInfo**](JobStorageInfo.md) | | [optional] **worker_tag** | **str** | Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [optional] -**submit_as_paused** | **bool** | Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. | [optional] +**initial_status** | **str** | Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. | [optional] **delete_requested_at** | **datetime** | If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/addon/flamenco/manager/docs/JobsApi.md b/addon/flamenco/manager/docs/JobsApi.md index 7ca7ee5e..6e100a0d 100644 --- a/addon/flamenco/manager/docs/JobsApi.md +++ b/addon/flamenco/manager/docs/JobsApi.md @@ -1296,7 +1296,7 @@ with flamenco.manager.ApiClient() as api_client: shaman_checkout_id="shaman_checkout_id_example", ), worker_tag="worker_tag_example", - submit_as_paused=True, + initial_status="initial_status_example", ) # SubmittedJob | Job to submit # example passing only required values which don't have defaults set @@ -1379,7 +1379,7 @@ with flamenco.manager.ApiClient() as api_client: shaman_checkout_id="shaman_checkout_id_example", ), worker_tag="worker_tag_example", - submit_as_paused=True, + initial_status="initial_status_example", ) # SubmittedJob | Job to check # example passing only required values which don't have defaults set diff --git a/addon/flamenco/manager/docs/SubmittedJob.md b/addon/flamenco/manager/docs/SubmittedJob.md index a6ea4728..25bebbdd 100644 --- a/addon/flamenco/manager/docs/SubmittedJob.md +++ b/addon/flamenco/manager/docs/SubmittedJob.md @@ -14,7 +14,7 @@ Name | Type | Description | Notes **metadata** | [**JobMetadata**](JobMetadata.md) | | [optional] **storage** | [**JobStorageInfo**](JobStorageInfo.md) | | [optional] **worker_tag** | **str** | Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [optional] -**submit_as_paused** | **bool** | Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. | [optional] +**initial_status** | **str** | Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/addon/flamenco/manager/model/job.py b/addon/flamenco/manager/model/job.py index 27855f61..8f70bc71 100644 --- a/addon/flamenco/manager/model/job.py +++ b/addon/flamenco/manager/model/job.py @@ -111,7 +111,7 @@ class Job(ModelComposed): 'metadata': (JobMetadata,), # noqa: E501 'storage': (JobStorageInfo,), # noqa: E501 'worker_tag': (str,), # noqa: E501 - 'submit_as_paused': (bool,), # noqa: E501 + 'initial_status': (str,), # noqa: E501 'delete_requested_at': (datetime,), # noqa: E501 } @@ -135,7 +135,7 @@ class Job(ModelComposed): 'metadata': 'metadata', # noqa: E501 'storage': 'storage', # noqa: E501 'worker_tag': 'worker_tag', # noqa: E501 - 'submit_as_paused': 'submit_as_paused', # noqa: E501 + 'initial_status': 'initial_status', # noqa: E501 'delete_requested_at': 'delete_requested_at', # noqa: E501 } @@ -192,7 +192,7 @@ class Job(ModelComposed): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 - submit_as_paused (bool): Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. . [optional] # noqa: E501 + initial_status (str): Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. . [optional] # noqa: E501 delete_requested_at (datetime): If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. . [optional] # noqa: E501 """ @@ -308,7 +308,7 @@ class Job(ModelComposed): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 - submit_as_paused (bool): Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. . [optional] # noqa: E501 + initial_status (str): Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. . [optional] # noqa: E501 delete_requested_at (datetime): If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. . [optional] # noqa: E501 """ diff --git a/addon/flamenco/manager/model/submitted_job.py b/addon/flamenco/manager/model/submitted_job.py index 3a195eb0..7e2a1a60 100644 --- a/addon/flamenco/manager/model/submitted_job.py +++ b/addon/flamenco/manager/model/submitted_job.py @@ -100,7 +100,7 @@ class SubmittedJob(ModelNormal): 'metadata': (JobMetadata,), # noqa: E501 'storage': (JobStorageInfo,), # noqa: E501 'worker_tag': (str,), # noqa: E501 - 'submit_as_paused': (bool,), # noqa: E501 + 'initial_status': (str,), # noqa: E501 } @cached_property @@ -118,7 +118,7 @@ class SubmittedJob(ModelNormal): 'metadata': 'metadata', # noqa: E501 'storage': 'storage', # noqa: E501 'worker_tag': 'worker_tag', # noqa: E501 - 'submit_as_paused': 'submit_as_paused', # noqa: E501 + 'initial_status': 'initial_status', # noqa: E501 } read_only_vars = { @@ -173,7 +173,7 @@ class SubmittedJob(ModelNormal): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 - submit_as_paused (bool): Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. . [optional] # noqa: E501 + initial_status (str): Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. . [optional] # noqa: E501 """ priority = kwargs.get('priority', 50) @@ -271,7 +271,7 @@ class SubmittedJob(ModelNormal): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 - submit_as_paused (bool): Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. . [optional] # noqa: E501 + initial_status (str): Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. . [optional] # noqa: E501 """ priority = kwargs.get('priority', 50) diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index 071828d9..1cd6879d 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -18,235 +18,235 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/api/openapi_types.gen.go b/pkg/api/openapi_types.gen.go index 4e9e990f..badcbcf4 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -702,6 +702,9 @@ type SocketIOSubscriptionType string // Job definition submitted to Flamenco. type SubmittedJob struct { + // Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. + InitialStatus *string `json:"initial_status,omitempty"` + // Arbitrary metadata strings. More complex structures can be modeled by using `a.b.c` notation for the key. Metadata *JobMetadata `json:"metadata,omitempty"` Name string `json:"name"` @@ -711,9 +714,6 @@ type SubmittedJob struct { // Storage info of a job, which Flamenco can use to remove job-related files when necessary. Storage *JobStorageInfo `json:"storage,omitempty"` - // Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. - SubmitAsPaused *bool `json:"submit_as_paused,omitempty"` - // Operating system of the submitter. This is used to recognise two-way variables. This should be a lower-case version of the platform, like "linux", "windows", "darwin", "openbsd", etc. Should be ompatible with Go's `runtime.GOOS`; run `go tool dist list` to get a list of possible platforms. // As a special case, the platform "manager" can be given, which will be interpreted as "the Manager's platform". This is mostly to make test/debug scripts easier, as they can use a static document on all platforms. SubmitterPlatform string `json:"submitter_platform"` diff --git a/web/app/src/manager-api/model/Job.js b/web/app/src/manager-api/model/Job.js index 79ae10b6..248a9a58 100644 --- a/web/app/src/manager-api/model/Job.js +++ b/web/app/src/manager-api/model/Job.js @@ -100,8 +100,8 @@ class Job { if (data.hasOwnProperty('worker_tag')) { obj['worker_tag'] = ApiClient.convertToType(data['worker_tag'], 'String'); } - if (data.hasOwnProperty('submit_as_paused')) { - obj['submit_as_paused'] = ApiClient.convertToType(data['submit_as_paused'], 'Boolean'); + if (data.hasOwnProperty('initial_status')) { + obj['initial_status'] = ApiClient.convertToType(data['initial_status'], 'String'); } if (data.hasOwnProperty('id')) { obj['id'] = ApiClient.convertToType(data['id'], 'String'); @@ -179,10 +179,10 @@ Job.prototype['storage'] = undefined; Job.prototype['worker_tag'] = undefined; /** - * Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. - * @member {Boolean} submit_as_paused + * Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. + * @member {String} initial_status */ -Job.prototype['submit_as_paused'] = undefined; +Job.prototype['initial_status'] = undefined; /** * UUID of the Job @@ -263,10 +263,10 @@ SubmittedJob.prototype['storage'] = undefined; */ SubmittedJob.prototype['worker_tag'] = undefined; /** - * Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. - * @member {Boolean} submit_as_paused + * Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. + * @member {String} initial_status */ -SubmittedJob.prototype['submit_as_paused'] = undefined; +SubmittedJob.prototype['initial_status'] = undefined; // Implement JobAllOf interface: /** * UUID of the Job diff --git a/web/app/src/manager-api/model/SubmittedJob.js b/web/app/src/manager-api/model/SubmittedJob.js index 0fe0274f..7e347810 100644 --- a/web/app/src/manager-api/model/SubmittedJob.js +++ b/web/app/src/manager-api/model/SubmittedJob.js @@ -84,8 +84,8 @@ class SubmittedJob { if (data.hasOwnProperty('worker_tag')) { obj['worker_tag'] = ApiClient.convertToType(data['worker_tag'], 'String'); } - if (data.hasOwnProperty('submit_as_paused')) { - obj['submit_as_paused'] = ApiClient.convertToType(data['submit_as_paused'], 'Boolean'); + if (data.hasOwnProperty('initial_status')) { + obj['initial_status'] = ApiClient.convertToType(data['initial_status'], 'String'); } } return obj; @@ -145,10 +145,10 @@ SubmittedJob.prototype['storage'] = undefined; SubmittedJob.prototype['worker_tag'] = undefined; /** - * Whether to submit this job as paused. This is useful for jobs that need manual intervention before they can be started. - * @member {Boolean} submit_as_paused + * Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. + * @member {String} initial_status */ -SubmittedJob.prototype['submit_as_paused'] = undefined; +SubmittedJob.prototype['initial_status'] = undefined; -- 2.30.2 From 578ffb1446ff67cbc68a0194b1976a0fc462038c Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 22 Jun 2024 09:15:00 -0400 Subject: [PATCH 27/29] OAPI: make initial_status refer to existing JobStatus definition --- pkg/api/flamenco-openapi.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pkg/api/flamenco-openapi.yaml b/pkg/api/flamenco-openapi.yaml index 127c060c..ad34d38d 100644 --- a/pkg/api/flamenco-openapi.yaml +++ b/pkg/api/flamenco-openapi.yaml @@ -1867,11 +1867,7 @@ components: Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. - "initial_status": - type: string - description: > - Initial status of the job. If not given, the job will start in the - 'queued' status. Currently only 'queued' and 'paused' are supported. + "initial_status": { $ref: "#/components/schemas/JobStatus" } required: [name, type, priority, submitter_platform] example: type: "simple-blender-render" -- 2.30.2 From 9aecbbb95c677476693f846d08d17af7d50e53fc Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 22 Jun 2024 09:15:23 -0400 Subject: [PATCH 28/29] OAPI: Regenerate code --- addon/flamenco/manager/docs/Job.md | 2 +- addon/flamenco/manager/docs/JobsApi.md | 4 +- addon/flamenco/manager/docs/SubmittedJob.md | 2 +- addon/flamenco/manager/model/job.py | 6 +- addon/flamenco/manager/model/submitted_job.py | 8 +- pkg/api/openapi_spec.gen.go | 457 +++++++++--------- pkg/api/openapi_types.gen.go | 3 +- web/app/src/manager-api/model/Job.js | 8 +- web/app/src/manager-api/model/SubmittedJob.js | 6 +- 9 files changed, 247 insertions(+), 249 deletions(-) diff --git a/addon/flamenco/manager/docs/Job.md b/addon/flamenco/manager/docs/Job.md index 1b58f2e4..90adc392 100644 --- a/addon/flamenco/manager/docs/Job.md +++ b/addon/flamenco/manager/docs/Job.md @@ -18,7 +18,7 @@ Name | Type | Description | Notes **metadata** | [**JobMetadata**](JobMetadata.md) | | [optional] **storage** | [**JobStorageInfo**](JobStorageInfo.md) | | [optional] **worker_tag** | **str** | Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [optional] -**initial_status** | **str** | Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. | [optional] +**initial_status** | [**JobStatus**](JobStatus.md) | | [optional] **delete_requested_at** | **datetime** | If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/addon/flamenco/manager/docs/JobsApi.md b/addon/flamenco/manager/docs/JobsApi.md index 6e100a0d..d97474b1 100644 --- a/addon/flamenco/manager/docs/JobsApi.md +++ b/addon/flamenco/manager/docs/JobsApi.md @@ -1296,7 +1296,7 @@ with flamenco.manager.ApiClient() as api_client: shaman_checkout_id="shaman_checkout_id_example", ), worker_tag="worker_tag_example", - initial_status="initial_status_example", + initial_status=JobStatus("active"), ) # SubmittedJob | Job to submit # example passing only required values which don't have defaults set @@ -1379,7 +1379,7 @@ with flamenco.manager.ApiClient() as api_client: shaman_checkout_id="shaman_checkout_id_example", ), worker_tag="worker_tag_example", - initial_status="initial_status_example", + initial_status=JobStatus("active"), ) # SubmittedJob | Job to check # example passing only required values which don't have defaults set diff --git a/addon/flamenco/manager/docs/SubmittedJob.md b/addon/flamenco/manager/docs/SubmittedJob.md index 25bebbdd..be6b9e93 100644 --- a/addon/flamenco/manager/docs/SubmittedJob.md +++ b/addon/flamenco/manager/docs/SubmittedJob.md @@ -14,7 +14,7 @@ Name | Type | Description | Notes **metadata** | [**JobMetadata**](JobMetadata.md) | | [optional] **storage** | [**JobStorageInfo**](JobStorageInfo.md) | | [optional] **worker_tag** | **str** | Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. | [optional] -**initial_status** | **str** | Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. | [optional] +**initial_status** | [**JobStatus**](JobStatus.md) | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/addon/flamenco/manager/model/job.py b/addon/flamenco/manager/model/job.py index 8f70bc71..33073a0f 100644 --- a/addon/flamenco/manager/model/job.py +++ b/addon/flamenco/manager/model/job.py @@ -111,7 +111,7 @@ class Job(ModelComposed): 'metadata': (JobMetadata,), # noqa: E501 'storage': (JobStorageInfo,), # noqa: E501 'worker_tag': (str,), # noqa: E501 - 'initial_status': (str,), # noqa: E501 + 'initial_status': (JobStatus,), # noqa: E501 'delete_requested_at': (datetime,), # noqa: E501 } @@ -192,7 +192,7 @@ class Job(ModelComposed): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 - initial_status (str): Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. . [optional] # noqa: E501 + initial_status (JobStatus): [optional] # noqa: E501 delete_requested_at (datetime): If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. . [optional] # noqa: E501 """ @@ -308,7 +308,7 @@ class Job(ModelComposed): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 - initial_status (str): Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. . [optional] # noqa: E501 + initial_status (JobStatus): [optional] # noqa: E501 delete_requested_at (datetime): If job deletion was requested, this is the timestamp at which that request was stored on Flamenco Manager. . [optional] # noqa: E501 """ diff --git a/addon/flamenco/manager/model/submitted_job.py b/addon/flamenco/manager/model/submitted_job.py index 7e2a1a60..8680929b 100644 --- a/addon/flamenco/manager/model/submitted_job.py +++ b/addon/flamenco/manager/model/submitted_job.py @@ -32,9 +32,11 @@ from flamenco.manager.exceptions import ApiAttributeError def lazy_import(): from flamenco.manager.model.job_metadata import JobMetadata from flamenco.manager.model.job_settings import JobSettings + from flamenco.manager.model.job_status import JobStatus from flamenco.manager.model.job_storage_info import JobStorageInfo globals()['JobMetadata'] = JobMetadata globals()['JobSettings'] = JobSettings + globals()['JobStatus'] = JobStatus globals()['JobStorageInfo'] = JobStorageInfo @@ -100,7 +102,7 @@ class SubmittedJob(ModelNormal): 'metadata': (JobMetadata,), # noqa: E501 'storage': (JobStorageInfo,), # noqa: E501 'worker_tag': (str,), # noqa: E501 - 'initial_status': (str,), # noqa: E501 + 'initial_status': (JobStatus,), # noqa: E501 } @cached_property @@ -173,7 +175,7 @@ class SubmittedJob(ModelNormal): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 - initial_status (str): Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. . [optional] # noqa: E501 + initial_status (JobStatus): [optional] # noqa: E501 """ priority = kwargs.get('priority', 50) @@ -271,7 +273,7 @@ class SubmittedJob(ModelNormal): metadata (JobMetadata): [optional] # noqa: E501 storage (JobStorageInfo): [optional] # noqa: E501 worker_tag (str): Worker tag that should execute this job. When a tag ID is given, only Workers in that tag will be scheduled to work on it. If empty or ommitted, all workers can work on this job. . [optional] # noqa: E501 - initial_status (str): Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. . [optional] # noqa: E501 + initial_status (JobStatus): [optional] # noqa: E501 """ priority = kwargs.get('priority', 50) diff --git a/pkg/api/openapi_spec.gen.go b/pkg/api/openapi_spec.gen.go index 1cd6879d..27612053 100644 --- a/pkg/api/openapi_spec.gen.go +++ b/pkg/api/openapi_spec.gen.go @@ -18,235 +18,234 @@ import ( // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/pkg/api/openapi_types.gen.go b/pkg/api/openapi_types.gen.go index badcbcf4..9ca88b4c 100644 --- a/pkg/api/openapi_types.gen.go +++ b/pkg/api/openapi_types.gen.go @@ -702,8 +702,7 @@ type SocketIOSubscriptionType string // Job definition submitted to Flamenco. type SubmittedJob struct { - // Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. - InitialStatus *string `json:"initial_status,omitempty"` + InitialStatus *JobStatus `json:"initial_status,omitempty"` // Arbitrary metadata strings. More complex structures can be modeled by using `a.b.c` notation for the key. Metadata *JobMetadata `json:"metadata,omitempty"` diff --git a/web/app/src/manager-api/model/Job.js b/web/app/src/manager-api/model/Job.js index 248a9a58..85898a29 100644 --- a/web/app/src/manager-api/model/Job.js +++ b/web/app/src/manager-api/model/Job.js @@ -101,7 +101,7 @@ class Job { obj['worker_tag'] = ApiClient.convertToType(data['worker_tag'], 'String'); } if (data.hasOwnProperty('initial_status')) { - obj['initial_status'] = ApiClient.convertToType(data['initial_status'], 'String'); + obj['initial_status'] = JobStatus.constructFromObject(data['initial_status']); } if (data.hasOwnProperty('id')) { obj['id'] = ApiClient.convertToType(data['id'], 'String'); @@ -179,8 +179,7 @@ Job.prototype['storage'] = undefined; Job.prototype['worker_tag'] = undefined; /** - * Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. - * @member {String} initial_status + * @member {module:model/JobStatus} initial_status */ Job.prototype['initial_status'] = undefined; @@ -263,8 +262,7 @@ SubmittedJob.prototype['storage'] = undefined; */ SubmittedJob.prototype['worker_tag'] = undefined; /** - * Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. - * @member {String} initial_status + * @member {module:model/JobStatus} initial_status */ SubmittedJob.prototype['initial_status'] = undefined; // Implement JobAllOf interface: diff --git a/web/app/src/manager-api/model/SubmittedJob.js b/web/app/src/manager-api/model/SubmittedJob.js index 7e347810..f86ab8cf 100644 --- a/web/app/src/manager-api/model/SubmittedJob.js +++ b/web/app/src/manager-api/model/SubmittedJob.js @@ -12,6 +12,7 @@ */ import ApiClient from '../ApiClient'; +import JobStatus from './JobStatus'; import JobStorageInfo from './JobStorageInfo'; /** @@ -85,7 +86,7 @@ class SubmittedJob { obj['worker_tag'] = ApiClient.convertToType(data['worker_tag'], 'String'); } if (data.hasOwnProperty('initial_status')) { - obj['initial_status'] = ApiClient.convertToType(data['initial_status'], 'String'); + obj['initial_status'] = JobStatus.constructFromObject(data['initial_status']); } } return obj; @@ -145,8 +146,7 @@ SubmittedJob.prototype['storage'] = undefined; SubmittedJob.prototype['worker_tag'] = undefined; /** - * Initial status of the job. If not given, the job will start in the 'queued' status. Currently only 'queued' and 'paused' are supported. - * @member {String} initial_status + * @member {module:model/JobStatus} initial_status */ SubmittedJob.prototype['initial_status'] = undefined; -- 2.30.2 From e6bc9cd0610fe2f160a414b2e200c19877dfb38d Mon Sep 17 00:00:00 2001 From: David Zhang Date: Sat, 22 Jun 2024 10:39:11 -0400 Subject: [PATCH 29/29] Manager: backend for submitting job with initial status --- debug-job-echo.sh | 3 ++- internal/manager/api_impl/jobs.go | 4 +++- internal/manager/job_compilers/job_compilers.go | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/debug-job-echo.sh b/debug-job-echo.sh index 55477dba..8a933a64 100755 --- a/debug-job-echo.sh +++ b/debug-job-echo.sh @@ -18,5 +18,6 @@ curl -X 'POST' \ "message": "Blender is {blender}" }, "type": "echo-sleep-test", - "submitter_platform": "manager" + "submitter_platform": "manager", + "initial_status": "paused" }' diff --git a/internal/manager/api_impl/jobs.go b/internal/manager/api_impl/jobs.go index 92d2aad9..09eeafb7 100644 --- a/internal/manager/api_impl/jobs.go +++ b/internal/manager/api_impl/jobs.go @@ -92,7 +92,9 @@ func (f *Flamenco) SubmitJob(e echo.Context) error { logger = logger.With().Str("job_id", authoredJob.JobID).Logger() // TODO: check whether this job should be queued immediately or start paused. - authoredJob.Status = api.JobStatusQueued + if authoredJob.Status == api.JobStatusUnderConstruction { + authoredJob.Status = api.JobStatusQueued + } if err := f.persist.StoreAuthoredJob(ctx, *authoredJob); err != nil { logger.Error().Err(err).Msg("error persisting job in database") diff --git a/internal/manager/job_compilers/job_compilers.go b/internal/manager/job_compilers/job_compilers.go index db7e2520..244a11d4 100644 --- a/internal/manager/job_compilers/job_compilers.go +++ b/internal/manager/job_compilers/job_compilers.go @@ -131,6 +131,10 @@ func (s *Service) Compile(ctx context.Context, sj api.SubmittedJob) (*AuthoredJo aj.WorkerTagUUID = *sj.WorkerTag } + if sj.InitialStatus != nil { + aj.Status = *sj.InitialStatus + } + compiler, err := vm.getCompileJob() if err != nil { return nil, err @@ -144,6 +148,7 @@ func (s *Service) Compile(ctx context.Context, sj api.SubmittedJob) (*AuthoredJo Str("name", aj.Name). Str("jobtype", aj.JobType). Str("job", aj.JobID). + Str("status", string(aj.Status)). Msg("job compiled") return &aj, nil -- 2.30.2