Resolved Task Limit error in Flamenco Manager #104201 #104205

3 changed files with 69 additions and 5 deletions

View File

@ -208,11 +208,19 @@ func (db *DB) StoreAuthoredJob(ctx context.Context, authoredJob job_compilers.Au
} }
deps[i] = depTask deps[i] = depTask
} }
dependenciesbatchsize := 1000
dbTask.Dependencies = deps for j := 0; j < len(deps); j += dependenciesbatchsize {
subQuery := tx.Model(dbTask).Updates(Task{Dependencies: deps}) end := j + dependenciesbatchsize
if subQuery.Error != nil { if end > len(deps) {
return taskError(subQuery.Error, "unable to store dependencies of task %q", authoredTask.UUID) end = len(deps)
}
currentDeps := deps[j:end]
dbTask.Dependencies = currentDeps
tx.Model(&dbTask).Where("UUID = ?", dbTask.UUID)
subQuery := tx.Model(dbTask).Updates(Task{Dependencies: currentDeps})
if subQuery.Error != nil {
return taskError(subQuery.Error, "error with storing dependencies of task %q issue exists in dependencies %d to %d", authoredTask.UUID, j, end)
}
} }
} }

View File

@ -258,6 +258,21 @@ func TestCountTasksOfJobInStatus(t *testing.T) {
assert.Equal(t, 3, numTotal) assert.Equal(t, 3, numTotal)
} }
func TestCheckIfJobsHoldLargeNumOfTasks(t *testing.T) {
if testing.Short() {
t.Skip("Skipping test in short mode")
}
numtasks := 3500
ctx, close, db, job, _ := jobTasksTestFixturesWithTaskNum(t, numtasks)
defer close()
numQueued, numTotal, err := db.CountTasksOfJobInStatus(ctx, job, api.TaskStatusQueued)
assert.NoError(t, err)
assert.Equal(t, numtasks, numQueued)
assert.Equal(t, numtasks, numTotal)
}
func TestFetchJobsInStatus(t *testing.T) { func TestFetchJobsInStatus(t *testing.T) {
ctx, close, db, job1, _ := jobTasksTestFixtures(t) ctx, close, db, job1, _ := jobTasksTestFixtures(t)
defer close() defer close()
@ -594,6 +609,36 @@ func createTestAuthoredJobWithTasks() job_compilers.AuthoredJob {
return createTestAuthoredJob("263fd47e-b9f8-4637-b726-fd7e47ecfdae", task1, task2, task3) return createTestAuthoredJob("263fd47e-b9f8-4637-b726-fd7e47ecfdae", task1, task2, task3)

Function documentation in Go should start with the function name, so in this case:

// createTestAuthoredJobWithNumTasks creates a Job with a specified number of tasks
func createTestAuthoredJobWithNumTasks(numTasks int) job_compilers.AuthoredJob {

In this particular case, though, I think the comment can be removed as it just repeats the same info that's already in the function name.

Function documentation in Go should start with the function name, so in this case: ```go // createTestAuthoredJobWithNumTasks creates a Job with a specified number of tasks func createTestAuthoredJobWithNumTasks(numTasks int) job_compilers.AuthoredJob { ``` In this particular case, though, I think the comment can be removed as it just repeats the same info that's already in the function name.
} }

Please configure your IDE to use auto-formatting, or run go fmt ./... before committing.

Please configure your IDE to use auto-formatting, or run `go fmt ./...` before committing.
func createTestAuthoredJobWithNumTasks(numTasks int) job_compilers.AuthoredJob {
//Generates all of the render jobs
prevtasks := make([]*job_compilers.AuthoredTask, 0)
for i := 0; i < numTasks-1; i++ {
currtask := job_compilers.AuthoredTask{

Just for consistency with the name, this should be Type: "blender-render".

Just for consistency with the name, this should be `Type: "blender-render"`.
Name: "render-" + fmt.Sprintf("%d", i),
Type: "blender-render",
UUID: uuid.New(),
Commands: []job_compilers.AuthoredCommand{},
}
prevtasks = append(prevtasks, &currtask)
}
// Generates the preview video command with Dependencies
videoJob := job_compilers.AuthoredTask{
Name: "preview-video",
Type: "ffmpeg",
UUID: uuid.New(),
Commands: []job_compilers.AuthoredCommand{},
Dependencies: prevtasks,
}
// convert pointers to values and generate job
taskvalues := make([]job_compilers.AuthoredTask, len(prevtasks))
for i, ptr := range prevtasks {
taskvalues[i] = *ptr
}
taskvalues = append(taskvalues, videoJob)
return createTestAuthoredJob(uuid.New(), taskvalues...)
}
func createTestAuthoredJob(jobID string, tasks ...job_compilers.AuthoredTask) job_compilers.AuthoredJob { func createTestAuthoredJob(jobID string, tasks ...job_compilers.AuthoredTask) job_compilers.AuthoredJob {
job := job_compilers.AuthoredJob{ job := job_compilers.AuthoredJob{
JobID: jobID, JobID: jobID,
@ -676,6 +721,16 @@ func jobTasksTestFixtures(t *testing.T) (context.Context, context.CancelFunc, *D
return ctx, cancel, db, dbJob, authoredJob return ctx, cancel, db, dbJob, authoredJob
} }
// This created Test Jobs using the new function createTestAuthoredJobWithNumTasks so that you can set the number of tasks
func jobTasksTestFixturesWithTaskNum(t *testing.T, numtasks int) (context.Context, context.CancelFunc, *DB, *Job, job_compilers.AuthoredJob) {
ctx, cancel, db := persistenceTestFixtures(t, schedulerTestTimeoutlong)
authoredJob := createTestAuthoredJobWithNumTasks(numtasks)
dbJob := persistAuthoredJob(t, ctx, db, authoredJob)
return ctx, cancel, db, dbJob, authoredJob
}
func createWorker(ctx context.Context, t *testing.T, db *DB, updaters ...func(*Worker)) *Worker { func createWorker(ctx context.Context, t *testing.T, db *DB, updaters ...func(*Worker)) *Worker {
w := Worker{ w := Worker{
UUID: "f0a123a9-ab05-4ce2-8577-94802cfe74a4", UUID: "f0a123a9-ab05-4ce2-8577-94802cfe74a4",

View File

@ -16,6 +16,7 @@ import (
) )
const schedulerTestTimeout = 100 * time.Millisecond const schedulerTestTimeout = 100 * time.Millisecond
const schedulerTestTimeoutlong = 5000 * time.Millisecond

This is a good idea, to have another timeout for this longer-running test.

To take it one step further, in TestCheckIfJobsHoldLargeNumOfTasks() you could add this code at the start of the function:

if testing.Short() {
    t.Skip("skipping test in short mode")
}

That way running go test -short will actually skip the test. It's not a necessity, but just a cherry on top. Up to you if you want to spend time on this, I'll accept the patch with or without this change.

This is a good idea, to have another timeout for this longer-running test. To take it one step further, in `TestCheckIfJobsHoldLargeNumOfTasks()` you could add this code at the start of the function: ```go if testing.Short() { t.Skip("skipping test in short mode") } ``` That way running `go test -short` will actually skip the test. It's not a necessity, but just a cherry on top. Up to you if you want to spend time on this, I'll accept the patch with or without this change.
func TestNoTasks(t *testing.T) { func TestNoTasks(t *testing.T) {
ctx, cancel, db := persistenceTestFixtures(t, schedulerTestTimeout) ctx, cancel, db := persistenceTestFixtures(t, schedulerTestTimeout)