Background distGzipFile to speed up CI builds

These can take a minute or more of build time, and currently hold up
other processing. We could move to a parallel compression scheme to
speed them up, but it's simpler just to background them and continue the
build, waiting to make sure they've finished before exiting.

Testing this on git_master/flame-userdebug:

This brings a local no-op `m nothing dist` build from 2m1s to 1m39s,
even though most of that time is still spent waiting on these (since
there is very little else happening in a `nothing` build when Soong and
Kati don't need to run).

Running `touch art/Android.mk; m nothing dist` (so the above, but with
Kati) goes from 3m39s to 2m2s. We spent 9 seconds at the end waiting for
these to finish.

CI cases that almost always run Kati plus some number of other actions
are likely to completely hide the time taken to dist these files.

Bug: 229932999
Test: Check $DIST_DIR, files still exist
Change-Id: I1fb78d7c4d5103d72b5d71d9277dea0d452f8968
This commit is contained in:
Dan Willemsen
2022-04-20 21:45:00 -07:00
committed by Ed Heyl
parent de3604453f
commit 80d7261821

View File

@@ -18,6 +18,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"sync"
"text/template" "text/template"
"android/soong/ui/metrics" "android/soong/ui/metrics"
@@ -205,6 +206,8 @@ func Build(ctx Context, config Config) {
return return
} }
defer waitForDist(ctx)
// checkProblematicFiles aborts the build if Android.mk or CleanSpec.mk are found at the root of the tree. // checkProblematicFiles aborts the build if Android.mk or CleanSpec.mk are found at the root of the tree.
checkProblematicFiles(ctx) checkProblematicFiles(ctx)
@@ -329,8 +332,18 @@ func Build(ctx Context, config Config) {
} }
} }
var distWaitGroup sync.WaitGroup
// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
func waitForDist(ctx Context) {
ctx.BeginTrace("soong_ui", "dist")
defer ctx.EndTrace()
distWaitGroup.Wait()
}
// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures // distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
// are printed but non-fatal. // are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
func distGzipFile(ctx Context, config Config, src string, subDirs ...string) { func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
if !config.Dist() { if !config.Dist() {
return return
@@ -343,13 +356,17 @@ func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
ctx.Printf("failed to mkdir %s: %s", destDir, err.Error()) ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
} }
if err := gzipFileToDir(src, destDir); err != nil { distWaitGroup.Add(1)
ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error()) go func() {
} defer distWaitGroup.Done()
if err := gzipFileToDir(src, destDir); err != nil {
ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
}
}()
} }
// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but // distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
// non-fatal. // non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
func distFile(ctx Context, config Config, src string, subDirs ...string) { func distFile(ctx Context, config Config, src string, subDirs ...string) {
if !config.Dist() { if !config.Dist() {
return return
@@ -362,7 +379,11 @@ func distFile(ctx Context, config Config, src string, subDirs ...string) {
ctx.Printf("failed to mkdir %s: %s", destDir, err.Error()) ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
} }
if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil { distWaitGroup.Add(1)
ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error()) go func() {
} defer distWaitGroup.Done()
if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
}
}()
} }