Hello Michael, I've posted a reply at https://github.com/golang/go/issues/32326#issuecomment-524997226 but perhaps I'll inline it below:
Hello @MichaelTJones, thank you for the patience! We are working on trying to diagnose why it is that by the time that the test executes, that your machine has already created close to 50 threads. To get started, please help me with: a) The output of `sysctl hw` b) Please run this program which will run most of the code from the failing test over a number of *os.Files and creates traces in a zip file. It is available at https://gist.github.com/odeke-em/1f60b09d30675ae9d4db47b3bfa2df22 or inlined ```go package main import ( "archive/zip" "context" "fmt" "io" "io/ioutil" "log" "os" "os/exec" "path/filepath" "time" ) func main() { nPipes := []int{0, 1, 5, 10, 20, 50, 75, 100} tmpDir, err := ioutil.TempDir("", "th") if err != nil { log.Fatalf("Failed to create temporary directory: %v", err) } defer os.RemoveAll(tmpDir) mainGoPath := filepath.Join(tmpDir, "main.go") if err := ioutil.WriteFile(mainGoPath, []byte(sourceCode), 0644); err != nil { log.Printf("writing main file %q: %v", mainGoPath, err) return } for _, n := range nPipes { if err := runIt(tmpDir, mainGoPath, n); err != nil { log.Printf("Error building for %d: %v\n", n, err) } } fz, err := os.Create("contents.zip") if err != nil { log.Printf("Failed to create contents.zip file: %v", err) return } defer fz.Close() zw := zip.NewWriter(fz) defer zw.Close() defer zw.Flush() err = filepath.Walk(tmpDir, func(path string, fi os.FileInfo, err error) error { if fi.IsDir() { return nil } if err != nil { return err } zfh, err := zip.FileInfoHeader(fi) if err != nil { return err } w, err := zw.CreateHeader(zfh) if err != nil { return err } f, err := os.Open(path) if err != nil { return err } defer f.Close() _, err = io.Copy(w, f) return err }) if err != nil { log.Fatalf("filepath.Walk error: %v", err) } } func runIt(baseDir, mainGoPath string, n int) error { // Now run it and save it to the file. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() cmd := exec.CommandContext(ctx, "go", "run", mainGoPath, "-dir", baseDir, "-n", fmt.Sprintf("%d", n)) output, err := cmd.CombinedOutput() if err != nil { err = fmt.Errorf("exec error: %v\nOutput: %s\n", err, output) } return err } const sourceCode = ` package main import ( "flag" "fmt" "log" "os" "path/filepath" "runtime/trace" ) func osPipesIO(n int) { r := make([]*os.File, n) w := make([]*os.File, n) for i := 0; i < n; i++ { rp, wp, err := os.Pipe() if err != nil { for j := 0; j < i; j++ { r[j].Close() w[j].Close() } log.Fatal(err) } r[i] = rp w[i] = wp } creading := make(chan bool, n) cdone := make(chan bool, n) for i := 0; i < n; i++ { go func(i int) { var b [1]byte creading <- true if _, err := r[i].Read(b[:]); err != nil { log.Printf("r[%d].Read: %v", i, err) } if err := r[i].Close(); err != nil { log.Printf("r[%d].Close: %v", i, err) } cdone <- true }(i) } for i := 0; i < n; i++ { <-creading } for i := 0; i < n; i++ { if _, err := w[i].Write([]byte{0}); err != nil { log.Printf("w[%d].Read: %v", i, err) } if err := w[i].Close(); err != nil { log.Printf("w[%d].Close: %v", i, err) } <-cdone } } func main() { baseDir := flag.String("dir", "", "the base directory to place execution traces") n := flag.Int("n", 0, "the number of *os.Pipe to create") flag.Parse() f, err := os.Create(filepath.Join(*baseDir, fmt.Sprintf("trace-%d.txt", *n))) if err != nil { log.Fatalf("Failed to create trace file: %v", err) } defer f.Close() trace.Start(f) defer trace.Stop() osPipesIO(*n) }` ``` c) Please share the created zip file and in there you'll see the various execution traces with n reads from [0, 1, 5, 10, 20, 50, 75, 100] which will perhaps shine a light on what's going on. If you don't feel comfortable sharing c), please feel free to email it to me and if you don't feel comfortable sharing the zip of the execution traces with me, not a problem, just please help me run `go tool trace trace-<N>.txt` after unzipping that file and examining the number of threads created with 0, 1 and 10 os.Pipe IOs. Thank you! On Wednesday, August 21, 2019 at 2:33:06 PM UTC-6, Andrew Bonventre wrote: > > Hello gophers, > > We have just released go1.13rc1, a release candidate version of Go 1.13. > It is cut from release-branch.go1.13 at the revision tagged go1.13rc1. > > Please try your production load tests and unit tests with the new version. > Your help testing these pre-release versions is invaluable. > > Report any problems using the issue tracker: > https://golang.org/issue/new > > If you have Go installed already, the easiest way to try go1.13rc1 > is by using the go command: > $ go get golang.org/dl/go1.13rc1 > $ go1.13rc1 download > > You can download binary and source distributions from the usual place: > https://golang.org/dl/#go1.13rc1 > > To find out what has changed in Go 1.13, read the draft release notes: > https://tip.golang.org/doc/go1.13 > > Cheers, > The Go Team > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/c2e9bf58-15d8-4ea5-8d5f-89f8533321ad%40googlegroups.com.