From 6097a69b5e5c0e77792ffb1617e8f0f25a2f1076 Mon Sep 17 00:00:00 2001 From: Tochemey Date: Sun, 11 Aug 2024 13:11:13 +0100 Subject: [PATCH] perf: add a performance benchmark tests --- bench/benchmark.go | 33 +++++++++++++++++++++++++++++++-- bench/benchmark_test.go | 27 +++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/bench/benchmark.go b/bench/benchmark.go index 34bb5a4e..d77eb719 100644 --- a/bench/benchmark.go +++ b/bench/benchmark.go @@ -61,6 +61,7 @@ func (p *Benchmarker) Receive(ctx actors.ReceiveContext) { case *benchmarkpb.BenchTell: totalRecv.Add(1) case *benchmarkpb.BenchRequest: + totalRecv.Add(1) ctx.Response(&benchmarkpb.BenchResponse{}) default: ctx.Unhandled() @@ -129,8 +130,8 @@ func (b *Benchmark) Stop(ctx context.Context) error { return b.system.Stop(ctx) } -// Bench sends messages to a random actor -func (b *Benchmark) Bench(ctx context.Context) error { +// BenchTell sends messages to a random actor +func (b *Benchmark) BenchTell(ctx context.Context) error { wg := sync.WaitGroup{} wg.Add(b.workersCount) deadline := time.Now().Add(b.duration) @@ -156,3 +157,31 @@ func (b *Benchmark) Bench(ctx context.Context) error { } return nil } + +// BenchAsk sends messages to a random actor +func (b *Benchmark) BenchAsk(ctx context.Context) error { + wg := sync.WaitGroup{} + wg.Add(b.workersCount) + deadline := time.Now().Add(b.duration) + for i := 0; i < b.workersCount; i++ { + go func() { + defer wg.Done() + for time.Now().Before(deadline) { + // randomly pick and actor + pid := b.pids[rand.IntN(len(b.pids))] //nolint:gosec + // send a message + _, _ = actors.Ask(ctx, pid, new(benchmarkpb.BenchRequest), receivingTimeout) + // increase sent counter + totalSent.Add(1) + } + }() + } + + // wait for the messages to be delivered + wg.Wait() + time.Sleep(500 * time.Millisecond) + if totalSent.Load() != totalRecv.Load() { + return fmt.Errorf("send count and receive count does not match: %d != %d", totalSent.Load(), totalRecv.Load()) + } + return nil +} diff --git a/bench/benchmark_test.go b/bench/benchmark_test.go index b7fe8c3c..2e29982b 100644 --- a/bench/benchmark_test.go +++ b/bench/benchmark_test.go @@ -162,7 +162,7 @@ func runParallel(b *testing.B, benchFn func(pb *testing.PB)) { b.ReportMetric(opsPerSec, "ops/s") } -func TestBenchmark_Bench(t *testing.T) { +func TestBenchmark_BenchTell(t *testing.T) { ctx := context.TODO() actorsCount := 2000 @@ -173,7 +173,30 @@ func TestBenchmark_Bench(t *testing.T) { require.NoError(t, benchmark.Start(ctx)) fmt.Printf("starting benchmark for (%v): num workers:(%d)\n", duration, workersCount) - if err := benchmark.Bench(ctx); err != nil { + if err := benchmark.BenchTell(ctx); err != nil { + t.Fatal(err) + } + + fmt.Printf("total actors spawned: (%d)\n", actorsCount) + fmt.Printf("total workers: (%d), total messages sent: (%d), total messages received: (%d) - duration: (%v)\n", workersCount, totalSent.Load(), totalRecv.Load(), duration) + fmt.Printf("messages per second: (%d)\n", totalRecv.Load()/int64(duration.Seconds())) + t.Cleanup(func() { + require.NoError(t, benchmark.Stop(ctx)) + }) +} + +func TestBenchmark_BenchAsk(t *testing.T) { + ctx := context.TODO() + + actorsCount := 2000 + workersCount := 50 + duration := 30 * time.Second + + benchmark := NewBenchmark(actorsCount, workersCount, duration) + require.NoError(t, benchmark.Start(ctx)) + + fmt.Printf("starting benchmark for (%v): num workers:(%d)\n", duration, workersCount) + if err := benchmark.BenchAsk(ctx); err != nil { t.Fatal(err) }