func benchmarkCallsN(b *testing.B, c benchmarkConfig) {
	var (
		clients []*Channel
		servers []*Channel
	)
	lt := newLatencyTracker()

	if c.numBytes == 0 {
		c.numBytes = 100
	}
	data := testutils.RandBytes(c.numBytes)

	// Set up clients and servers.
	for i := 0; i < c.numServers; i++ {
		servers = append(servers, setupServer(b))
	}
	for i := 0; i < c.numClients; i++ {
		clients = append(clients, testutils.NewClient(b, nil))
		for _, s := range servers {
			clients[i].Peers().Add(s.PeerInfo().HostPort)

			// Initialize a connection
			ctx, cancel := NewContext(50 * time.Millisecond)
			assert.NoError(b, clients[i].Ping(ctx, s.PeerInfo().HostPort), "Initial ping failed")
			cancel()
		}
	}

	// Make calls from clients to the servers
	call := func(sc *SubChannel) {
		ctx, cancel := NewContext(50 * time.Millisecond)
		start := time.Now()
		_, _, _, err := raw.CallSC(ctx, sc, "echo", nil, data)
		duration := time.Since(start)
		cancel()
		if assert.NoError(b, err, "Call failed") {
			lt.addLatency(duration)
		}
	}

	reqsLeft := testutils.Decrementor(c.numCalls)
	clientWorker := func(client *Channel, clientNum, workerNum int) {
		sc := client.GetSubChannel(benchService)
		for reqsLeft() {
			call(sc)
		}
	}
	clientRunner := func(client *Channel, clientNum int) {
		testutils.RunN(c.workersPerClient, func(i int) {
			clientWorker(client, clientNum, i)
		})
	}

	lt.reset()
	defer lt.report(b)
	b.ResetTimer()

	testutils.RunN(c.numClients, func(i int) {
		clientRunner(clients[i], i)
	})
}
Esempio n. 2
0
func benchmarkRelay(b *testing.B, p benchmarkParams) {
	b.SetBytes(int64(p.requestSize))
	b.ReportAllocs()

	services := make(map[string][]string)

	servers := make([]benchmark.Server, p.servers)
	for i := range servers {
		servers[i] = benchmark.NewServer(
			benchmark.WithServiceName("svc"),
			benchmark.WithRequestSize(p.requestSize),
			benchmark.WithExternalProcess(),
		)
		defer servers[i].Close()
		services["svc"] = append(services["svc]"], servers[i].HostPort())
	}

	relay, err := benchmark.NewRealRelay(services)
	require.NoError(b, err, "Failed to create relay")
	defer relay.Close()

	clients := make([]benchmark.Client, p.clients)
	for i := range clients {
		clients[i] = benchmark.NewClient([]string{relay.HostPort()},
			benchmark.WithServiceName("svc"),
			benchmark.WithRequestSize(p.requestSize),
			benchmark.WithExternalProcess(),
			benchmark.WithTimeout(10*time.Second),
		)
		defer clients[i].Close()
		require.NoError(b, clients[i].Warmup(), "Warmup failed")
	}

	quantileVals := []float64{0.50, 0.95, 0.99, 1.0}
	quantiles := make([]*quantile.Stream, p.clients)
	for i := range quantiles {
		quantiles[i] = quantile.NewTargeted(quantileVals...)
	}

	wc := newWorkerControl(p.clients)
	dec := testutils.Decrementor(b.N)

	for i, c := range clients {
		go func(i int, c benchmark.Client) {
			// Do a warm up call.
			c.RawCall(1)

			wc.WorkerStart()
			defer wc.WorkerDone()

			for {
				tokens := dec.Multiple(200)
				if tokens == 0 {
					break
				}

				durations, err := c.RawCall(tokens)
				if err != nil {
					b.Fatalf("Call failed: %v", err)
				}

				for _, d := range durations {
					quantiles[i].Insert(float64(d))
				}
			}
		}(i, c)
	}

	var started time.Time
	wc.WaitForStart(func() {
		b.ResetTimer()
		started = time.Now()
	})
	wc.WaitForEnd()
	duration := time.Since(started)

	fmt.Printf("\nb.N: %v Duration: %v RPS = %0.0f\n", b.N, duration, float64(b.N)/duration.Seconds())

	// Merge all the quantiles into 1
	for _, q := range quantiles[1:] {
		quantiles[0].Merge(q.Samples())
	}

	for _, q := range quantileVals {
		fmt.Printf("  %0.4f = %v\n", q, time.Duration(quantiles[0].Query(q)))
	}
	fmt.Println()
}