diff options
author | Terin Stock <terinjokes@gmail.com> | 2017-12-15 16:05:17 -0800 |
---|---|---|
committer | Terin Stock <terinjokes@gmail.com> | 2017-12-15 16:05:17 -0800 |
commit | 46d4d2492fc6c64fd0a16b0080383025565d6acf (patch) | |
tree | 453ab2520646ebfcb34f7fb1c1a4375317f42cd6 | |
parent | 916d12b3cc199ae043734e7dde5e326756fc0eb3 (diff) |
feat: replace parallel with a semaphore
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Gopkg.lock | 14 | ||||
-rw-r--r-- | main.go | 96 |
3 files changed, 68 insertions, 43 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61ead86 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor diff --git a/Gopkg.lock b/Gopkg.lock index 19691af..86ff3bb 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -3,13 +3,19 @@ [[projects]] branch = "master" - name = "github.com/neelance/parallel" - packages = ["."] - revision = "4de9ce63d14c18517a79efe69e10e99d32c850c3" + name = "golang.org/x/net" + packages = ["context"] + revision = "d866cfc389cec985d6fda2859936a575a55a3ab6" + +[[projects]] + branch = "master" + name = "golang.org/x/sync" + packages = ["semaphore"] + revision = "fd80eb99c8f653c847d294a001bdf2a3a6f768f5" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "5cee123e66d33e8e63ab1f1a2ae68b744798e2093d92a855bfa52f7465b4c6ca" + inputs-digest = "1b7a27daae87f4f213b3475a08fd7367804c2755750bf27adb8c32ada7c9bdae" solver-name = "gps-cdcl" solver-version = 1 diff --git a/main.go b/main.go index ea2942c..a990cc3 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,7 @@ import ( "path/filepath" "runtime" - "github.com/neelance/parallel" + "golang.org/x/sync/semaphore" ) type Arch string @@ -114,46 +114,64 @@ func main() { os.Exit(-1) } - parallelJobs := runtime.NumCPU() - par := parallel.NewRun(parallelJobs) + var ( + parallelJobs = runtime.NumCPU() + sem = semaphore.NewWeighted(int64(parallelJobs)) + out = make([]error, len(platforms)*len(packages)) + ctx = context.Background() + ) + fmt.Printf("info: running bakelite with %d jobs\n", parallelJobs) - for _, platform := range platforms { - for _, pkg := range packages { - par.Acquire() - go func(platform Platform, pkg string) { - defer par.Release() - name := fmt.Sprintf("%s-%s-%s", filepath.Base(pkg), platform.OS, platform.Arch) - env := kvs{ - "GOOS": string(platform.OS), - "GOARCH": string(platform.Arch), - "GOROOT": os.Getenv("GOROOT"), - "GOPATH": os.Getenv("GOPATH"), - } - - if cgo { - env["CGO_ENABLED"] = "1" - } else { - env["CGO_ENABLED"] = "0" - } - - var stdout bytes.Buffer - var stderr bytes.Buffer - - cmd := exec.CommandContext(context.Background(), "go", "build", "-o", name, pkg) - cmd.Env = env.Strings() - cmd.Stdout = &stdout - cmd.Stderr = &stderr - - fmt.Printf("info: Running build for %s @ %s/%s…\n", pkg, platform.OS, platform.Arch) - err := cmd.Run() - - if err != nil { - log.Printf("fatal: There was an error! err='%s' stdout='%s' stderr='%s'", err, stdout.String(), stderr.String()) - os.Exit(-1) - } - }(platform, pkg) + for i, platform := range platforms { + for j, pkg := range packages { + if err := sem.Acquire(ctx, 1); err != nil { + log.Printf("failed to acquire semaphore: %s", err) + break + } + + go func(i int, j int, platform Platform, pkg string) { + defer sem.Release(1) + out[i*j] = build(ctx, platform, pkg) + }(i, j, platform, pkg) } } - par.Wait() + + if err := sem.Acquire(ctx, int64(parallelJobs)); err != nil { + log.Printf("failed to acquire semaphore: %s", err) + } +} + +func build(ctx context.Context, platform Platform, pkg string) error { + name := fmt.Sprintf("%s-%s-%s", filepath.Base(pkg), platform.OS, platform.Arch) + + env := kvs{ + "GOOS": string(platform.OS), + "GOARCH": string(platform.Arch), + "GOROOT": os.Getenv("GOROOT"), + "GOPATH": os.Getenv("GOPATH"), + } + + if cgo { + env["CGO_ENABLED"] = "1" + } else { + env["CGO_ENABLED"] = "0" + } + + var stdout bytes.Buffer + var stderr bytes.Buffer + + cmd := exec.CommandContext(context.Background(), "go", "build", "-o", name, pkg) + cmd.Env = env.Strings() + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + fmt.Printf("info: Running build for %s @ %s/%s…\n", pkg, platform.OS, platform.Arch) + err := cmd.Run() + + if err != nil { + log.Printf("fatal: There was an error! err='%s' stdout='%s' stderr='%s'", err, stdout.String(), stderr.String()) + } + + return err } |