From de7b0b93b91f3e51a190cd0b0306f5cc65934eaa Mon Sep 17 00:00:00 2001 From: Vladimir Pavlov <43521651+MisterVVP@users.noreply.github.com> Date: Thu, 9 Jul 2026 13:50:17 +0300 Subject: [PATCH 1/2] Refactor performance driver structure --- tests/performance/README.md | 48 ++++ tests/performance/a2a_performance_driver.cpp | 244 ++++++++----------- tests/performance/a2a_performance_driver.h | 109 +++++++++ 3 files changed, 261 insertions(+), 140 deletions(-) create mode 100644 tests/performance/README.md create mode 100644 tests/performance/a2a_performance_driver.h diff --git a/tests/performance/README.md b/tests/performance/README.md new file mode 100644 index 0000000..1aaf486 --- /dev/null +++ b/tests/performance/README.md @@ -0,0 +1,48 @@ +# A2A performance driver + +`a2a_performance_driver` is the in-process C++ SDK performance driver used by +`scripts/run_performance_tests.sh` and `scripts/performance_runner.py`. It runs a +fixed set of report-only scenarios against the SDK's example executor and prints +a JSON array of per-scenario measurements. + +## What it measures + +The driver covers task, streaming, subscription, push-configuration, and push +notification paths. Each scenario reports: + +- operation counts and success/error totals; +- throughput in operations per second; +- latency percentiles (`p50`, `p90`, `p95`, `p99`) and maximum latency in + milliseconds; +- metadata identifying the transport label, store backend, and SDK dispatch + path. + +Warmup operations run before timing starts, so setup and warmup work are excluded +from performance calculations. During measured execution, each worker records its +own counters and latency samples, then the driver aggregates those samples after +workers finish. This avoids adding result-collection mutex contention to the +measured operation latency. + +## Store backends + +By default, scenarios use the in-memory stores owned by the example executor. To +exercise PostgreSQL-backed stores, run with `--store-backend postgres` and set +`A2A_TEST_POSTGRES_DSN` to a valid connection string. The driver creates a unique +schema name for each PostgreSQL run. + +## Example + +```bash +./build/tests/a2a_performance_driver \ + --transport grpc \ + --store-backend inmemory \ + --requests 1000 \ + --concurrency 4 \ + --warmup-seconds 1 +``` + +For the canonical wrapper and generated summary artifacts, prefer: + +```bash +./scripts/run_performance_tests.sh --store-backends inmemory --requests 1000 --concurrency 1,4 +``` diff --git a/tests/performance/a2a_performance_driver.cpp b/tests/performance/a2a_performance_driver.cpp index c308953..5477732 100644 --- a/tests/performance/a2a_performance_driver.cpp +++ b/tests/performance/a2a_performance_driver.cpp @@ -1,19 +1,22 @@ // SPDX-License-Identifier: Apache-2.0 +#include "a2a_performance_driver.h" + #include #include +#include #include #include #include #include -#include #include #include #include #include #include #include +#include #include #include @@ -25,86 +28,7 @@ #include "a2a/v1/a2a.pb.h" #include "example_support/example_support.h" -namespace { -constexpr std::string_view kGrpcTransport = "grpc"; -constexpr std::string_view kJsonRpcTransport = "jsonrpc"; -constexpr std::string_view kHttpJsonTransport = "http_json"; -constexpr std::string_view kInMemoryStore = "inmemory"; -constexpr std::string_view kPostgresStore = "postgres"; -constexpr std::string_view kDriverType = "cpp_sdk_in_process"; -constexpr double kNanosecondsPerMillisecond = 1000000.0; -constexpr double kMinElapsedSeconds = 0.000001; -constexpr int kDefaultRequests = 1000; -constexpr int kDefaultConcurrency = 1; -constexpr int kListPageSize = 10; -constexpr int kPushConfigFanout = 8; -constexpr int kMultiSubscriberCount = 3; -constexpr int kDisconnectSubscriberCount = 2; -constexpr int kHttpStatusOk = 200; -constexpr int kUsageExitCode = 2; -constexpr double kP50 = 50.0; -constexpr double kP90 = 90.0; -constexpr double kP95 = 95.0; -constexpr double kP99 = 99.0; -constexpr std::size_t kIdReserveSlack = 16U; -constexpr std::string_view kSdkTransportPathPrefix = "sdk_"; -constexpr std::string_view kServerDispatchSuffix = "_server_dispatch"; -constexpr char kPostgresDsnEnv[] = "A2A_TEST_POSTGRES_DSN"; -constexpr std::string_view kPerfSchemaPrefix = "a2a_perf_"; - -const std::vector& Scenarios() { - static const std::vector scenarios = {"SendMessage_CreateTask", - "GetTask_ExistingTask", - "CancelTask_WorkingTask", - "ListTasks_NoPagination", - "ListTasks_WithPagination", - "SendMessage_FollowUpExistingTask", - "GetTask_MissingTaskError", - "SendStreamingMessage_FiniteStream", - "SubscribeToTask_FirstEventLatency", - "SubscribeToTask_MultiSubscriber", - "SubscribeToTask_TerminalCompletionLatency", - "SubscribeToTask_DisconnectOneSubscriber", - "PushConfig_Create", - "PushConfig_Get", - "PushConfig_List", - "PushConfig_Delete", - "PushNotify_ManyConfigsOneTaskUpdate", - "PushDelivery_CallbackLatency"}; - return scenarios; -} - -class RecordingPushDelivery final : public a2a::server::PushNotificationDeliveryClient { - public: - a2a::core::Result Deliver(const a2a::server::PushDeliveryRequest& request) override { - (void)request; - std::lock_guard lock(mutex_); - ++deliveries_; - return a2a::server::PushDeliveryResult{.http_status = kHttpStatusOk, .error_message = {}}; - } - - private: - std::mutex mutex_; - int deliveries_ = 0; -}; - -struct Options final { - std::string transport = std::string(kGrpcTransport); - std::string store_backend = std::string(kInMemoryStore); - int requests = kDefaultRequests; - int concurrency = kDefaultConcurrency; - double warmup_seconds = 0.0; - double duration_seconds = 0.0; -}; - -struct ScenarioResult final { - std::string scenario; - int operations = 0; - int success = 0; - int errors = 0; - double throughput = 0.0; - std::vector latencies; -}; +namespace a2a::tests::performance { double Percentile(const std::vector& sorted_values, double percentile) { if (sorted_values.empty()) { @@ -115,13 +39,13 @@ double Percentile(const std::vector& sorted_values, double percentile) { return sorted_values[std::min(index, sorted_values.size() - 1U)]; } -lf::a2a::v1::SendMessageRequest MakeSendRequest(std::string_view message_id, std::string_view task_id = {}) { +lf::a2a::v1::SendMessageRequest MakeSendRequest(std::string_view message_id, std::string_view task_id) { lf::a2a::v1::SendMessageRequest request; request.mutable_message()->set_message_id(std::string(message_id)); if (!task_id.empty()) { request.mutable_message()->set_task_id(std::string(task_id)); } - request.mutable_message()->add_parts()->set_text("hello"); + request.mutable_message()->add_parts()->set_text(std::string(kMessageText)); return request; } @@ -129,10 +53,37 @@ lf::a2a::v1::TaskPushNotificationConfig MakePushConfig(std::string_view task_id, lf::a2a::v1::TaskPushNotificationConfig config; config.set_task_id(std::string(task_id)); config.set_id(std::string(config_id)); - config.set_url("http://127.0.0.1/fake-push-callback"); + config.set_url(std::string(kPushCallbackUrl)); return config; } +std::string BuildId(std::string_view prefix, int index) { + std::string value; + value.reserve(prefix.size() + kIdReserveSlack); + value.append(prefix); + value.push_back('-'); + value.append(std::to_string(index)); + return value; +} + +} // namespace a2a::tests::performance + +namespace { + +using namespace a2a::tests::performance; + +class RecordingPushDelivery final : public a2a::server::PushNotificationDeliveryClient { + public: + a2a::core::Result Deliver(const a2a::server::PushDeliveryRequest& request) override { + (void)request; + deliveries_.fetch_add(1, std::memory_order_relaxed); + return a2a::server::PushDeliveryResult{.http_status = kHttpStatusOk, .error_message = {}}; + } + + private: + std::atomic deliveries_{0}; +}; + class ScenarioHarness final { public: explicit ScenarioHarness(std::string_view store_backend) { @@ -189,30 +140,30 @@ class ScenarioHarness final { } std::optional ExecuteTaskScenario(std::string_view scenario, int index, a2a::server::RequestContext& context) { - if (scenario == "SendMessage_CreateTask") { + if (scenario == kScenarioSendMessageCreateTask) { return executor_->SendMessage(MakeSendRequest(BuildId("create", index)), context).ok(); } - if (scenario == "GetTask_ExistingTask") { + if (scenario == kScenarioGetTaskExistingTask) { lf::a2a::v1::GetTaskRequest request; request.set_id(existing_task_id_); return executor_->GetTask(request, context).ok(); } - if (scenario == "CancelTask_WorkingTask") { + if (scenario == kScenarioCancelTaskWorkingTask) { const std::string task_id = SeedTask(BuildId("cancel", index)); lf::a2a::v1::CancelTaskRequest request; request.set_id(task_id); return executor_->CancelTask(request, context).ok(); } - if (scenario == "ListTasks_NoPagination") { + if (scenario == kScenarioListTasksNoPagination) { return ListTasks(/*use_pagination=*/false, context); } - if (scenario == "ListTasks_WithPagination") { + if (scenario == kScenarioListTasksWithPagination) { return ListTasks(/*use_pagination=*/true, context); } - if (scenario == "SendMessage_FollowUpExistingTask") { + if (scenario == kScenarioSendMessageFollowUpExistingTask) { return executor_->SendMessage(MakeSendRequest(BuildId("follow", index), existing_task_id_), context).ok(); } - if (scenario == "GetTask_MissingTaskError") { + if (scenario == kScenarioGetTaskMissingTaskError) { lf::a2a::v1::GetTaskRequest request; request.set_id(BuildId("missing", index)); return !executor_->GetTask(request, context).ok(); @@ -222,43 +173,43 @@ class ScenarioHarness final { std::optional ExecuteStreamingScenario(std::string_view scenario, int index, a2a::server::RequestContext& context) { - if (scenario == "SendStreamingMessage_FiniteStream") { + if (scenario == kScenarioSendStreamingMessageFiniteStream) { return SendAndDrainStream(BuildId("stream", index), context); } - if (scenario == "SubscribeToTask_FirstEventLatency") { + if (scenario == kScenarioSubscribeToTaskFirstEventLatency) { return SubscribeOnce(context); } - if (scenario == "SubscribeToTask_MultiSubscriber") { + if (scenario == kScenarioSubscribeToTaskMultiSubscriber) { return SubscribeMany(kMultiSubscriberCount, context); } - if (scenario == "SubscribeToTask_TerminalCompletionLatency") { + if (scenario == kScenarioSubscribeToTaskTerminalCompletionLatency) { return SendAndDrainStream(BuildId("terminal", index), context); } - if (scenario == "SubscribeToTask_DisconnectOneSubscriber") { + if (scenario == kScenarioSubscribeToTaskDisconnectOneSubscriber) { return SubscribeMany(kDisconnectSubscriberCount, context); } return std::nullopt; } std::optional ExecutePushScenario(std::string_view scenario, int index, a2a::server::RequestContext& context) { - if (scenario == "PushConfig_Create") { + if (scenario == kScenarioPushConfigCreate) { return executor_ ->CreateTaskPushNotificationConfig(MakePushConfig(existing_task_id_, BuildId("cfg-create", index)), context) .ok(); } - if (scenario == "PushConfig_Get") { + if (scenario == kScenarioPushConfigGet) { return GetPushConfig(context); } - if (scenario == "PushConfig_List") { + if (scenario == kScenarioPushConfigList) { return ListPushConfigs(context); } - if (scenario == "PushConfig_Delete") { + if (scenario == kScenarioPushConfigDelete) { return DeletePushConfig(BuildId("cfg-delete", index), context); } - if (scenario == "PushNotify_ManyConfigsOneTaskUpdate") { + if (scenario == kScenarioPushNotifyManyConfigsOneTaskUpdate) { return NotifyPushConfigs(index, context); } - if (scenario == "PushDelivery_CallbackLatency") { + if (scenario == kScenarioPushDeliveryCallbackLatency) { return NotifyPushConfigs(index, context); } return std::nullopt; @@ -325,14 +276,6 @@ class ScenarioHarness final { return schema; } - static std::string BuildId(std::string_view prefix, int index) { - std::string value; - value.reserve(prefix.size() + kIdReserveSlack); - value.append(prefix); - value.push_back('-'); - value.append(std::to_string(index)); - return value; - } std::string SeedTask(std::string_view message_id) { a2a::server::RequestContext context; auto response = executor_->SendMessage(MakeSendRequest(message_id), context); @@ -386,38 +329,59 @@ ScenarioResult RunScenario(const Options& options, const std::string& scenario) while (std::chrono::steady_clock::now() < warmup_end) { (void)harness.Execute(scenario, warmup_index++); } + + struct ThreadResult final { + int success = 0; + int errors = 0; + std::vector latencies; + }; + + const int worker_count = std::min(options.concurrency, options.requests); + std::atomic next_index{0}; + std::vector thread_results(static_cast(worker_count)); + std::vector workers; + workers.reserve(static_cast(worker_count)); + + const auto started = std::chrono::steady_clock::now(); + for (int worker_index = 0; worker_index < worker_count; ++worker_index) { + workers.emplace_back([&harness, &next_index, &options, &scenario, &thread_results, worker_index]() { + auto& thread_result = thread_results[static_cast(worker_index)]; + const int reserve_count = (options.requests + options.concurrency - 1) / options.concurrency; + thread_result.latencies.reserve(static_cast(reserve_count)); + for (;;) { + const int operation_index = next_index.fetch_add(1, std::memory_order_relaxed); + if (operation_index >= options.requests) { + return; + } + const auto op_started = std::chrono::steady_clock::now(); + const bool ok = harness.Execute(scenario, operation_index); + const auto op_finished = std::chrono::steady_clock::now(); + const double latency = + static_cast( + std::chrono::duration_cast(op_finished - op_started).count()) / + kNanosecondsPerMillisecond; + if (ok) { + ++thread_result.success; + thread_result.latencies.push_back(latency); + } else { + ++thread_result.errors; + } + } + }); + } + for (auto& worker : workers) { + worker.join(); + } + ScenarioResult result; result.scenario = scenario; result.operations = options.requests; result.latencies.reserve(static_cast(options.requests)); - std::mutex result_mutex; - const auto started = std::chrono::steady_clock::now(); - auto operation = [&](int index) { - const auto op_started = std::chrono::steady_clock::now(); - const bool ok = harness.Execute(scenario, index); - const auto op_finished = std::chrono::steady_clock::now(); - const double latency = - static_cast(std::chrono::duration_cast(op_finished - op_started).count()) / - kNanosecondsPerMillisecond; - std::lock_guard lock(result_mutex); - if (ok) { - ++result.success; - result.latencies.push_back(latency); - } else { - ++result.errors; - } - }; - std::vector> futures; - futures.reserve(static_cast(options.concurrency)); - for (int index = 0; index < options.requests; ++index) { - futures.push_back(std::async(std::launch::async, operation, index)); - if (futures.size() >= static_cast(options.concurrency)) { - futures.front().get(); - futures.erase(futures.begin()); - } - } - for (auto& future : futures) { - future.get(); + for (auto& thread_result : thread_results) { + result.success += thread_result.success; + result.errors += thread_result.errors; + result.latencies.insert(result.latencies.end(), std::make_move_iterator(thread_result.latencies.begin()), + std::make_move_iterator(thread_result.latencies.end())); } const auto elapsed = std::chrono::duration(std::chrono::steady_clock::now() - started).count(); result.throughput = static_cast(result.success) / std::max(elapsed, kMinElapsedSeconds); @@ -517,8 +481,8 @@ int main(int argc, char** argv) { } std::cout << "[\n"; bool first = true; - for (const auto& scenario : Scenarios()) { - WriteResultJson(options, RunScenario(options, scenario), first); + for (const std::string_view scenario : kScenarios) { + WriteResultJson(options, RunScenario(options, std::string(scenario)), first); first = false; } std::cout << "\n]\n"; diff --git a/tests/performance/a2a_performance_driver.h b/tests/performance/a2a_performance_driver.h new file mode 100644 index 0000000..49089d2 --- /dev/null +++ b/tests/performance/a2a_performance_driver.h @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include +#include +#include + +#include "a2a/v1/a2a.pb.h" + +namespace a2a::tests::performance { + +constexpr std::string_view kGrpcTransport = "grpc"; +constexpr std::string_view kJsonRpcTransport = "jsonrpc"; +constexpr std::string_view kHttpJsonTransport = "http_json"; +constexpr std::string_view kInMemoryStore = "inmemory"; +constexpr std::string_view kPostgresStore = "postgres"; +constexpr std::string_view kDriverType = "cpp_sdk_in_process"; +constexpr double kNanosecondsPerMillisecond = 1000000.0; +constexpr double kMinElapsedSeconds = 0.000001; +constexpr int kDefaultRequests = 1000; +constexpr int kDefaultConcurrency = 1; +constexpr int kListPageSize = 10; +constexpr int kPushConfigFanout = 8; +constexpr int kMultiSubscriberCount = 3; +constexpr int kDisconnectSubscriberCount = 2; +constexpr int kHttpStatusOk = 200; +constexpr int kUsageExitCode = 2; +constexpr double kP50 = 50.0; +constexpr double kP90 = 90.0; +constexpr double kP95 = 95.0; +constexpr double kP99 = 99.0; +constexpr std::size_t kIdReserveSlack = 16U; +constexpr std::string_view kSdkTransportPathPrefix = "sdk_"; +constexpr std::string_view kServerDispatchSuffix = "_server_dispatch"; +constexpr char kPostgresDsnEnv[] = "A2A_TEST_POSTGRES_DSN"; +constexpr std::string_view kPerfSchemaPrefix = "a2a_perf_"; +constexpr std::string_view kMessageText = "hello"; +constexpr std::string_view kPushCallbackUrl = "http://127.0.0.1/fake-push-callback"; + +constexpr std::string_view kScenarioSendMessageCreateTask = "SendMessage_CreateTask"; +constexpr std::string_view kScenarioGetTaskExistingTask = "GetTask_ExistingTask"; +constexpr std::string_view kScenarioCancelTaskWorkingTask = "CancelTask_WorkingTask"; +constexpr std::string_view kScenarioListTasksNoPagination = "ListTasks_NoPagination"; +constexpr std::string_view kScenarioListTasksWithPagination = "ListTasks_WithPagination"; +constexpr std::string_view kScenarioSendMessageFollowUpExistingTask = "SendMessage_FollowUpExistingTask"; +constexpr std::string_view kScenarioGetTaskMissingTaskError = "GetTask_MissingTaskError"; +constexpr std::string_view kScenarioSendStreamingMessageFiniteStream = "SendStreamingMessage_FiniteStream"; +constexpr std::string_view kScenarioSubscribeToTaskFirstEventLatency = "SubscribeToTask_FirstEventLatency"; +constexpr std::string_view kScenarioSubscribeToTaskMultiSubscriber = "SubscribeToTask_MultiSubscriber"; +constexpr std::string_view kScenarioSubscribeToTaskTerminalCompletionLatency = + "SubscribeToTask_TerminalCompletionLatency"; +constexpr std::string_view kScenarioSubscribeToTaskDisconnectOneSubscriber = "SubscribeToTask_DisconnectOneSubscriber"; +constexpr std::string_view kScenarioPushConfigCreate = "PushConfig_Create"; +constexpr std::string_view kScenarioPushConfigGet = "PushConfig_Get"; +constexpr std::string_view kScenarioPushConfigList = "PushConfig_List"; +constexpr std::string_view kScenarioPushConfigDelete = "PushConfig_Delete"; +constexpr std::string_view kScenarioPushNotifyManyConfigsOneTaskUpdate = "PushNotify_ManyConfigsOneTaskUpdate"; +constexpr std::string_view kScenarioPushDeliveryCallbackLatency = "PushDelivery_CallbackLatency"; + +constexpr std::array kScenarios = { + kScenarioSendMessageCreateTask, + kScenarioGetTaskExistingTask, + kScenarioCancelTaskWorkingTask, + kScenarioListTasksNoPagination, + kScenarioListTasksWithPagination, + kScenarioSendMessageFollowUpExistingTask, + kScenarioGetTaskMissingTaskError, + kScenarioSendStreamingMessageFiniteStream, + kScenarioSubscribeToTaskFirstEventLatency, + kScenarioSubscribeToTaskMultiSubscriber, + kScenarioSubscribeToTaskTerminalCompletionLatency, + kScenarioSubscribeToTaskDisconnectOneSubscriber, + kScenarioPushConfigCreate, + kScenarioPushConfigGet, + kScenarioPushConfigList, + kScenarioPushConfigDelete, + kScenarioPushNotifyManyConfigsOneTaskUpdate, + kScenarioPushDeliveryCallbackLatency, +}; + +struct Options final { + std::string transport = std::string(kGrpcTransport); + std::string store_backend = std::string(kInMemoryStore); + int requests = kDefaultRequests; + int concurrency = kDefaultConcurrency; + double warmup_seconds = 0.0; + double duration_seconds = 0.0; +}; + +struct ScenarioResult final { + std::string scenario; + int operations = 0; + int success = 0; + int errors = 0; + double throughput = 0.0; + std::vector latencies; +}; + +[[nodiscard]] lf::a2a::v1::SendMessageRequest MakeSendRequest(std::string_view message_id, + std::string_view task_id = {}); +[[nodiscard]] lf::a2a::v1::TaskPushNotificationConfig MakePushConfig(std::string_view task_id, + std::string_view config_id); +[[nodiscard]] std::string BuildId(std::string_view prefix, int index); +[[nodiscard]] double Percentile(const std::vector& sorted_values, double percentile); + +} // namespace a2a::tests::performance From da0f2c16fbffefb15ed690ed3da3802cbc818037 Mon Sep 17 00:00:00 2001 From: Vladimir Pavlov Date: Thu, 9 Jul 2026 16:52:19 +0300 Subject: [PATCH 2/2] fix: increase perf tests load --- .github/workflows/ci.yml | 2 +- docs/performance-testing.md | 4 ++-- scripts/performance_runner.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c15e9e..6b30133 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,7 +130,7 @@ jobs: env: A2A_PERF_TRANSPORTS: grpc,jsonrpc,http_json A2A_PERF_STORE_BACKENDS: inmemory,postgres - A2A_PERF_REQUESTS: 1000 + A2A_PERF_REQUESTS: 2000 A2A_PERF_CONCURRENCY: 1,4 A2A_PERF_WARMUP_SECONDS: 0 A2A_PERF_REPORT_DIR: perf-artifacts diff --git a/docs/performance-testing.md b/docs/performance-testing.md index b6eca96..c94a5e2 100644 --- a/docs/performance-testing.md +++ b/docs/performance-testing.md @@ -29,7 +29,7 @@ matching environment variables. | --- | --- | --- | | Transports (`grpc`, `jsonrpc`, `http_json`, or `all`) | `A2A_PERF_TRANSPORTS` | `grpc,jsonrpc,http_json` | | Store backends (`inmemory`, `postgres`, or `all`) | `A2A_PERF_STORE_BACKENDS` | `inmemory,postgres` | -| Operations per result row | `A2A_PERF_REQUESTS` | `1000` | +| Operations per result row | `A2A_PERF_REQUESTS` | `2000` | | Concurrency levels | `A2A_PERF_CONCURRENCY` | `1,4` | | Warmup seconds | `A2A_PERF_WARMUP_SECONDS` | `1` | | Duration seconds metadata | `A2A_PERF_DURATION_SECONDS` | `0` | @@ -88,7 +88,7 @@ enforce latency or throughput thresholds. ```bash A2A_PERF_TRANSPORTS=grpc,jsonrpc,http_json \ A2A_PERF_STORE_BACKENDS=inmemory,postgres \ -A2A_PERF_REQUESTS=1000 \ +A2A_PERF_REQUESTS=2000 \ A2A_PERF_CONCURRENCY=1,4,16,64 \ A2A_PERF_WARMUP_SECONDS=5 \ A2A_PERF_REPORT_DIR=perf-artifacts \ diff --git a/scripts/performance_runner.py b/scripts/performance_runner.py index 5f4e89e..7a39f36 100755 --- a/scripts/performance_runner.py +++ b/scripts/performance_runner.py @@ -40,7 +40,7 @@ "PushNotify_ManyConfigsOneTaskUpdate", "PushDelivery_CallbackLatency", ) -DEFAULT_REQUESTS = 10_000 +DEFAULT_REQUESTS = 2_000 DEFAULT_CONCURRENCY = (1, 4) DEFAULT_BUILD_DIR = "build/performance" DRIVER_NAME = "a2a_performance_driver"