@@ -111,18 +111,18 @@ func (s *Scheduler) work() {
111
111
r := <- s .scheduledRuns
112
112
113
113
// Prepare execution and start it
114
- s .prepareAndExec (& r )
114
+ s .prepareAndExec (r )
115
115
}
116
116
}
117
117
118
118
// prepareAndExec does the real preparation and start the execution.
119
- func (s * Scheduler ) prepareAndExec (r * gaia.PipelineRun ) {
119
+ func (s * Scheduler ) prepareAndExec (r gaia.PipelineRun ) {
120
120
// Mark the scheduled run as running
121
121
r .Status = gaia .RunRunning
122
122
r .StartDate = time .Now ()
123
123
124
124
// Update entry in store
125
- err := s .storeService .PipelinePutRun (r )
125
+ err := s .storeService .PipelinePutRun (& r )
126
126
if err != nil {
127
127
gaia .Cfg .Logger .Debug ("could not put pipeline run into store during executing work" , "error" , err .Error ())
128
128
return
@@ -138,14 +138,14 @@ func (s *Scheduler) prepareAndExec(r *gaia.PipelineRun) {
138
138
139
139
// Update store
140
140
r .Status = gaia .RunFailed
141
- s .storeService .PipelinePutRun (r )
141
+ s .storeService .PipelinePutRun (& r )
142
142
return
143
143
}
144
144
145
145
// Check if this pipeline has jobs declared
146
146
if len (r .Jobs ) == 0 {
147
147
// Finish pipeline run
148
- s .finishPipelineRun (r , gaia .RunSuccess )
148
+ s .finishPipelineRun (& r , gaia .RunSuccess )
149
149
return
150
150
}
151
151
@@ -160,7 +160,7 @@ func (s *Scheduler) prepareAndExec(r *gaia.PipelineRun) {
160
160
c := createPipelineCmd (pipeline )
161
161
if c == nil {
162
162
gaia .Cfg .Logger .Debug ("cannot create pipeline start command" , "error" , errCreateCMDForPipeline .Error ())
163
- s .finishPipelineRun (r , gaia .RunFailed )
163
+ s .finishPipelineRun (& r , gaia .RunFailed )
164
164
return
165
165
}
166
166
@@ -171,14 +171,14 @@ func (s *Scheduler) prepareAndExec(r *gaia.PipelineRun) {
171
171
path = filepath .Join (path , gaia .LogsFileName )
172
172
if err := pS .Connect (c , & path ); err != nil {
173
173
gaia .Cfg .Logger .Debug ("cannot connect to pipeline" , "error" , err .Error (), "pipeline" , pipeline )
174
- s .finishPipelineRun (r , gaia .RunFailed )
174
+ s .finishPipelineRun (& r , gaia .RunFailed )
175
175
return
176
176
}
177
177
defer pS .Close ()
178
178
179
179
// Schedule jobs and execute them.
180
180
// Also update the run in the store.
181
- s .scheduleJobsByPriority (r , pipeline , pS )
181
+ s .scheduleJobsByPriority (r , pS )
182
182
}
183
183
184
184
// schedule looks in the store for new work and schedules it.
@@ -249,21 +249,22 @@ func (s *Scheduler) SchedulePipeline(p *gaia.Pipeline) (*gaia.PipelineRun, error
249
249
250
250
// executeJob executes a single job.
251
251
// This method is blocking.
252
- func executeJob (job * gaia.Job , pS Plugin , wg * sync.WaitGroup , triggerSave chan bool ) {
252
+ func executeJob (job gaia.Job , pS Plugin , wg * sync.WaitGroup , triggerSave chan gaia. Job ) {
253
253
defer wg .Done ()
254
254
defer func () {
255
- triggerSave <- true
255
+ triggerSave <- job
256
256
}()
257
257
258
258
// Set Job to running and trigger save
259
259
job .Status = gaia .JobRunning
260
- triggerSave <- true
260
+ triggerSave <- job
261
261
262
262
// Execute job
263
- if err := pS .Execute (job ); err != nil {
263
+ if err := pS .Execute (& job ); err != nil {
264
264
// TODO: Show it to user
265
265
gaia .Cfg .Logger .Debug ("error during job execution" , "error" , err .Error (), "job" , job )
266
266
job .Status = gaia .JobFailed
267
+ return
267
268
}
268
269
269
270
// If we are here, the job execution was ok
@@ -273,7 +274,7 @@ func executeJob(job *gaia.Job, pS Plugin, wg *sync.WaitGroup, triggerSave chan b
273
274
// scheduleJobsByPriority schedules the given jobs by their respective
274
275
// priority. This method is designed to be recursive and blocking.
275
276
// If jobs have the same priority, they will be executed in parallel.
276
- func (s * Scheduler ) scheduleJobsByPriority (r * gaia.PipelineRun , p * gaia. Pipeline , pS Plugin ) {
277
+ func (s * Scheduler ) scheduleJobsByPriority (r gaia.PipelineRun , pS Plugin ) {
277
278
// Do a prescheduling and set it to the first waiting job
278
279
var lowestPrio int64
279
280
for _ , job := range r .Jobs {
@@ -293,31 +294,54 @@ func (s *Scheduler) scheduleJobsByPriority(r *gaia.PipelineRun, p *gaia.Pipeline
293
294
// We might have multiple jobs with the same priority.
294
295
// It means these jobs should be started in parallel.
295
296
var wg sync.WaitGroup
296
- triggerSave := make (chan bool )
297
+ triggerSave := make (chan gaia.Job )
298
+ done := make (chan bool )
297
299
for id , job := range r .Jobs {
298
300
if job .Priority == lowestPrio && job .Status == gaia .JobWaitingExec {
299
301
// Increase wait group by one
300
302
wg .Add (1 )
301
303
302
304
// Execute this job in a separate goroutine
303
- go executeJob (& r .Jobs [id ], pS , & wg , triggerSave )
305
+ go executeJob (r .Jobs [id ], pS , & wg , triggerSave )
304
306
}
305
307
}
306
308
307
309
// Create channel for storing job run results and spawn results routine
308
- go s .getJobResultsAndStore (triggerSave , r )
310
+ go func () {
311
+ for {
312
+ j , open := <- triggerSave
313
+
314
+ // Channel has been closed
315
+ if ! open {
316
+ done <- true
317
+ return
318
+ }
319
+
320
+ // Filter out the job
321
+ for id , job := range r .Jobs {
322
+ if job .ID == j .ID {
323
+ r .Jobs [id ].Status = j .Status
324
+ break
325
+ }
326
+ }
327
+
328
+ // Store update
329
+ s .storeService .PipelinePutRun (& r )
330
+ }
331
+ }()
309
332
310
333
// Wait until all jobs have been finished and close results channel
311
334
wg .Wait ()
312
335
close (triggerSave )
336
+ <- done
313
337
314
338
// Check if a job has been failed. If so, stop execution.
315
339
// We also check if all jobs has been executed.
316
340
var notExecJob bool
317
341
for _ , job := range r .Jobs {
318
342
switch job .Status {
319
343
case gaia .JobFailed :
320
- s .finishPipelineRun (r , gaia .RunFailed )
344
+ s .finishPipelineRun (& r , gaia .RunFailed )
321
345
return
322
346
case gaia .JobWaitingExec :
323
347
notExecJob = true
@@ -326,20 +350,12 @@ func (s *Scheduler) scheduleJobsByPriority(r *gaia.PipelineRun, p *gaia.Pipeline
326
350
327
351
// All jobs have been executed
328
352
if ! notExecJob {
329
- s .finishPipelineRun (r , gaia .RunSuccess )
353
+ s .finishPipelineRun (& r , gaia .RunSuccess )
330
354
return
331
355
}
332
356
333
357
// Run scheduleJobsByPriority again until all jobs have been executed
334
- s .scheduleJobsByPriority (r , p , pS )
335
- }
336
-
337
- // getJobResultsAndStore
338
- func (s * Scheduler ) getJobResultsAndStore (triggerSave chan bool , r * gaia.PipelineRun ) {
339
- for range triggerSave {
340
- // Store update
341
- s .storeService .PipelinePutRun (r )
342
- }
358
+ s .scheduleJobsByPriority (r , pS )
343
359
}
344
360
345
361
// getPipelineJobs uses the plugin system to get all jobs from the given pipeline.
0 commit comments