Skip to content

Commit dd0c8ee

Browse files
committed
cmd/buildlet: don't log one line per untarred file
Some builders (OpenBSD, FreeBSD, Plan9 at least?) have their buildlet process's stdout/stderr hooked up to their serial console. The log line for each untarred Go1.4 + Go src tarball going to the serial console added just shy of 1 minute (!!) to the build time. Now it takes 3 seconds. (Or 12 seconds before change to use an async+noatime filesystem on the BSDs) Updates golang/go#17104 Change-Id: I1e6f00bcca955ead26b279a79729e50319384593 Reviewed-on: https://go-review.googlesource.com/29430 Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 885124e commit dd0c8ee

File tree

1 file changed

+33
-8
lines changed

1 file changed

+33
-8
lines changed

cmd/buildlet/buildlet.go

+33-8
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ func handleWriteTGZ(w http.ResponseWriter, r *http.Request) {
462462
baseDir := *workDir
463463
if dir := urlParam.Get("dir"); dir != "" {
464464
if !validRelativeDir(dir) {
465+
log.Printf("writetgz: bogus dir %q", dir)
465466
http.Error(w, "bogus dir", http.StatusBadRequest)
466467
return
467468
}
@@ -472,49 +473,55 @@ func handleWriteTGZ(w http.ResponseWriter, r *http.Request) {
472473
// This lets clients do a blind write to it and not do extra work.
473474
if r.Method == "POST" && dir == "go1.4" {
474475
if fi, err := os.Stat(baseDir); err == nil && fi.IsDir() {
475-
log.Printf("skipping URL puttar to go1.4 dir; already exists")
476+
log.Printf("writetgz: skipping URL puttar to go1.4 dir; already exists")
476477
io.WriteString(w, "SKIP")
477478
return
478479
}
479480
}
480481

481482
if err := os.MkdirAll(baseDir, 0755); err != nil {
483+
log.Printf("writetgz: %v", err)
482484
http.Error(w, "mkdir of base: "+err.Error(), http.StatusInternalServerError)
483485
return
484486
}
485487
}
486488

487489
var tgz io.Reader
490+
var urlStr string
488491
switch r.Method {
489492
case "PUT":
490493
tgz = r.Body
494+
log.Printf("writetgz: untarring Request.Body into %s", baseDir)
491495
case "POST":
492-
urlStr := r.FormValue("url")
496+
urlStr = r.FormValue("url")
493497
if urlStr == "" {
498+
log.Printf("writetgz: missing url POST param")
494499
http.Error(w, "missing url POST param", http.StatusBadRequest)
495500
return
496501
}
502+
t0 := time.Now()
497503
res, err := http.Get(urlStr)
498504
if err != nil {
499-
log.Printf("Failed to fetch tgz URL %s: %v", urlStr, err)
505+
log.Printf("writetgz: failed to fetch tgz URL %s: %v", urlStr, err)
500506
http.Error(w, fmt.Sprintf("fetching URL %s: %v", urlStr, err), http.StatusInternalServerError)
501507
return
502508
}
503509
defer res.Body.Close()
504510
if res.StatusCode != http.StatusOK {
505-
log.Printf("Failed to fetch tgz URL %s: status=%v", urlStr, res.Status)
511+
log.Printf("writetgz: failed to fetch tgz URL %s: status=%v", urlStr, res.Status)
506512
http.Error(w, fmt.Sprintf("fetching provided url: %s", res.Status), http.StatusInternalServerError)
507513
return
508514
}
509515
tgz = res.Body
516+
log.Printf("writetgz: untarring %s (got headers in %v) into %s", urlStr, time.Since(t0), baseDir)
510517
default:
518+
log.Printf("writetgz: invalid method %q", r.Method)
511519
http.Error(w, "requires PUT or POST method", http.StatusBadRequest)
512520
return
513521
}
514522

515523
err := untar(tgz, baseDir)
516524
if err != nil {
517-
log.Printf("untar failure: %v", err)
518525
status := http.StatusInternalServerError
519526
if he, ok := err.(httpStatuser); ok {
520527
status = he.httpStatus()
@@ -583,7 +590,18 @@ func writeFile(r io.Reader, path string, mode os.FileMode) error {
583590
}
584591

585592
// untar reads the gzip-compressed tar file from r and writes it into dir.
586-
func untar(r io.Reader, dir string) error {
593+
func untar(r io.Reader, dir string) (err error) {
594+
t0 := time.Now()
595+
nFiles := 0
596+
madeDir := map[string]bool{}
597+
defer func() {
598+
td := time.Since(t0)
599+
if err == nil {
600+
log.Printf("extracted tarball into %s: %d files, %d dirs (%v)", dir, nFiles, len(madeDir), td)
601+
} else {
602+
log.Printf("error extracting tarball into %s after %d files, %d dirs, %v: %v", dir, nFiles, len(madeDir), td, err)
603+
}
604+
}()
587605
zr, err := gzip.NewReader(r)
588606
if err != nil {
589607
return badRequest("requires gzip-compressed body: " + err.Error())
@@ -612,7 +630,13 @@ func untar(r io.Reader, dir string) error {
612630
// already be made by a directory entry in the tar
613631
// beforehand. Thus, don't check for errors; the next
614632
// write will fail with the same error.
615-
os.MkdirAll(filepath.Dir(abs), 0755)
633+
dir := filepath.Dir(abs)
634+
if !madeDir[dir] {
635+
if err := os.MkdirAll(filepath.Dir(abs), 0755); err != nil {
636+
return err
637+
}
638+
madeDir[dir] = true
639+
}
616640
wf, err := os.OpenFile(abs, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode.Perm())
617641
if err != nil {
618642
return err
@@ -627,7 +651,6 @@ func untar(r io.Reader, dir string) error {
627651
if n != f.Size {
628652
return fmt.Errorf("only wrote %d bytes to %s; expected %d", n, abs, f.Size)
629653
}
630-
log.Printf("wrote %s", abs)
631654
if !f.ModTime.IsZero() {
632655
if err := os.Chtimes(abs, f.ModTime, f.ModTime); err != nil {
633656
// benign error. Gerrit doesn't even set the
@@ -638,10 +661,12 @@ func untar(r io.Reader, dir string) error {
638661
log.Printf("error changing modtime: %v", err)
639662
}
640663
}
664+
nFiles++
641665
case mode.IsDir():
642666
if err := os.MkdirAll(abs, 0755); err != nil {
643667
return err
644668
}
669+
madeDir[abs] = true
645670
default:
646671
return badRequest(fmt.Sprintf("tar file entry %s contained unsupported file type %v", f.Name, mode))
647672
}

0 commit comments

Comments
 (0)