@@ -42,8 +42,7 @@ func NewJob(name string) *Job {
42
42
}
43
43
44
44
j .rootJob = & StepInfo [interface {}]{
45
- name : "[Start]" ,
46
- dependOn : []string {},
45
+ name : "[Start]" ,
47
46
task : asynctask .Start (context .Background (), func (fctx context.Context ) (* interface {}, error ) {
48
47
fmt .Println ("RootJob Added" )
49
48
// this will pause all steps from starting, until Start() method is called.
@@ -53,14 +52,14 @@ func NewJob(name string) *Job {
53
52
}),
54
53
}
55
54
56
- j .Steps [j .rootJob .Name ()] = j .rootJob
57
- j .stepsDag .Add (j .rootJob .Name ())
55
+ j .Steps [j .rootJob .GetName ()] = j .rootJob
56
+ j .stepsDag .Add (j .rootJob .GetName ())
58
57
59
58
return j
60
59
}
61
60
62
61
func InputParam [T any ](bCtx context.Context , j * Job , stepName string , value * T ) * StepInfo [T ] {
63
- step := newStepInfo [T ](stepName , [] string { j . rootJob . Name ()} )
62
+ step := newStepInfo [T ](stepName )
64
63
65
64
instrumentedFunc := func (ctx context.Context ) (* T , error ) {
66
65
j .rootJob .Wait (ctx )
@@ -69,15 +68,18 @@ func InputParam[T any](bCtx context.Context, j *Job, stepName string, value *T)
69
68
step .task = asynctask .Start (bCtx , instrumentedFunc )
70
69
71
70
j .Steps [stepName ] = step
72
- j .registerStepInGraph (stepName , j .rootJob .Name ())
71
+ j .registerStepInGraph (stepName , j .rootJob .GetName ())
73
72
74
73
return step
75
74
}
76
75
77
- func AddStep [T any ](bCtx context.Context , j * Job , stepName string , stepFunc asynctask.AsyncFunc [T ], dependOn []string , optionDecorators ... ExecutionOptionPreparer ) (* StepInfo [T ], error ) {
78
- // manually specified the dependencies, without consume the result.
76
+ func AddStep [T any ](bCtx context.Context , j * Job , stepName string , stepFunc asynctask.AsyncFunc [T ], optionDecorators ... ExecutionOptionPreparer ) (* StepInfo [T ], error ) {
77
+ step := newStepInfo [T ](stepName , optionDecorators ... )
78
+
79
+ // also consider specified the dependencies from ExecutionOptionPreparer, without consume the result.
80
+ var precedingStepNames = step .DependsOn ()
79
81
var precedingTasks []asynctask.Waitable
80
- for _ , stepName := range dependOn {
82
+ for _ , stepName := range precedingStepNames {
81
83
if step , ok := j .Steps [stepName ]; ok {
82
84
precedingTasks = append (precedingTasks , step .Waitable ())
83
85
} else {
@@ -87,11 +89,10 @@ func AddStep[T any](bCtx context.Context, j *Job, stepName string, stepFunc asyn
87
89
88
90
// if a step have no preceding tasks, link it to our rootJob as preceding task, so it won't start yet.
89
91
if len (precedingTasks ) == 0 {
92
+ precedingStepNames = append (precedingStepNames , j .rootJob .GetName ())
90
93
precedingTasks = append (precedingTasks , j .rootJob .Waitable ())
91
94
}
92
95
93
- step := newStepInfo [T ](stepName , dependOn , optionDecorators ... )
94
-
95
96
// instrument to :
96
97
// replaceRuntimeContext,
97
98
// trackStepState
@@ -115,30 +116,45 @@ func AddStep[T any](bCtx context.Context, j *Job, stepName string, stepFunc asyn
115
116
step .task = asynctask .Start (bCtx , instrumentedFunc )
116
117
117
118
j .Steps [stepName ] = step
118
- if len (dependOn ) > 0 {
119
- j .registerStepInGraph (stepName , dependOn ... )
120
- } else {
121
- j .registerStepInGraph (stepName , j .rootJob .Name ())
122
- }
119
+ j .registerStepInGraph (stepName , precedingStepNames ... )
123
120
124
121
return step , nil
125
122
}
126
123
127
124
func StepAfter [T , S any ](bCtx context.Context , j * Job , stepName string , parentStep * StepInfo [T ], stepFunc asynctask.ContinueFunc [T , S ], optionDecorators ... ExecutionOptionPreparer ) (* StepInfo [S ], error ) {
128
125
// check parentStepT is in this job
129
- if get , ok := j .Steps [parentStep .Name ()]; ! ok || get != parentStep {
130
- return nil , fmt .Errorf ("step [%s] not found in job" , parentStep .Name ())
126
+ if get , ok := j .Steps [parentStep .GetName ()]; ! ok || get != parentStep {
127
+ return nil , fmt .Errorf ("step [%s] not found in job" , parentStep .GetName ())
128
+ }
129
+
130
+ step := newStepInfo [S ](stepName , append (optionDecorators , ExecuteAfter (parentStep ))... )
131
+
132
+ // also consider specified the dependencies from ExecutionOptionPreparer, without consume the result.
133
+ var precedingStepNames = step .DependsOn ()
134
+ var precedingTasks []asynctask.Waitable
135
+ for _ , stepName := range precedingStepNames {
136
+ if step , ok := j .Steps [stepName ]; ok {
137
+ precedingTasks = append (precedingTasks , step .Waitable ())
138
+ } else {
139
+ return nil , fmt .Errorf ("step [%s] not found" , stepName )
140
+ }
131
141
}
132
142
133
- step := newStepInfo [S ](stepName , []string {parentStep .Name ()}, optionDecorators ... )
143
+ // if a step have no preceding tasks, link it to our rootJob as preceding task, so it won't start yet.
144
+ if len (precedingTasks ) == 0 {
145
+ precedingTasks = append (precedingTasks , j .rootJob .Waitable ())
146
+ }
134
147
135
148
// instrument to :
136
149
// replaceRuntimeContext
137
150
// trackStepState
138
151
// retryHandling (TODO)
139
152
// errorHandling (TODO)
140
153
// timeoutHandling (TODO)
141
- instrumentedFunc := func (_ context.Context , t * T ) (* S , error ) {
154
+ instrumentedFunc := func (ctx context.Context , t * T ) (* S , error ) {
155
+ if err := asynctask .WaitAll (ctx , & asynctask.WaitAllOptions {}, precedingTasks ... ); err != nil {
156
+ return nil , err
157
+ }
142
158
step .state = StepStateRunning
143
159
result , err := stepFunc (j .runtimeCtx , t )
144
160
if err != nil {
@@ -152,7 +168,7 @@ func StepAfter[T, S any](bCtx context.Context, j *Job, stepName string, parentSt
152
168
step .task = asynctask .ContinueWith (bCtx , parentStep .task , instrumentedFunc )
153
169
154
170
j .Steps [stepName ] = step
155
- j .registerStepInGraph (stepName , parentStep . Name () )
171
+ j .registerStepInGraph (stepName , precedingStepNames ... )
156
172
if err := j .stepsDag .Validate (); err != nil {
157
173
return nil , fmt .Errorf ("cycle dependency detected: %s" , err )
158
174
}
@@ -161,15 +177,30 @@ func StepAfter[T, S any](bCtx context.Context, j *Job, stepName string, parentSt
161
177
162
178
func StepAfterBoth [T , S , R any ](bCtx context.Context , j * Job , stepName string , parentStepT * StepInfo [T ], parentStepS * StepInfo [S ], stepFunc asynctask.AfterBothFunc [T , S , R ], optionDecorators ... ExecutionOptionPreparer ) (* StepInfo [R ], error ) {
163
179
// check parentStepT is in this job
164
- if get , ok := j .Steps [parentStepT .Name ()]; ! ok || get != parentStepT {
165
- return nil , fmt .Errorf ("step [%s] not found in job" , parentStepT .Name ())
180
+ if get , ok := j .Steps [parentStepT .GetName ()]; ! ok || get != parentStepT {
181
+ return nil , fmt .Errorf ("step [%s] not found in job" , parentStepT .GetName ())
166
182
}
167
- if get , ok := j .Steps [parentStepS .Name ()]; ! ok || get != parentStepS {
168
- return nil , fmt .Errorf ("step [%s] not found in job" , parentStepS .Name ())
183
+ if get , ok := j .Steps [parentStepS .GetName ()]; ! ok || get != parentStepS {
184
+ return nil , fmt .Errorf ("step [%s] not found in job" , parentStepS .GetName ())
169
185
}
170
186
171
- step := newStepInfo [R ](stepName , []string {parentStepT .Name (), parentStepS .Name ()}, optionDecorators ... )
187
+ step := newStepInfo [R ](stepName , append (optionDecorators , ExecuteAfter (parentStepT ), ExecuteAfter (parentStepS ))... )
188
+
189
+ // also consider specified the dependencies from ExecutionOptionPreparer, without consume the result.
190
+ var precedingStepNames = step .DependsOn ()
191
+ var precedingTasks []asynctask.Waitable
192
+ for _ , stepName := range precedingStepNames {
193
+ if step , ok := j .Steps [stepName ]; ok {
194
+ precedingTasks = append (precedingTasks , step .Waitable ())
195
+ } else {
196
+ return nil , fmt .Errorf ("step [%s] not found" , stepName )
197
+ }
198
+ }
172
199
200
+ // if a step have no preceding tasks, link it to our rootJob as preceding task, so it won't start yet.
201
+ if len (precedingTasks ) == 0 {
202
+ precedingTasks = append (precedingTasks , j .rootJob .Waitable ())
203
+ }
173
204
// instrument to :
174
205
// replaceRuntimeContext
175
206
// trackStepState
@@ -190,7 +221,8 @@ func StepAfterBoth[T, S, R any](bCtx context.Context, j *Job, stepName string, p
190
221
step .task = asynctask .AfterBoth (bCtx , parentStepT .task , parentStepS .task , instrumentedFunc )
191
222
192
223
j .Steps [stepName ] = step
193
- j .registerStepInGraph (stepName , parentStepT .Name (), parentStepS .Name ())
224
+ j .registerStepInGraph (stepName , precedingStepNames ... )
225
+
194
226
return step , nil
195
227
}
196
228
0 commit comments