Manager: allow setup to finish without Blender #104306

Manually merged
Sybren A. Stüvel merged 34 commits from abelli/flamenco:issue100195 into main 2024-09-09 11:22:42 +02:00
7 changed files with 78 additions and 33 deletions
Showing only changes of commit 3bc6404280 - Show all commits

2
go.mod
View File

@ -1,6 +1,6 @@
module projects.blender.org/studio/flamenco
go 1.22.3
go 1.22.4
require (
github.com/adrg/xdg v0.4.0

View File

@ -4,8 +4,10 @@ package persistence
import (
"context"
"database/sql"
"errors"
"gorm.io/gorm/clause"
"projects.blender.org/studio/flamenco/internal/manager/persistence/sqlc"
)
// LastRendered only has one entry in its database table, to indicate the job
@ -19,30 +21,32 @@ type LastRendered struct {
// SetLastRendered sets this job as the one with the most recent rendered image.
func (db *DB) SetLastRendered(ctx context.Context, j *Job) error {
render := LastRendered{
// Always use the same database ID to ensure a single entry.
Model: Model{ID: uint(1)},
JobID: j.ID,
Job: j,
queries, err := db.queries()
if err != nil {
return err
}
tx := db.gormDB.
WithContext(ctx).
Clauses(clause.OnConflict{UpdateAll: true}).
Create(&render)
return tx.Error
now := db.now()
return queries.SetLastRendered(ctx, sqlc.SetLastRenderedParams{
CreatedAt: now.Time,
UpdatedAt: now,
JobID: int64(j.ID),
})
}
// GetLastRendered returns the UUID of the job with the most recent rendered image.
func (db *DB) GetLastRenderedJobUUID(ctx context.Context) (string, error) {
job := Job{}
tx := db.gormDB.WithContext(ctx).
Joins("inner join last_rendereds LR on jobs.id = LR.job_id").
Select("uuid").
Find(&job)
if tx.Error != nil {
return "", jobError(tx.Error, "finding job with most rencent render")
queries, err := db.queries()
if err != nil {
return "", err
}
return job.UUID, nil
jobUUID, err := queries.GetLastRenderedJobUUID(ctx)
if errors.Is(err, sql.ErrNoRows) {
return "", nil
}
if err != nil {
return "", jobError(err, "finding job with most rencent render")
}
return jobUUID, nil
}

View File

@ -1,7 +1,4 @@
-- Jobs / Tasks queries
--
-- name: CreateJob :exec
INSERT INTO jobs (
created_at,
@ -190,3 +187,19 @@ WHERE task_id in (SELECT id FROM tasks WHERE job_id=@job_id);
SELECT sqlc.embed(workers) FROM workers
INNER JOIN task_failures TF on TF.worker_id=workers.id
WHERE TF.task_id=@task_id;
-- name: SetLastRendered :exec
-- Set the 'last rendered' job info.
--
-- Note that the use of ?2 and ?3 in the SQL is not desirable, and should be
-- replaced with @updated_at and @job_id as soon as sqlc issue #3334 is fixed.
-- See https://github.com/sqlc-dev/sqlc/issues/3334 for more info.
INSERT INTO last_rendereds (id, created_at, updated_at, job_id)
VALUES (1, @created_at, @updated_at, @job_id)
ON CONFLICT DO UPDATE
SET updated_at=?2, job_id=?3
WHERE id=1;
-- name: GetLastRenderedJobUUID :one
SELECT uuid FROM jobs
INNER JOIN last_rendereds LR ON jobs.id = LR.job_id;

View File

@ -64,7 +64,6 @@ func (q *Queries) CountWorkersFailingTask(ctx context.Context, taskID int64) (in
}
const createJob = `-- name: CreateJob :exec
INSERT INTO jobs (
created_at,
uuid,
@ -93,7 +92,6 @@ type CreateJobParams struct {
StorageShamanCheckoutID string
}
// Jobs / Tasks queries
func (q *Queries) CreateJob(ctx context.Context, arg CreateJobParams) error {
_, err := q.db.ExecContext(ctx, createJob,
arg.CreatedAt,
@ -623,6 +621,18 @@ func (q *Queries) FetchTasksOfWorkerInStatusOfJob(ctx context.Context, arg Fetch
return items, nil
}
const getLastRenderedJobUUID = `-- name: GetLastRenderedJobUUID :one
SELECT uuid FROM jobs
INNER JOIN last_rendereds LR ON jobs.id = LR.job_id
`
func (q *Queries) GetLastRenderedJobUUID(ctx context.Context) (string, error) {
row := q.db.QueryRowContext(ctx, getLastRenderedJobUUID)
var uuid string
err := row.Scan(&uuid)
return uuid, err
}
const jobCountTaskStatuses = `-- name: JobCountTaskStatuses :many
SELECT status, count(*) as num_tasks FROM tasks
WHERE job_id = ?1
@ -771,6 +781,30 @@ func (q *Queries) SaveJobStorageInfo(ctx context.Context, arg SaveJobStorageInfo
return err
}
const setLastRendered = `-- name: SetLastRendered :exec
INSERT INTO last_rendereds (id, created_at, updated_at, job_id)
VALUES (1, ?1, ?2, ?3)
ON CONFLICT DO UPDATE
SET updated_at=?2, job_id=?3
WHERE id=1
`
type SetLastRenderedParams struct {
CreatedAt time.Time
UpdatedAt sql.NullTime
JobID int64
}
// Set the 'last rendered' job info.
//
// Note that the use of ?2 and ?3 in the SQL is not desirable, and should be
// replaced with @updated_at and @job_id as soon as sqlc issue #3334 is fixed.
// See https://github.com/sqlc-dev/sqlc/issues/3334 for more info.
func (q *Queries) SetLastRendered(ctx context.Context, arg SetLastRenderedParams) error {
_, err := q.db.ExecContext(ctx, setLastRendered, arg.CreatedAt, arg.UpdatedAt, arg.JobID)
return err
}
const taskAssignToWorker = `-- name: TaskAssignToWorker :exec
UPDATE tasks SET
updated_at = ?1,

View File

@ -1,7 +1,4 @@
-- Worker queries
--
-- name: CreateWorker :one
INSERT INTO workers (
created_at,

View File

@ -27,7 +27,6 @@ func (q *Queries) AddWorkerTagMembership(ctx context.Context, arg AddWorkerTagMe
}
const createWorker = `-- name: CreateWorker :one
INSERT INTO workers (
created_at,
uuid,
@ -79,8 +78,6 @@ type CreateWorkerParams struct {
CanRestart bool
}
// Worker queries
//
func (q *Queries) CreateWorker(ctx context.Context, arg CreateWorkerParams) (int64, error) {
row := q.db.QueryRowContext(ctx, createWorker,
arg.CreatedAt,

View File

@ -221,7 +221,7 @@ func TestTaskStatusChangeCancelSingleTaskWithOtherFailed(t *testing.T) {
mocks.expectSaveJobWithStatus(t, job, api.JobStatusCanceled)
mocks.expectBroadcastJobChange(task1.Job, api.JobStatusCancelRequested, api.JobStatusCanceled)
// The paused task just stays paused, so don't expectBroadcastTaskChange(task3).
// The canceled task just stays canceled, so don't expectBroadcastTaskChange(task3).
require.NoError(t, sm.TaskStatusChange(ctx, task1, api.TaskStatusCanceled))
}