59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"git.csclub.uwaterloo.ca/public/merlin/common"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
func main() {
|
|
logger := common.NewLogger("main")
|
|
cfg := common.GetConfig()
|
|
logger.Debug("Read config:")
|
|
logger.Debug(fmt.Sprintf("%+v\n", cfg))
|
|
|
|
unix.Umask(002)
|
|
|
|
// TODO: add debug log in main that job has started
|
|
repos := cfg.Repos
|
|
repoMap := make(map[string]*common.Repo)
|
|
for _, repo := range repos {
|
|
repoMap[repo.Name] = repo
|
|
}
|
|
doneChan := cfg.DoneChan
|
|
repoIdx := 0
|
|
numJobsRunning := 0
|
|
runAsManyAsPossible := func() {
|
|
// We use a round-robin strategy. It's not the most efficient,
|
|
// but it's simple (read: easy to understand) and guarantees
|
|
// that each repo will eventually get a chance to run.
|
|
startIdx := repoIdx
|
|
for numJobsRunning < cfg.MaxJobs {
|
|
repo := repos[repoIdx]
|
|
// attempt to run repo and increment when a job is started
|
|
if repo.RunIfScheduled() {
|
|
numJobsRunning++
|
|
}
|
|
repoIdx = (repoIdx + 1) % len(repos)
|
|
if repoIdx == startIdx {
|
|
// we've come full circle
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
runAsManyAsPossible()
|
|
for {
|
|
select {
|
|
case result := <-doneChan:
|
|
// move this into a method in common.go
|
|
repoMap[result.Name].JobDone(result.Exit)
|
|
numJobsRunning--
|
|
case <-time.After(1 * time.Minute):
|
|
}
|
|
runAsManyAsPossible()
|
|
}
|
|
}
|