From 06c16b1a26394cad90f5342e50ef92c2c512f4a1 Mon Sep 17 00:00:00 2001 From: Rick Newton-Rogers Date: Thu, 17 Oct 2024 13:03:52 +0100 Subject: [PATCH] Add future wait benchmark to catch memory leaks (#2931) ### Motivation: In the past we introduced a memory leak around the creation of and waiting on futures - we should protect against leaks in this fundamental operation. ### Modifications: Add a new benchmark which would have failed with the previous bug ### Result: Regression protection for this type of memory leak. --- .../NIOCoreBenchmarks/Benchmarks.swift | 29 +++++++++++++++++++ .../NIOCoreBenchmarks.WaitOnPromise.p90.json | 4 +++ .../NIOCoreBenchmarks.WaitOnPromise.p90.json | 4 +++ .../NIOCoreBenchmarks.WaitOnPromise.p90.json | 4 +++ 4 files changed, 41 insertions(+) create mode 100644 Benchmarks/Thresholds/5.10/NIOCoreBenchmarks.WaitOnPromise.p90.json create mode 100644 Benchmarks/Thresholds/5.8/NIOCoreBenchmarks.WaitOnPromise.p90.json create mode 100644 Benchmarks/Thresholds/5.9/NIOCoreBenchmarks.WaitOnPromise.p90.json diff --git a/Benchmarks/Benchmarks/NIOCoreBenchmarks/Benchmarks.swift b/Benchmarks/Benchmarks/NIOCoreBenchmarks/Benchmarks.swift index cea2e10af5..c821b872dd 100644 --- a/Benchmarks/Benchmarks/NIOCoreBenchmarks/Benchmarks.swift +++ b/Benchmarks/Benchmarks/NIOCoreBenchmarks/Benchmarks.swift @@ -21,6 +21,11 @@ let benchmarks = { .mallocCountTotal ] + let leakMetrics: [BenchmarkMetric] = [ + .mallocCountTotal, + .memoryLeaked, + ] + Benchmark( "NIOAsyncChannel.init", configuration: .init( @@ -46,4 +51,28 @@ let benchmarks = { blackHole(asyncChanel) } } + + Benchmark( + "WaitOnPromise", + configuration: .init( + metrics: leakMetrics, + scalingFactor: .kilo, + maxDuration: .seconds(10_000_000), + maxIterations: 10_000 // need 10k to get a signal + ) + ) { benchmark in + // Elide the cost of the 'EmbeddedEventLoop'. + let el = EmbeddedEventLoop() + + benchmark.startMeasurement() + defer { + benchmark.stopMeasurement() + } + + for _ in 0..