Skip to content

Make blocking performance test measure throughput - #8160

Open
Eddy Ashton (eddyashton) wants to merge 1 commit into
mainfrom
agents/blocking-perf-mkii-tweaks
Open

Make blocking performance test measure throughput#8160
Eddy Ashton (eddyashton) wants to merge 1 commit into
mainfrom
agents/blocking-perf-mkii-tweaks

Conversation

@eddyashton

@eddyashton Eddy Ashton (eddyashton) commented Aug 14, 2026

Copy link
Copy Markdown
Member

Summary

Update pi_basic_blocking from a basic load test that showed blocking responses could handle some concurrency into a useful measure of blocking transaction throughput.

The previous test launched one synchronous submitter process per logical client. With 128 processes, 100 requests per client, and a 100ms signature interval, it was dominated by signature cadence and client process overhead. Its roughly 1,200 tx/s result mostly confirmed that blocking requests completed under load rather than measuring the throughput the service can sustain with blocking enabled.

This change adds an event-driven, multi-session mode to the Piccolo submitter. Each process drives multiple independent logical sessions through libcurl-multi/libuv while preserving one blocking request in flight and one persistent HTTP/1.1 connection per session. This reduces the physical client count from hundreds of processes to a small number of event loops without reducing logical concurrency.

The updated blocking benchmark uses:

  • 320 logical sessions across 10 submitter processes
  • 2,000 blocking writes per session
  • a 2ms signature interval
  • explicit connection-pool sizing so all session connections remain persistent

On the development machine, the updated workload completed 640,000 requests without errors at approximately 27,500-29,000 tx/s, compared with an approximately 1,200 tx/s baseline.

Additional changes

  • Preserve the existing synchronous submitter path for pipelined and failover tests.
  • Keep generated and result parquet schemas compatible while batching logical-session workloads into fewer processes.
  • Report p50, p90, and p99 latency alongside throughput.
  • Expose blocking workload, signature cadence, and optional CPU-affinity settings as CMake parameters.
  • Validate unsupported multi-session option combinations and terminate cleanly if a queued request cannot be scheduled.

Validation

  • Built the submit and curl_test targets.
  • Passed the extended e2e_curl fixture, including persistent-handle reuse and callback-failure regression coverage.
  • Passed the optimized blocking performance workload and legacy synchronous submitter path during performance validation.
  • Passed C++, Python, CMake, include, copyright, ASCII, and whitespace checks.

…g perf test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eddyashton
Eddy Ashton (eddyashton) requested a review from a team as a code owner August 14, 2026 13:44
Copilot AI lite review requested due to automatic review settings August 14, 2026 13:44
@eddyashton Eddy Ashton (eddyashton) changed the title Refactor submitter to fix concurrency issues and improve performance Refactor perf submitter to manager multiple sessions, tweak parameters for blocking perf test Aug 14, 2026
@eddyashton Eddy Ashton (eddyashton) changed the title Refactor perf submitter to manager multiple sessions, tweak parameters for blocking perf test Make blocking performance test measure throughput Aug 14, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the perf submitter to support driving multiple logical HTTP sessions concurrently (libcurl multi + libuv), and updates the perf harness to batch multiple logical clients into a single submitter process for blocking perf runs. It also strengthens option validation (multi-session vs failover), improves Arrow Parquet parsing to support additional column types, and adds regression coverage for curl handle reuse and callback failures.

Changes:

  • Add a multi-session async submit path in submit.cpp (per-session request queues, curl easy-handle reuse, libuv loop integration).
  • Extend the workload Parquet format to optionally include sessionID, and update the perf harness to generate/propagate it and batch clients per process.
  • Add regression tests for (a) reused easy handles clearing missing header lists and (b) submitter robustness when callbacks fail.

Custom instructions used:

  • .github/copilot-instructions.md
  • .github/instructions/reviewing.instructions.md

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/perf-system/submitter/submit.cpp Adds multi-session submitter (curl+uv) and validates multi-session CLI constraints.
tests/perf-system/submitter/parquet_data.h Extends perf workload data model to include per-request session_ids.
tests/perf-system/submitter/handle_arguments.h Adds --multi-session flag and improves help text wrapping.
tests/perf-system/submitter/CMakeLists.txt Links submitter against curl + libuv to support the async multi-session path.
tests/infra/basicperf.py Batches multiple logical clients per submitter process, adds CPU affinity support, and updates reporting to use sessionID.
tests/e2e_curl.py Adds an end-to-end regression that the submitter doesn’t hang on callback failure; uses a DELETE request to trigger the failure.
src/http/test/curl_test.cpp Adds a regression ensuring reused easy handles clear absent CURLOPT_HTTPHEADER lists.
src/http/curl.h Always sets CURLOPT_HTTPHEADER (including null) to prevent stale header pointers; adds easy-handle extraction and connection-limit helper.
CMakeLists.txt Adds tunables for the blocking perf test (client counts, per-process batching, sig intervals, affinity args).
Suppressed comments (2)

tests/perf-system/submitter/submit.cpp:596

  • curl_context is created but never referenced, which is likely to trigger -Wunused-variable under -Wextra -Werror. Since you already added set_connection_limits, call it directly on curl_context (rather than via get_instance()) to both use the object and avoid reliance on the singleton accessor here.
      ccf::curl::CurlmLibuvContextSingleton curl_context(loop);
      ccf::curl::CurlmLibuvContextSingleton::get_instance()
        ->set_connection_limits(pending.size());

tests/perf-system/submitter/submit.cpp:604

  • The structured binding element _ is unused. With -Wextra -Werror, this is likely to fail compilation as an unused variable. Bind it to a named variable and explicitly ignore it (or iterate over keys only).
      for (const auto& [session_id, _] : pending)
      {
        try
        {
          submit_next(session_id, ccf::curl::UniqueCURL(), true);

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

"Failed to initialise curl: {}",
curl_easy_strerror(curl_init_result)));
}
const CurlGlobalCleanup curl_cleanup;
Comment thread tests/infra/basicperf.py
Comment on lines +302 to +308
if args.clients_per_process <= 0:
raise ValueError("--clients-per-process must be positive")
if args.stop_primary_after_s and args.clients_per_process != 1:
raise ValueError(
"Failover tests require --clients-per-process=1 because the "
"multi-session submitter does not support failover"
)
@eddyashton

Copy link
Copy Markdown
Member Author

I think we prefer #8158 for this - off-the-shelf tooling, avoid awkward barely-used multi-session options for our explicitly pipeline-friendly submitter. Would be good to confirm that both approaches have similar results at similar parameters, or at least similar curve shapes? And then we can discuss what a "sensible" sig-ms-interval is, given it remains the dominant lever for controlling latency.

@achamayou

Copy link
Copy Markdown
Member

@eddyasthon agreed, if there the numbers are substantially different, we want to understand why.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants