internal/relui: log previous state when retrying tasks
This logs the task state and workflow state when retrying a task for a
workflow, so as not to lose history.
Eventually, we should store the full history for workflows and tasks.
Moves the transaction rollback to a defer, which is safe even if commit
or rollback is called first.
Fixes golang/go#53165
Change-Id: I6a9c42beb9352656b044dbe6e5adf6493d32873d
Reviewed-on: https://go-review.googlesource.com/c/build/+/411194
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Alex Rakoczy <alex@golang.org>
diff --git a/internal/relui/db/workflows.sql.go b/internal/relui/db/workflows.sql.go
index 11a780d..41e10a7 100644
--- a/internal/relui/db/workflows.sql.go
+++ b/internal/relui/db/workflows.sql.go
@@ -120,7 +120,8 @@
result = DEFAULT,
error = DEFAULT,
updated_at = $3
-WHERE workflow_id = $1 AND name = $2
+WHERE workflow_id = $1
+ AND name = $2
RETURNING workflow_id, name, finished, result, error, created_at, updated_at
`
@@ -147,9 +148,9 @@
const resetWorkflow = `-- name: ResetWorkflow :one
UPDATE workflows
-SET finished = false,
- output = DEFAULT,
- error = DEFAULT,
+SET finished = false,
+ output = DEFAULT,
+ error = DEFAULT,
updated_at = $2
WHERE id = $1
RETURNING id, params, name, created_at, updated_at, finished, output, error
@@ -176,6 +177,34 @@
return i, err
}
+const task = `-- name: Task :one
+SELECT tasks.workflow_id, tasks.name, tasks.finished, tasks.result, tasks.error, tasks.created_at, tasks.updated_at
+FROM tasks
+WHERE workflow_id = $1
+ AND name = $2
+LIMIT 1
+`
+
+type TaskParams struct {
+ WorkflowID uuid.UUID
+ Name string
+}
+
+func (q *Queries) Task(ctx context.Context, arg TaskParams) (Task, error) {
+ row := q.db.QueryRow(ctx, task, arg.WorkflowID, arg.Name)
+ var i Task
+ err := row.Scan(
+ &i.WorkflowID,
+ &i.Name,
+ &i.Finished,
+ &i.Result,
+ &i.Error,
+ &i.CreatedAt,
+ &i.UpdatedAt,
+ )
+ return i, err
+}
+
const taskLogs = `-- name: TaskLogs :many
SELECT task_logs.id, task_logs.workflow_id, task_logs.task_name, task_logs.body, task_logs.created_at, task_logs.updated_at
FROM task_logs
diff --git a/internal/relui/queries/workflows.sql b/internal/relui/queries/workflows.sql
index 4a21cac..755a7d9 100644
--- a/internal/relui/queries/workflows.sql
+++ b/internal/relui/queries/workflows.sql
@@ -45,6 +45,13 @@
WHERE workflow_id = $1
ORDER BY created_at;
+-- name: Task :one
+SELECT tasks.*
+FROM tasks
+WHERE workflow_id = $1
+ AND name = $2
+LIMIT 1;
+
-- name: CreateTaskLog :one
INSERT INTO task_logs (workflow_id, task_name, body)
VALUES ($1, $2, $3)
@@ -82,14 +89,15 @@
result = DEFAULT,
error = DEFAULT,
updated_at = $3
-WHERE workflow_id = $1 AND name = $2
+WHERE workflow_id = $1
+ AND name = $2
RETURNING *;
-- name: ResetWorkflow :one
UPDATE workflows
-SET finished = false,
- output = DEFAULT,
- error = DEFAULT,
+SET finished = false,
+ output = DEFAULT,
+ error = DEFAULT,
updated_at = $2
WHERE id = $1
RETURNING *;
diff --git a/internal/relui/web.go b/internal/relui/web.go
index 807ee0d..e946ac2 100644
--- a/internal/relui/web.go
+++ b/internal/relui/web.go
@@ -281,19 +281,27 @@
if err != nil {
return fmt.Errorf("tx.Begin(): %w", err)
}
- q := db.New(s.db)
- q = q.WithTx(tx)
+ defer tx.Rollback(ctx)
+ q := db.New(s.db).WithTx(tx)
+ wf, err := q.Workflow(ctx, id)
+ if err != nil {
+ return fmt.Errorf("q.Workflow: %w", err)
+ }
+ task, err := q.Task(ctx, db.TaskParams{WorkflowID: id, Name: name})
+ if err != nil {
+ return fmt.Errorf("q.Task: %w", err)
+ }
if _, err := q.ResetTask(ctx, db.ResetTaskParams{WorkflowID: id, Name: name, UpdatedAt: time.Now()}); err != nil {
- tx.Rollback(ctx)
return fmt.Errorf("q.ResetTask: %w", err)
}
if _, err := q.ResetWorkflow(ctx, db.ResetWorkflowParams{ID: id, UpdatedAt: time.Now()}); err != nil {
- tx.Rollback(ctx)
return fmt.Errorf("q.ResetWorkflow: %w", err)
}
if err := tx.Commit(ctx); err != nil {
- tx.Rollback(ctx)
return fmt.Errorf("tx.Commit: %w", err)
}
+ l := s.w.l.Logger(id, name)
+ l.Printf("task reset. Previous state: %#v", task)
+ l.Printf("workflow reset. Previous state: %#v", wf)
return nil
}