@@ -73,7 +73,7 @@ func (s *Scheduler) Init() {
73
73
func (s * Scheduler ) work () {
74
74
// This worker never stops working.
75
75
for {
76
- // Take one scheduled run
76
+ // Take one scheduled run, block if there are no scheduled pipelines
77
77
r := <- s .scheduledRuns
78
78
79
79
// Mark the scheduled run as running
@@ -175,61 +175,81 @@ func (s *Scheduler) executePipeline(p *gaia.Pipeline, r *gaia.PipelineRun) {
175
175
return
176
176
}
177
177
178
+ // Check if this pipeline has jobs declared
179
+ if len (r .Jobs ) == 0 {
180
+ return
181
+ }
182
+
183
+ // Schedule jobs and execute them.
184
+ // Also update the run in the store.
185
+ s .scheduleJobsByPriority (r )
178
186
}
179
187
180
188
func executeJob (job * gaia.Job , wg * sync.WaitGroup ) {
181
189
// TODO
182
190
wg .Done ()
183
191
}
184
192
185
- func executeJobs (jobs []* gaia.Job ) {
186
- // We finished all jobs, exit recursive execution.
187
- if len (jobs ) == 0 {
188
- return
189
- }
190
-
193
+ // scheduleJobsByPriority schedules the given jobs by their respective
194
+ // priority. This method is designed to be recursive and blocking.
195
+ // If jobs have the same priority, they will be executed in parallel.
196
+ func (s * Scheduler ) scheduleJobsByPriority (r * gaia.PipelineRun ) {
191
197
// Find the job with the lowest priority
192
- var lowestPrio int32
193
- for id , job := range jobs {
194
- if job .Priority < lowestPrio || id == 0 {
198
+ var lowestPrio int64
199
+ for _ , job := range r . Jobs {
200
+ if job .Priority < lowestPrio && job . Status == gaia . JobWaitingExec {
195
201
lowestPrio = job .Priority
196
202
}
197
203
}
198
204
199
- // We allocate a new slice for jobs with higher priority.
200
- // And also a slice for jobs which we execute now.
201
- var nextJobs []* gaia.Job
202
- var execJobs []* gaia.Job
203
-
204
205
// We might have multiple jobs with the same priority.
205
206
// It means these jobs should be started in parallel.
206
207
var wg sync.WaitGroup
207
- for _ , job := range jobs {
208
+ for _ , job := range r . Jobs {
208
209
if job .Priority == lowestPrio {
209
210
// Increase wait group by one
210
211
wg .Add (1 )
211
- execJobs = append (execJobs , job )
212
212
213
213
// Execute this job in a separate goroutine
214
- go executeJob (job , & wg )
215
- } else {
216
- // We add this job to the next list
217
- nextJobs = append (nextJobs , job )
214
+ go executeJob (& job , & wg )
218
215
}
219
216
}
220
217
221
- // Wait until all jobs has been finished
218
+ // Create channel for storing job run results and spawn results routine
219
+ results := make (chan gaia.Job )
220
+ go s .getJobResultsAndStore (results , r )
221
+
222
+ // Wait until all jobs has been finished and close results channel
222
223
wg .Wait ()
224
+ close (results )
223
225
224
226
// Check if a job has been failed. If so, stop execution.
225
- for _ , job := range execJobs {
226
- if ! job .Success {
227
+ // We also check if all jobs has been executed.
228
+ var notExecJob bool
229
+ for _ , job := range r .Jobs {
230
+ switch job .Status {
231
+ case gaia .JobFailed :
227
232
return
233
+ case gaia .JobWaitingExec :
234
+ notExecJob = true
228
235
}
229
236
}
230
237
231
- // Run executeJobs again until all jobs have been executed
232
- executeJobs (nextJobs )
238
+ // All jobs has been executed
239
+ if ! notExecJob {
240
+ return
241
+ }
242
+
243
+ // Run scheduleJobsByPriority again until all jobs have been executed
244
+ s .scheduleJobsByPriority (r )
245
+ }
246
+
247
+ // getJobResultsAndStore
248
+ func (s * Scheduler ) getJobResultsAndStore (results chan gaia.Job , r * gaia.PipelineRun ) {
249
+ for _ = range results {
250
+ // Store update
251
+ s .storeService .PipelinePutRun (r )
252
+ }
233
253
}
234
254
235
255
// getPipelineJobs uses the plugin system to get all jobs from the given pipeline.
0 commit comments