func()

in sweet/benchmarks/gvisor/http_server.go [90:206]


func (b httpServer) run(cfg *config, out io.Writer) (err error) {
	procs := runtime.GOMAXPROCS(-1)
	clientProcs := procs / 4
	if clientProcs == 0 {
		clientProcs = 1
	}
	serverProcs := procs - clientProcs
	if serverProcs == 0 {
		serverProcs = 1
	}
	runtime.GOMAXPROCS(clientProcs)
	defer runtime.GOMAXPROCS(procs)
	clients := clientProcs

	baseSrvCmd := cfg.runscCmd(
		"-rootless", "do", "-ip", ip,
		workloadsPath(cfg.assetsDir, "http"),
		"-host", ip,
		"-port", port,
		"-assets", filepath.Join(cfg.assetsDir, "http", "assets"),
		"-procs", strconv.Itoa(serverProcs),
	)
	baseSrvCmd.Stdout = out
	baseSrvCmd.Stderr = out
	srvCmd, err := cgroups.WrapCommand(baseSrvCmd, "test-http-server.scope")
	if err != nil {
		return err
	}
	ctx := context.Background()
	defer func() {
		if r := srvCmd.Process.Signal(os.Interrupt); r != nil {
			if err != nil {
				fmt.Fprintf(os.Stderr, "failed to force shut down server: %v\n", r)
			} else {
				err = r
			}
		}
		if r := srvCmd.Wait(); r != nil {
			ee, ok := r.(*exec.ExitError)
			if ok {
				status := ee.ProcessState.Sys().(syscall.WaitStatus)
				if status.Signaled() && status.Signal() == os.Interrupt {
					return
				}
			}
			if err != nil {
				fmt.Fprintf(os.Stderr, "warning: failed to wait for server: %v\n", r)
				return
			}
			err = r
			return
		}
	}()

	err = driver.RunBenchmark(b.name()+"Startup", func(d *driver.B) error {
		if err := srvCmd.Start(); err != nil {
			return err
		}
		// Poll until the server is ready to serve, up to a maximum in case of a bug.
		const timeout = 30 * time.Second
		start := time.Now()
		for time.Now().Sub(start) < timeout {
			resp, err := httpGet(ctx, host)
			if err == nil {
				resp.Body.Close()
				break
			}
		}
		if time.Now().Sub(start) >= timeout {
			return fmt.Errorf("server startup timed out")
		}
		return nil
	}, driver.DoTime(true))

	workers := make([]pool.Worker, 0, clients)
	for i := 0; i < clients; i++ {
		workers = append(workers, newWorker())
	}

	// Run the benchmark for b.duration.
	ctx, cancel := context.WithTimeout(ctx, b.duration)
	defer cancel()
	p := pool.New(ctx, workers)
	return driver.RunBenchmark(b.name(), func(d *driver.B) error {
		if err := p.Run(); err != nil {
			return err
		}
		d.StopTimer()

		// Test is done, bring all latency measurements together.
		latencies := make([]time.Duration, 0, len(workers)*100000)
		for _, w := range workers {
			latencies = append(latencies, w.(*worker).lat...)
		}
		sort.Slice(latencies, func(i, j int) bool {
			return latencies[i] < latencies[j]
		})

		// Sort and report percentiles.
		p50 := latencies[len(latencies)*50/100]
		p90 := latencies[len(latencies)*90/100]
		p99 := latencies[len(latencies)*99/100]
		d.Report("p50-latency-ns", uint64(p50))
		d.Report("p90-latency-ns", uint64(p90))
		d.Report("p99-latency-ns", uint64(p99))

		// Report throughput.
		lengthS := float64(b.duration) / float64(time.Second)
		reqsPerSec := float64(len(latencies)) / lengthS
		d.Report("ops/s", uint64(reqsPerSec))

		// Report the average request latency.
		d.Ops(len(latencies))
		d.Report(driver.StatTime, uint64((int(b.duration)*clients)/len(latencies)))
		return nil
	}, driver.DoTime(true), driver.DoAvgRSS(srvCmd.RSSFunc()))
}