Skip to content

Commit e825973

Browse files
heschigopherbot
authored andcommitted
internal/workflow: clarify ownership
For golang/go#48523. Change-Id: Ie55cdf3c90687d065fb1b81d0a9f97a81d6ffd1f Reviewed-on: https://go-review.googlesource.com/c/build/+/423036 Reviewed-by: Jenny Rakoczy <[email protected]> Auto-Submit: Heschi Kreinick <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Heschi Kreinick <[email protected]>
1 parent ac2bd83 commit e825973

File tree

1 file changed

+26
-24
lines changed

1 file changed

+26
-24
lines changed

Diff for: internal/workflow/workflow.go

+26-24
Original file line numberDiff line numberDiff line change
@@ -467,16 +467,20 @@ func (tr *taskResult[T]) dependencies() []*taskDefinition {
467467
// A Workflow is an instantiated workflow instance, ready to run.
468468
type Workflow struct {
469469
ID uuid.UUID
470-
def *Definition
471470
params map[string]interface{}
472471
retryCommands chan retryCommand
473472

473+
// Notes on ownership and concurrency:
474+
// The taskDefinitions used below are immutable. Everything else should be
475+
// treated as mutable, used only in the Run goroutine, and never published
476+
// to a background goroutine.
477+
478+
def *Definition
474479
tasks map[*taskDefinition]*taskState
475480
}
476481

477482
type taskState struct {
478483
def *taskDefinition
479-
w *Workflow
480484
started bool
481485
finished bool
482486
result interface{}
@@ -485,19 +489,6 @@ type taskState struct {
485489
retryCount int
486490
}
487491

488-
func (t *taskState) args() ([]reflect.Value, bool) {
489-
for _, dep := range t.def.deps {
490-
if depState, ok := t.w.tasks[dep]; !ok || !depState.finished || depState.err != nil {
491-
return nil, false
492-
}
493-
}
494-
var args []reflect.Value
495-
for _, v := range t.def.args {
496-
args = append(args, v.value(t.w))
497-
}
498-
return args, true
499-
}
500-
501492
func (t *taskState) toExported() *TaskState {
502493
state := &TaskState{
503494
Name: t.def.name,
@@ -526,7 +517,7 @@ func Start(def *Definition, params map[string]interface{}) (*Workflow, error) {
526517
return nil, err
527518
}
528519
for _, taskDef := range def.tasks {
529-
w.tasks[taskDef] = &taskState{def: taskDef, w: w}
520+
w.tasks[taskDef] = &taskState{def: taskDef}
530521
}
531522
return w, nil
532523
}
@@ -592,7 +583,6 @@ func Resume(def *Definition, state *WorkflowState, taskStates map[string]*TaskSt
592583
}
593584
state := &taskState{
594585
def: taskDef,
595-
w: w,
596586
started: tState.Finished, // Can't resume tasks, so either it's new or done.
597587
finished: tState.Finished,
598588
serializedResult: tState.SerializedResult,
@@ -661,15 +651,15 @@ func (w *Workflow) Run(ctx context.Context, listener Listener) (map[string]inter
661651
if task.started {
662652
continue
663653
}
664-
in, ready := task.args()
654+
args, ready := w.taskArgs(task.def)
665655
if !ready {
666656
continue
667657
}
668658
task.started = true
669659
running++
670660
listener.TaskStateChanged(w.ID, task.def.name, task.toExported())
671661
go func(task taskState) {
672-
stateChan <- w.runTask(ctx, listener, task, in)
662+
stateChan <- runTask(ctx, w.ID, listener, task, args)
673663
}(*task)
674664
}
675665
}
@@ -699,7 +689,7 @@ func (w *Workflow) Run(ctx context.Context, listener Listener) (map[string]inter
699689
break
700690
}
701691
listener.Logger(w.ID, def.name).Printf("Manual retry requested")
702-
stateChan <- taskState{def: def, w: w}
692+
stateChan <- taskState{def: def}
703693
retry.reply <- nil
704694
// Don't get stuck when cancellation comes in after all tasks have
705695
// finished, but also don't busy wait if something's still running.
@@ -709,20 +699,33 @@ func (w *Workflow) Run(ctx context.Context, listener Listener) (map[string]inter
709699
}
710700
}
711701

702+
func (w *Workflow) taskArgs(def *taskDefinition) ([]reflect.Value, bool) {
703+
for _, dep := range def.deps {
704+
if depState, ok := w.tasks[dep]; !ok || !depState.finished || depState.err != nil {
705+
return nil, false
706+
}
707+
}
708+
var args []reflect.Value
709+
for _, v := range def.args {
710+
args = append(args, v.value(w))
711+
}
712+
return args, true
713+
}
714+
712715
// Maximum number of retries. This could be a workflow property.
713716
var MaxRetries = 3
714717

715718
var WatchdogDelay = 10 * time.Minute
716719

717-
func (w *Workflow) runTask(ctx context.Context, listener Listener, state taskState, args []reflect.Value) taskState {
720+
func runTask(ctx context.Context, workflowID uuid.UUID, listener Listener, state taskState, args []reflect.Value) taskState {
718721
ctx, cancel := context.WithCancel(ctx)
719722
defer cancel()
720723

721724
tctx := &TaskContext{
722725
Context: ctx,
723-
Logger: listener.Logger(w.ID, state.def.name),
726+
Logger: listener.Logger(workflowID, state.def.name),
724727
TaskName: state.def.name,
725-
WorkflowID: w.ID,
728+
WorkflowID: workflowID,
726729
watchdogTimer: time.AfterFunc(WatchdogDelay, cancel),
727730
}
728731

@@ -750,7 +753,6 @@ func (w *Workflow) runTask(ctx context.Context, listener Listener, state taskSta
750753
tctx.Printf("task failed, will retry (%v of %v): %v", state.retryCount+1, MaxRetries, state.err)
751754
state = taskState{
752755
def: state.def,
753-
w: state.w,
754756
retryCount: state.retryCount + 1,
755757
}
756758
}

0 commit comments

Comments
 (0)