From 0c9475bb8a28d92adf4483f2e15db55c0cbc43ea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 07:36:25 +0000 Subject: [PATCH 01/25] Initial plan From 429c9cc56a9654ca0d6cfc7c9ac0dbdf22a49fe4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 07:42:47 +0000 Subject: [PATCH 02/25] ci: Replace pytest-benchmark with pytest-codspeed and improve benchmarks - Replace pytest-benchmark with pytest-codspeed in test dependencies - Rewrite benchmark tests to use @pytest.mark.benchmark decorator - Add full process lifecycle benchmark (init + run + destroy) - Parameterize benchmarks across AsyncioConnector and ZMQConnector - Replace GitHub Actions workflow with CodSpeed integration Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com> Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/b8d70f1d-7f6f-412b-9452-e70611a349de --- .github/workflows/benchmarks.yaml | 72 +++++++--------------------- pyproject.toml | 2 +- tests/benchmark/test_benchmarking.py | 70 ++++++++++++++++++--------- uv.lock | 58 ++++++++++++---------- 4 files changed, 98 insertions(+), 104 deletions(-) diff --git a/.github/workflows/benchmarks.yaml b/.github/workflows/benchmarks.yaml index fa1b8480f..ddbbdf7de 100644 --- a/.github/workflows/benchmarks.yaml +++ b/.github/workflows/benchmarks.yaml @@ -1,83 +1,45 @@ name: Benchmarks on: + push: + branches: + - main pull_request: types: - opened - synchronize + # `workflow_dispatch` allows CodSpeed to trigger backtest + # performance analysis in order to generate initial data. + workflow_dispatch: jobs: benchmark: - name: Benchmark tests + name: Run benchmarks runs-on: ubuntu-latest permissions: contents: read - pull-requests: write - strategy: - matrix: - python_version: [3.12] + id-token: write steps: - - name: Checkout branch + - name: Checkout uses: actions/checkout@v4 - with: - path: pr - - - name: Checkout main - uses: actions/checkout@v4 - with: - ref: main - path: main - name: Install python uses: actions/setup-python@v5 with: - python-version: ${{matrix.python_version}} + python-version: "3.12" - name: Install uv uses: astral-sh/setup-uv@v4 with: enable-cache: true - cache-dependency-glob: "main/uv.lock" - - - name: Setup benchmarks - run: | - echo "BASE_SHA=$(echo ${{ github.event.pull_request.base.sha }} | cut -c1-8)" >> $GITHUB_ENV - echo "HEAD_SHA=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-8)" >> $GITHUB_ENV - echo "PR_COMMENT=$(mktemp)" >> $GITHUB_ENV - - - name: Run benchmarks on PR - working-directory: ./pr - run: | - uv sync --group test - uv run pytest --benchmark-only --benchmark-save=pr - - - name: Run benchmarks on main - working-directory: ./main - continue-on-error: true - run: | - uv sync --group test - uv run pytest --benchmark-only --benchmark-save=base + cache-dependency-glob: "uv.lock" - - name: Compare results - continue-on-error: false - run: | - uvx pytest-benchmark compare **/.benchmarks/**/*.json | tee cmp_results + - name: Install project + run: uv sync --group test - echo 'Benchmark comparison for [`${{ env.BASE_SHA }}`](${{ github.event.repository.html_url }}/commit/${{ github.event.pull_request.base.sha }}) (base) vs [`${{ env.HEAD_SHA }}`](${{ github.event.repository.html_url }}/commit/${{ github.event.pull_request.head.sha }}) (PR)' >> pr_comment - echo '```' >> pr_comment - cat cmp_results >> pr_comment - echo '```' >> pr_comment - cat pr_comment > ${{ env.PR_COMMENT }} - - - name: Comment on PR - uses: actions/github-script@v7 + - name: Run benchmarks + uses: CodSpeedHQ/action@v4 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: require('fs').readFileSync('${{ env.PR_COMMENT }}').toString() - }); + mode: walltime + run: uv run pytest tests/benchmark/ --codspeed diff --git a/pyproject.toml b/pyproject.toml index 3b5786c27..e7c09cfa9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,7 +80,7 @@ test = [ "optuna>=3.0,<5", "pytest>=8.3,<10", "pytest-asyncio>=1.0,<2", - "pytest-benchmark>=5.1.0", + "pytest-codspeed>=4.3.0", "pytest-cases>=3.8,<4", "pytest-env>=1.1,<2", "pytest-rerunfailures>=15.0,<17", diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 7554a7a0f..051ea1cbd 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -1,35 +1,61 @@ -"""Simple benchmark tests for Plugboard models.""" +"""Benchmark tests for Plugboard processes.""" import asyncio -from pytest_benchmark.fixture import BenchmarkFixture +import pytest -from plugboard.connector import AsyncioConnector -from plugboard.process import LocalProcess, Process +from plugboard.connector import AsyncioConnector, Connector, ZMQConnector +from plugboard.process import LocalProcess from plugboard.schemas import ConnectorSpec from tests.integration.test_process_with_components_run import A, B -def _setup_process() -> tuple[tuple[Process], dict]: - comp_a = A(name="comp_a", iters=1000) +ITERS = 1000 + + +def _build_process(connector_cls: type[Connector]) -> LocalProcess: + """Build a process with the given connector class.""" + comp_a = A(name="comp_a", iters=ITERS) comp_b1 = B(name="comp_b1", factor=1) comp_b2 = B(name="comp_b2", factor=2) components = [comp_a, comp_b1, comp_b2] connectors = [ - AsyncioConnector(spec=ConnectorSpec(source="comp_a.out_1", target="comp_b1.in_1")), - AsyncioConnector(spec=ConnectorSpec(source="comp_b1.out_1", target="comp_b2.in_1")), + connector_cls(spec=ConnectorSpec(source="comp_a.out_1", target="comp_b1.in_1")), + connector_cls(spec=ConnectorSpec(source="comp_b1.out_1", target="comp_b2.in_1")), ] - process = LocalProcess(components=components, connectors=connectors) - # Initialise process so that this is excluded from the benchmark timing - asyncio.run(process.init()) - # Return args and kwargs tuple for benchmark.pedantic - return (process,), {} - - -def _run_process(process: Process) -> None: - asyncio.run(process.run()) - - -def test_benchmark_process_run(benchmark: BenchmarkFixture) -> None: - """Benchmark the running of a Plugboard Process.""" - benchmark.pedantic(_run_process, setup=_setup_process, rounds=5) + return LocalProcess(components=components, connectors=connectors) + + +@pytest.mark.benchmark +@pytest.mark.parametrize( + "connector_cls", + [AsyncioConnector, ZMQConnector], + ids=["asyncio", "zmq"], +) +def test_benchmark_process_run(connector_cls: type[Connector]) -> None: + """Benchmark the init and run of a Plugboard Process.""" + + async def _run() -> None: + process = _build_process(connector_cls) + await process.init() + await process.run() + + asyncio.run(_run()) + + +@pytest.mark.benchmark +@pytest.mark.parametrize( + "connector_cls", + [AsyncioConnector, ZMQConnector], + ids=["asyncio", "zmq"], +) +def test_benchmark_process_lifecycle(connector_cls: type[Connector]) -> None: + """Benchmark the full lifecycle (init, run, destroy) of a Plugboard Process.""" + + async def _lifecycle() -> None: + process = _build_process(connector_cls) + await process.init() + await process.run() + await process.destroy() + + asyncio.run(_lifecycle()) diff --git a/uv.lock b/uv.lock index 4372bd4b8..c4f1415aa 100644 --- a/uv.lock +++ b/uv.lock @@ -692,10 +692,16 @@ sdist = { url = "https://files.pythonhosted.org/packages/92/88/b8527e1b00c1811db wheels = [ { url = "https://files.pythonhosted.org/packages/d3/25/79c98ebe12df31548ba4eaf44db11b7cad6b3e7b4203718335620939083c/caio-0.9.25-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:fb7ff95af4c31ad3f03179149aab61097a71fd85e05f89b4786de0359dffd044", size = 36983, upload-time = "2025-12-26T15:21:36.075Z" }, { url = "https://files.pythonhosted.org/packages/a3/2b/21288691f16d479945968a0a4f2856818c1c5be56881d51d4dac9b255d26/caio-0.9.25-cp312-cp312-manylinux2010_x86_64.manylinux2014_x86_64.manylinux_2_12_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:97084e4e30dfa598449d874c4d8e0c8d5ea17d2f752ef5e48e150ff9d240cd64", size = 82012, upload-time = "2025-12-26T15:22:20.983Z" }, + { url = "https://files.pythonhosted.org/packages/03/c4/8a1b580875303500a9c12b9e0af58cb82e47f5bcf888c2457742a138273c/caio-0.9.25-cp312-cp312-manylinux_2_34_aarch64.whl", hash = "sha256:4fa69eba47e0f041b9d4f336e2ad40740681c43e686b18b191b6c5f4c5544bfb", size = 81502, upload-time = "2026-03-04T22:08:22.381Z" }, + { url = "https://files.pythonhosted.org/packages/d1/1c/0fe770b8ffc8362c48134d1592d653a81a3d8748d764bec33864db36319d/caio-0.9.25-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:6bebf6f079f1341d19f7386db9b8b1f07e8cc15ae13bfdaff573371ba0575d69", size = 80200, upload-time = "2026-03-04T22:08:23.382Z" }, { url = "https://files.pythonhosted.org/packages/31/57/5e6ff127e6f62c9f15d989560435c642144aa4210882f9494204bc892305/caio-0.9.25-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d6c2a3411af97762a2b03840c3cec2f7f728921ff8adda53d7ea2315a8563451", size = 36979, upload-time = "2025-12-26T15:21:35.484Z" }, { url = "https://files.pythonhosted.org/packages/a3/9f/f21af50e72117eb528c422d4276cbac11fb941b1b812b182e0a9c70d19c5/caio-0.9.25-cp313-cp313-manylinux2010_x86_64.manylinux2014_x86_64.manylinux_2_12_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0998210a4d5cd5cb565b32ccfe4e53d67303f868a76f212e002a8554692870e6", size = 81900, upload-time = "2025-12-26T15:22:21.919Z" }, + { url = "https://files.pythonhosted.org/packages/9c/12/c39ae2a4037cb10ad5eb3578eb4d5f8c1a2575c62bba675f3406b7ef0824/caio-0.9.25-cp313-cp313-manylinux_2_34_aarch64.whl", hash = "sha256:1a177d4777141b96f175fe2c37a3d96dec7911ed9ad5f02bac38aaa1c936611f", size = 81523, upload-time = "2026-03-04T22:08:25.187Z" }, + { url = "https://files.pythonhosted.org/packages/22/59/f8f2e950eb4f1a5a3883e198dca514b9d475415cb6cd7b78b9213a0dd45a/caio-0.9.25-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:9ed3cfb28c0e99fec5e208c934e5c157d0866aa9c32aa4dc5e9b6034af6286b7", size = 80243, upload-time = "2026-03-04T22:08:26.449Z" }, { url = "https://files.pythonhosted.org/packages/69/ca/a08fdc7efdcc24e6a6131a93c85be1f204d41c58f474c42b0670af8c016b/caio-0.9.25-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fab6078b9348e883c80a5e14b382e6ad6aabbc4429ca034e76e730cf464269db", size = 36978, upload-time = "2025-12-26T15:21:41.055Z" }, { url = "https://files.pythonhosted.org/packages/5e/6c/d4d24f65e690213c097174d26eda6831f45f4734d9d036d81790a27e7b78/caio-0.9.25-cp314-cp314-manylinux2010_x86_64.manylinux2014_x86_64.manylinux_2_12_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:44a6b58e52d488c75cfaa5ecaa404b2b41cc965e6c417e03251e868ecd5b6d77", size = 81832, upload-time = "2025-12-26T15:22:22.757Z" }, + { url = "https://files.pythonhosted.org/packages/87/a4/e534cf7d2d0e8d880e25dd61e8d921ffcfe15bd696734589826f5a2df727/caio-0.9.25-cp314-cp314-manylinux_2_34_aarch64.whl", hash = "sha256:628a630eb7fb22381dd8e3c8ab7f59e854b9c806639811fc3f4310c6bd711d79", size = 81565, upload-time = "2026-03-04T22:08:27.483Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ed/bf81aeac1d290017e5e5ac3e880fd56ee15e50a6d0353986799d1bc5cfd5/caio-0.9.25-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:0ba16aa605ccb174665357fc729cf500679c2d94d5f1458a6f0d5ca48f2060a7", size = 80071, upload-time = "2026-03-04T22:08:28.751Z" }, { url = "https://files.pythonhosted.org/packages/86/93/1f76c8d1bafe3b0614e06b2195784a3765bbf7b0a067661af9e2dd47fc33/caio-0.9.25-py3-none-any.whl", hash = "sha256:06c0bb02d6b929119b1cfbe1ca403c768b2013a369e2db46bfa2a5761cf82e40", size = 19087, upload-time = "2025-12-26T15:22:00.221Z" }, ] @@ -3861,8 +3867,8 @@ all = [ { name = "pre-commit" }, { name = "pytest" }, { name = "pytest-asyncio" }, - { name = "pytest-benchmark" }, { name = "pytest-cases" }, + { name = "pytest-codspeed" }, { name = "pytest-env" }, { name = "pytest-rerunfailures" }, { name = "radon" }, @@ -3907,8 +3913,8 @@ test = [ { name = "optuna" }, { name = "pytest" }, { name = "pytest-asyncio" }, - { name = "pytest-benchmark" }, { name = "pytest-cases" }, + { name = "pytest-codspeed" }, { name = "pytest-env" }, { name = "pytest-rerunfailures" }, { name = "ray", extra = ["default", "tune"] }, @@ -3977,8 +3983,8 @@ all = [ { name = "pre-commit", specifier = ">=3.8,<4" }, { name = "pytest", specifier = ">=8.3,<10" }, { name = "pytest-asyncio", specifier = ">=1.0,<2" }, - { name = "pytest-benchmark", specifier = ">=5.1.0" }, { name = "pytest-cases", specifier = ">=3.8,<4" }, + { name = "pytest-codspeed", specifier = ">=4.3.0" }, { name = "pytest-env", specifier = ">=1.1,<2" }, { name = "pytest-rerunfailures", specifier = ">=15.0,<17" }, { name = "radon", specifier = ">=6.0.1,<7" }, @@ -4023,8 +4029,8 @@ test = [ { name = "optuna", specifier = ">=3.0,<5" }, { name = "pytest", specifier = ">=8.3,<10" }, { name = "pytest-asyncio", specifier = ">=1.0,<2" }, - { name = "pytest-benchmark", specifier = ">=5.1.0" }, { name = "pytest-cases", specifier = ">=3.8,<4" }, + { name = "pytest-codspeed", specifier = ">=4.3.0" }, { name = "pytest-env", specifier = ">=1.1,<2" }, { name = "pytest-rerunfailures", specifier = ">=15.0,<17" }, { name = "ray", extras = ["default", "tune"], specifier = ">=2.40.0,<3" }, @@ -4260,15 +4266,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, ] -[[package]] -name = "py-cpuinfo" -version = "9.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/a8/d832f7293ebb21690860d2e01d8115e5ff6f2ae8bbdc953f0eb0fa4bd2c7/py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690", size = 104716, upload-time = "2022-10-25T20:38:06.303Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5", size = 22335, upload-time = "2022-10-25T20:38:27.636Z" }, -] - [[package]] name = "py-partiql-parser" version = "0.6.3" @@ -4541,19 +4538,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, ] -[[package]] -name = "pytest-benchmark" -version = "5.2.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "py-cpuinfo" }, - { name = "pytest" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/24/34/9f732b76456d64faffbef6232f1f9dbec7a7c4999ff46282fa418bd1af66/pytest_benchmark-5.2.3.tar.gz", hash = "sha256:deb7317998a23c650fd4ff76e1230066a76cb45dcece0aca5607143c619e7779", size = 341340, upload-time = "2025-11-09T18:48:43.215Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/33/29/e756e715a48959f1c0045342088d7ca9762a2f509b945f362a316e9412b7/pytest_benchmark-5.2.3-py3-none-any.whl", hash = "sha256:bc839726ad20e99aaa0d11a127445457b4219bdb9e80a1afc4b51da7f96b0803", size = 45255, upload-time = "2025-11-09T18:48:39.765Z" }, -] - [[package]] name = "pytest-cases" version = "3.9.1" @@ -4569,6 +4553,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/92/82/db006f1d06e5d31805ac47f9ce979937e3d026292f2759543b744f8040be/pytest_cases-3.9.1-py2.py3-none-any.whl", hash = "sha256:60507716650c5ed1ce4a36a3c137f1c3ec58f4fef1ee8678404be074612fcd21", size = 108262, upload-time = "2025-06-09T20:05:01.915Z" }, ] +[[package]] +name = "pytest-codspeed" +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, + { name = "pytest" }, + { name = "rich" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/ab/eca41967d11c95392829a8b4bfa9220a51cffc4a33ec4653358000356918/pytest_codspeed-4.3.0.tar.gz", hash = "sha256:5230d9d65f39063a313ed1820df775166227ec5c20a1122968f85653d5efee48", size = 124745, upload-time = "2026-02-09T15:23:34.745Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/58/50df94e9a78e1c77818a492c90557eeb1309af025120c9a21e6375950c52/pytest_codspeed-4.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527a3a02eaa3e4d4583adc4ba2327eef79628f3e1c682a4b959439551a72588e", size = 347395, upload-time = "2026-02-09T15:23:21.986Z" }, + { url = "https://files.pythonhosted.org/packages/e4/56/7dfbd3eefd112a14e6fb65f9ff31dacf2e9c381cb94b27332b81d2b13f8d/pytest_codspeed-4.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9858c2a6e1f391d5696757e7b6e9484749a7376c46f8b4dd9aebf093479a9667", size = 342625, upload-time = "2026-02-09T15:23:23.035Z" }, + { url = "https://files.pythonhosted.org/packages/7f/53/7255f6a25bc56ff1745b254b21545dfe0be2268f5b91ce78f7e8a908f0ad/pytest_codspeed-4.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34f2fd8497456eefbd325673f677ea80d93bb1bc08a578c1fa43a09cec3d1879", size = 347325, upload-time = "2026-02-09T15:23:23.998Z" }, + { url = "https://files.pythonhosted.org/packages/2e/f8/82ae570d8b9ad30f33c9d4002a7a1b2740de0e090540c69a28e4f711ebe2/pytest_codspeed-4.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df6a36a2a9da1406bc50428437f657f0bd8c842ae54bee5fb3ad30e01d50c0f5", size = 342558, upload-time = "2026-02-09T15:23:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/b3/e1/55cfe9474f91d174c7a4b04d257b5fc6d4d06f3d3680f2da672ee59ccc10/pytest_codspeed-4.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bec30f4fc9c4973143cd80f0d33fa780e9fa3e01e4dbe8cedf229e72f1212c62", size = 347383, upload-time = "2026-02-09T15:23:26.68Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3b/8fd781d959bbe789b3de8ce4c50d5706a684a0df377147dfb27b200c20c1/pytest_codspeed-4.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e6584e641cadf27d894ae90b87c50377232a97cbfd76ee0c7ecd0c056fa3f7f4", size = 342481, upload-time = "2026-02-09T15:23:27.686Z" }, + { url = "https://files.pythonhosted.org/packages/bb/0c/368045133c6effa2c665b1634b7b8a9c88b307f877fa31f1f8df47885b51/pytest_codspeed-4.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df0d1f6ea594f29b745c634d66d5f5f1caa1c3abd2af82fea49d656038e8fc77", size = 353680, upload-time = "2026-02-09T15:23:28.726Z" }, + { url = "https://files.pythonhosted.org/packages/59/21/e543abcd72244294e25ae88ec3a9311ade24d6913f8c8f42569d671700bc/pytest_codspeed-4.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2f5bb6d8898bea7db45e3c8b916ee48e36905b929477bb511b79c5a3ccacda4", size = 347888, upload-time = "2026-02-09T15:23:30.443Z" }, + { url = "https://files.pythonhosted.org/packages/55/d9/b8a53c20cf5b41042c205bb9d36d37da00418d30fd1a94bf9eb147820720/pytest_codspeed-4.3.0-py3-none-any.whl", hash = "sha256:05baff2a61dc9f3e92b92b9c2ab5fb45d9b802438f5373073f5766a91319ed7a", size = 125224, upload-time = "2026-02-09T15:23:33.774Z" }, +] + [[package]] name = "pytest-env" version = "1.2.0" From 6a5f2e9daa2e1ae3ec74044fe50c296ec5977eb5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 20:41:34 +0000 Subject: [PATCH 03/25] Benchmark only process.run(), add RayConnector/RayProcess parametrization - test_benchmark_process_run now uses benchmark.pedantic with setup to only time process.run(), excluding init - Added RayConnector/RayProcess to both benchmark test parametrizations - Added Ray env vars to CI workflow for benchmark tests Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com> Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/2d017dc2-a948-4b46-8c61-c42be32507a4 --- .github/workflows/benchmarks.yaml | 3 ++ tests/benchmark/test_benchmarking.py | 64 +++++++++++++++++++--------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/.github/workflows/benchmarks.yaml b/.github/workflows/benchmarks.yaml index ddbbdf7de..d106b179a 100644 --- a/.github/workflows/benchmarks.yaml +++ b/.github/workflows/benchmarks.yaml @@ -39,6 +39,9 @@ jobs: - name: Run benchmarks uses: CodSpeedHQ/action@v4 + env: + RAY_ENABLE_UV_RUN_RUNTIME_ENV: 0 + PLUGBOARD_IO_READ_TIMEOUT: 5.0 with: mode: walltime run: uv run pytest tests/benchmark/ --codspeed diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 051ea1cbd..15f2acd91 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -3,18 +3,26 @@ import asyncio import pytest +from pytest_codspeed import BenchmarkFixture -from plugboard.connector import AsyncioConnector, Connector, ZMQConnector -from plugboard.process import LocalProcess +from plugboard.connector import AsyncioConnector, Connector, RayConnector, ZMQConnector +from plugboard.process import LocalProcess, Process, RayProcess from plugboard.schemas import ConnectorSpec from tests.integration.test_process_with_components_run import A, B ITERS = 1000 +CONNECTOR_PROCESS_PARAMS = [ + (AsyncioConnector, LocalProcess), + (ZMQConnector, LocalProcess), + (RayConnector, RayProcess), +] +CONNECTOR_PROCESS_IDS = ["asyncio", "zmq", "ray"] -def _build_process(connector_cls: type[Connector]) -> LocalProcess: - """Build a process with the given connector class.""" + +def _build_process(connector_cls: type[Connector], process_cls: type[Process]) -> Process: + """Build a process with the given connector and process class.""" comp_a = A(name="comp_a", iters=ITERS) comp_b1 = B(name="comp_b1", factor=1) comp_b2 = B(name="comp_b2", factor=2) @@ -23,37 +31,51 @@ def _build_process(connector_cls: type[Connector]) -> LocalProcess: connector_cls(spec=ConnectorSpec(source="comp_a.out_1", target="comp_b1.in_1")), connector_cls(spec=ConnectorSpec(source="comp_b1.out_1", target="comp_b2.in_1")), ] - return LocalProcess(components=components, connectors=connectors) + return process_cls(components=components, connectors=connectors) -@pytest.mark.benchmark @pytest.mark.parametrize( - "connector_cls", - [AsyncioConnector, ZMQConnector], - ids=["asyncio", "zmq"], + "connector_cls, process_cls", + CONNECTOR_PROCESS_PARAMS, + ids=CONNECTOR_PROCESS_IDS, ) -def test_benchmark_process_run(connector_cls: type[Connector]) -> None: - """Benchmark the init and run of a Plugboard Process.""" +def test_benchmark_process_run( + benchmark: BenchmarkFixture, + connector_cls: type[Connector], + process_cls: type[Process], + ray_ctx: None, +) -> None: + """Benchmark running of a Plugboard Process.""" - async def _run() -> None: - process = _build_process(connector_cls) - await process.init() - await process.run() + def _setup() -> tuple[tuple[Process], dict]: + async def _init() -> Process: + process = _build_process(connector_cls, process_cls) + await process.init() + return process + + return (asyncio.run(_init()),), {} + + def _run(process: Process) -> None: + asyncio.run(process.run()) - asyncio.run(_run()) + benchmark.pedantic(_run, setup=_setup, rounds=5) @pytest.mark.benchmark @pytest.mark.parametrize( - "connector_cls", - [AsyncioConnector, ZMQConnector], - ids=["asyncio", "zmq"], + "connector_cls, process_cls", + CONNECTOR_PROCESS_PARAMS, + ids=CONNECTOR_PROCESS_IDS, ) -def test_benchmark_process_lifecycle(connector_cls: type[Connector]) -> None: +def test_benchmark_process_lifecycle( + connector_cls: type[Connector], + process_cls: type[Process], + ray_ctx: None, +) -> None: """Benchmark the full lifecycle (init, run, destroy) of a Plugboard Process.""" async def _lifecycle() -> None: - process = _build_process(connector_cls) + process = _build_process(connector_cls, process_cls) await process.init() await process.run() await process.destroy() From 4dac1b54ed44cb19160e5cb41e7006059cf1889c Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Sat, 28 Mar 2026 18:29:28 +0000 Subject: [PATCH 04/25] Use codspeed runners --- .github/workflows/benchmarks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yaml b/.github/workflows/benchmarks.yaml index d106b179a..6c8714c52 100644 --- a/.github/workflows/benchmarks.yaml +++ b/.github/workflows/benchmarks.yaml @@ -15,7 +15,7 @@ on: jobs: benchmark: name: Run benchmarks - runs-on: ubuntu-latest + runs-on: codspeed-macro permissions: contents: read id-token: write From adfd12c742f73bde108001c1550cc704d26d70ff Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Sun, 29 Mar 2026 10:23:20 +0100 Subject: [PATCH 05/25] Add codspeed badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0d8ae78b6..c760b9d9e 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ CodeQL + + CodSpeed Badge
Docs From 6a427e5f7d67f00b75693380c0167e25a8b554bf Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Tue, 31 Mar 2026 22:21:45 +0100 Subject: [PATCH 06/25] Remove run-only tests and keep full lifecycle tests --- tests/benchmark/test_benchmarking.py | 44 ++++------------------------ 1 file changed, 5 insertions(+), 39 deletions(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 15f2acd91..96e179be2 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -1,9 +1,6 @@ """Benchmark tests for Plugboard processes.""" -import asyncio - import pytest -from pytest_codspeed import BenchmarkFixture from plugboard.connector import AsyncioConnector, Connector, RayConnector, ZMQConnector from plugboard.process import LocalProcess, Process, RayProcess @@ -34,50 +31,19 @@ def _build_process(connector_cls: type[Connector], process_cls: type[Process]) - return process_cls(components=components, connectors=connectors) -@pytest.mark.parametrize( - "connector_cls, process_cls", - CONNECTOR_PROCESS_PARAMS, - ids=CONNECTOR_PROCESS_IDS, -) -def test_benchmark_process_run( - benchmark: BenchmarkFixture, - connector_cls: type[Connector], - process_cls: type[Process], - ray_ctx: None, -) -> None: - """Benchmark running of a Plugboard Process.""" - - def _setup() -> tuple[tuple[Process], dict]: - async def _init() -> Process: - process = _build_process(connector_cls, process_cls) - await process.init() - return process - - return (asyncio.run(_init()),), {} - - def _run(process: Process) -> None: - asyncio.run(process.run()) - - benchmark.pedantic(_run, setup=_setup, rounds=5) - - @pytest.mark.benchmark @pytest.mark.parametrize( "connector_cls, process_cls", CONNECTOR_PROCESS_PARAMS, ids=CONNECTOR_PROCESS_IDS, ) -def test_benchmark_process_lifecycle( +@pytest.mark.asyncio +async def test_benchmark_process_lifecycle( connector_cls: type[Connector], process_cls: type[Process], ray_ctx: None, ) -> None: """Benchmark the full lifecycle (init, run, destroy) of a Plugboard Process.""" - - async def _lifecycle() -> None: - process = _build_process(connector_cls, process_cls) - await process.init() - await process.run() - await process.destroy() - - asyncio.run(_lifecycle()) + process = _build_process(connector_cls, process_cls) + async with process: + process.run() From 83eea99c7cc7bd9c6ad3b755ca5a6168302a8366 Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Wed, 1 Apr 2026 08:20:25 +0100 Subject: [PATCH 07/25] Missing await --- tests/benchmark/test_benchmarking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 96e179be2..023e94da8 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -46,4 +46,4 @@ async def test_benchmark_process_lifecycle( """Benchmark the full lifecycle (init, run, destroy) of a Plugboard Process.""" process = _build_process(connector_cls, process_cls) async with process: - process.run() + await process.run() From c663755ba4d703c415ebc4df43dce33ab18f788a Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Mon, 6 Apr 2026 10:09:04 +0100 Subject: [PATCH 08/25] Try reinstated benchmark --- tests/benchmark/test_benchmarking.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 023e94da8..8ca9d4426 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -1,6 +1,8 @@ """Benchmark tests for Plugboard processes.""" import pytest +from pytest_codspeed import BenchmarkFixture +import uvloop from plugboard.connector import AsyncioConnector, Connector, RayConnector, ZMQConnector from plugboard.process import LocalProcess, Process, RayProcess @@ -47,3 +49,26 @@ async def test_benchmark_process_lifecycle( process = _build_process(connector_cls, process_cls) async with process: await process.run() + + +@pytest.mark.parametrize( + "connector_cls, process_cls", + CONNECTOR_PROCESS_PARAMS, + ids=CONNECTOR_PROCESS_IDS, +) +def test_benchmark_process_run( + benchmark: BenchmarkFixture, + connector_cls: type[Connector], + process_cls: type[Process], + ray_ctx: None, +) -> None: + """Benchmark running of a Plugboard Process.""" + process = _build_process(connector_cls, process_cls) + + def setup() -> None: + uvloop.run(process.init()) + + def _run(process: Process) -> None: + uvloop.run(process.run()) + + benchmark.pedantic(_run, rounds=5) From f2254a1f822b02622aaa82729f8641cf77566dbf Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Mon, 6 Apr 2026 10:23:28 +0100 Subject: [PATCH 09/25] Fix --- tests/benchmark/test_benchmarking.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 8ca9d4426..4873970f0 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -68,7 +68,7 @@ def test_benchmark_process_run( def setup() -> None: uvloop.run(process.init()) - def _run(process: Process) -> None: + def _run() -> None: uvloop.run(process.run()) benchmark.pedantic(_run, rounds=5) From 48872a6bb4c806c1d36e444d893071e470848d97 Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Mon, 6 Apr 2026 10:31:58 +0100 Subject: [PATCH 10/25] Reinstate setup --- tests/benchmark/test_benchmarking.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 4873970f0..1beedf49d 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -65,10 +65,10 @@ def test_benchmark_process_run( """Benchmark running of a Plugboard Process.""" process = _build_process(connector_cls, process_cls) - def setup() -> None: + def _setup() -> None: uvloop.run(process.init()) def _run() -> None: uvloop.run(process.run()) - benchmark.pedantic(_run, rounds=5) + benchmark.pedantic(_run, setup=_setup, rounds=5) From d0efaf5f04c3c71c94a9f6b2b98f63633dde31c7 Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Mon, 6 Apr 2026 10:43:07 +0100 Subject: [PATCH 11/25] Try marking asyncio --- tests/benchmark/test_benchmarking.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 1beedf49d..65525b97e 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -56,6 +56,7 @@ async def test_benchmark_process_lifecycle( CONNECTOR_PROCESS_PARAMS, ids=CONNECTOR_PROCESS_IDS, ) +@pytest.mark.asyncio def test_benchmark_process_run( benchmark: BenchmarkFixture, connector_cls: type[Connector], From f8c763685e87f58715d3f2abbab5715fc478ee8b Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Mon, 6 Apr 2026 10:54:48 +0100 Subject: [PATCH 12/25] Retry --- tests/benchmark/test_benchmarking.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 65525b97e..1bc963e85 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -1,5 +1,7 @@ """Benchmark tests for Plugboard processes.""" +import asyncio + import pytest from pytest_codspeed import BenchmarkFixture import uvloop @@ -56,7 +58,6 @@ async def test_benchmark_process_lifecycle( CONNECTOR_PROCESS_PARAMS, ids=CONNECTOR_PROCESS_IDS, ) -@pytest.mark.asyncio def test_benchmark_process_run( benchmark: BenchmarkFixture, connector_cls: type[Connector], @@ -64,12 +65,22 @@ def test_benchmark_process_run( ray_ctx: None, ) -> None: """Benchmark running of a Plugboard Process.""" - process = _build_process(connector_cls, process_cls) - def _setup() -> None: - uvloop.run(process.init()) + async def _setup_process() -> Process: + process = _build_process(connector_cls, process_cls) + await process.init() + return process + + def _setup() -> tuple[tuple[asyncio.Runner, Process], dict[str, object]]: + runner = asyncio.Runner(loop_factory=uvloop.new_event_loop) + process = runner.run(_setup_process()) + return (runner, process), {} + + def _run(runner: asyncio.Runner, process: Process) -> None: + runner.run(process.run()) - def _run() -> None: - uvloop.run(process.run()) + def _teardown(runner: asyncio.Runner, process: Process) -> None: + runner.run(process.destroy()) + runner.close() - benchmark.pedantic(_run, setup=_setup, rounds=5) + benchmark.pedantic(_run, setup=_setup, teardown=_teardown, rounds=5) From e2c6d5374cc61a6dbfc7290424bb110b8582113e Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Mon, 6 Apr 2026 11:02:00 +0100 Subject: [PATCH 13/25] Simple test --- tests/benchmark/test_benchmarking.py | 39 ++++++---------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 1bc963e85..d2d0a9843 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -1,10 +1,7 @@ """Benchmark tests for Plugboard processes.""" -import asyncio - import pytest from pytest_codspeed import BenchmarkFixture -import uvloop from plugboard.connector import AsyncioConnector, Connector, RayConnector, ZMQConnector from plugboard.process import LocalProcess, Process, RayProcess @@ -53,34 +50,14 @@ async def test_benchmark_process_lifecycle( await process.run() -@pytest.mark.parametrize( - "connector_cls, process_cls", - CONNECTOR_PROCESS_PARAMS, - ids=CONNECTOR_PROCESS_IDS, -) -def test_benchmark_process_run( - benchmark: BenchmarkFixture, - connector_cls: type[Connector], - process_cls: type[Process], - ray_ctx: None, -) -> None: - """Benchmark running of a Plugboard Process.""" - - async def _setup_process() -> Process: - process = _build_process(connector_cls, process_cls) - await process.init() - return process - - def _setup() -> tuple[tuple[asyncio.Runner, Process], dict[str, object]]: - runner = asyncio.Runner(loop_factory=uvloop.new_event_loop) - process = runner.run(_setup_process()) - return (runner, process), {} +def test_codspeed_benchmark(benchmark: BenchmarkFixture) -> None: + """Run the benchmark for the process lifecycle.""" + import time - def _run(runner: asyncio.Runner, process: Process) -> None: - runner.run(process.run()) + def _setup(): + time.sleep(0.5) # Simulate setup time - def _teardown(runner: asyncio.Runner, process: Process) -> None: - runner.run(process.destroy()) - runner.close() + def _run(): + time.sleep(1) # Simulate the process lifecycle time - benchmark.pedantic(_run, setup=_setup, teardown=_teardown, rounds=5) + benchmark.pedantic(_run, setup=_setup, rounds=3, iterations=1) From 95dde5d4e83fa26cf0fbeb2f160c861e51acfb6c Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Mon, 6 Apr 2026 12:36:37 +0100 Subject: [PATCH 14/25] Note to resinstate run-only tests --- tests/benchmark/test_benchmarking.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index d2d0a9843..4cea1a2fe 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -1,7 +1,6 @@ """Benchmark tests for Plugboard processes.""" import pytest -from pytest_codspeed import BenchmarkFixture from plugboard.connector import AsyncioConnector, Connector, RayConnector, ZMQConnector from plugboard.process import LocalProcess, Process, RayProcess @@ -50,14 +49,4 @@ async def test_benchmark_process_lifecycle( await process.run() -def test_codspeed_benchmark(benchmark: BenchmarkFixture) -> None: - """Run the benchmark for the process lifecycle.""" - import time - - def _setup(): - time.sleep(0.5) # Simulate setup time - - def _run(): - time.sleep(1) # Simulate the process lifecycle time - - benchmark.pedantic(_run, setup=_setup, rounds=3, iterations=1) +# TODO: Reinstate run-only tests depending on https://github.com/CodSpeedHQ/pytest-codspeed/issues/113 From 85362c6f783910841778dd2ae74d429fec942c62 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Apr 2026 12:57:28 +0000 Subject: [PATCH 15/25] Reinstate run-only benchmark tests and update pytest-codspeed to >=4.4.0 Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/e645afe0-8441-4d40-a914-d6d34ad285d0 Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com> --- pyproject.toml | 2 +- tests/benchmark/test_benchmarking.py | 24 +++++++++++++++++++++++- uv.lock | 28 ++++++++++++++-------------- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e7c09cfa9..c763cf684 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,7 +80,7 @@ test = [ "optuna>=3.0,<5", "pytest>=8.3,<10", "pytest-asyncio>=1.0,<2", - "pytest-codspeed>=4.3.0", + "pytest-codspeed>=4.4.0", "pytest-cases>=3.8,<4", "pytest-env>=1.1,<2", "pytest-rerunfailures>=15.0,<17", diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 4cea1a2fe..153a27c3b 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -1,6 +1,8 @@ """Benchmark tests for Plugboard processes.""" import pytest +from pytest_codspeed import BenchmarkFixture +import uvloop from plugboard.connector import AsyncioConnector, Connector, RayConnector, ZMQConnector from plugboard.process import LocalProcess, Process, RayProcess @@ -49,4 +51,24 @@ async def test_benchmark_process_lifecycle( await process.run() -# TODO: Reinstate run-only tests depending on https://github.com/CodSpeedHQ/pytest-codspeed/issues/113 +@pytest.mark.parametrize( + "connector_cls, process_cls", + CONNECTOR_PROCESS_PARAMS, + ids=CONNECTOR_PROCESS_IDS, +) +def test_benchmark_process_run( + benchmark: BenchmarkFixture, + connector_cls: type[Connector], + process_cls: type[Process], + ray_ctx: None, +) -> None: + """Benchmark running of a Plugboard Process.""" + process = _build_process(connector_cls, process_cls) + + def setup() -> None: + uvloop.run(process.init()) + + def _run(process: Process) -> None: + uvloop.run(process.run()) + + benchmark.pedantic(_run, setup=setup, rounds=5) diff --git a/uv.lock b/uv.lock index 6d72ce2e4..0d3038444 100644 --- a/uv.lock +++ b/uv.lock @@ -3994,7 +3994,7 @@ all = [ { name = "pytest", specifier = ">=8.3,<10" }, { name = "pytest-asyncio", specifier = ">=1.0,<2" }, { name = "pytest-cases", specifier = ">=3.8,<4" }, - { name = "pytest-codspeed", specifier = ">=4.3.0" }, + { name = "pytest-codspeed", specifier = ">=4.4.0" }, { name = "pytest-env", specifier = ">=1.1,<2" }, { name = "pytest-rerunfailures", specifier = ">=15.0,<17" }, { name = "radon", specifier = ">=6.0.1,<7" }, @@ -4040,7 +4040,7 @@ test = [ { name = "pytest", specifier = ">=8.3,<10" }, { name = "pytest-asyncio", specifier = ">=1.0,<2" }, { name = "pytest-cases", specifier = ">=3.8,<4" }, - { name = "pytest-codspeed", specifier = ">=4.3.0" }, + { name = "pytest-codspeed", specifier = ">=4.4.0" }, { name = "pytest-env", specifier = ">=1.1,<2" }, { name = "pytest-rerunfailures", specifier = ">=15.0,<17" }, { name = "ray", extras = ["default", "tune"], specifier = ">=2.40.0,<3" }, @@ -4565,24 +4565,24 @@ wheels = [ [[package]] name = "pytest-codspeed" -version = "4.3.0" +version = "4.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi" }, { name = "pytest" }, { name = "rich" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/98/ab/eca41967d11c95392829a8b4bfa9220a51cffc4a33ec4653358000356918/pytest_codspeed-4.3.0.tar.gz", hash = "sha256:5230d9d65f39063a313ed1820df775166227ec5c20a1122968f85653d5efee48", size = 124745, upload-time = "2026-02-09T15:23:34.745Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/09/58/50df94e9a78e1c77818a492c90557eeb1309af025120c9a21e6375950c52/pytest_codspeed-4.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527a3a02eaa3e4d4583adc4ba2327eef79628f3e1c682a4b959439551a72588e", size = 347395, upload-time = "2026-02-09T15:23:21.986Z" }, - { url = "https://files.pythonhosted.org/packages/e4/56/7dfbd3eefd112a14e6fb65f9ff31dacf2e9c381cb94b27332b81d2b13f8d/pytest_codspeed-4.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9858c2a6e1f391d5696757e7b6e9484749a7376c46f8b4dd9aebf093479a9667", size = 342625, upload-time = "2026-02-09T15:23:23.035Z" }, - { url = "https://files.pythonhosted.org/packages/7f/53/7255f6a25bc56ff1745b254b21545dfe0be2268f5b91ce78f7e8a908f0ad/pytest_codspeed-4.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34f2fd8497456eefbd325673f677ea80d93bb1bc08a578c1fa43a09cec3d1879", size = 347325, upload-time = "2026-02-09T15:23:23.998Z" }, - { url = "https://files.pythonhosted.org/packages/2e/f8/82ae570d8b9ad30f33c9d4002a7a1b2740de0e090540c69a28e4f711ebe2/pytest_codspeed-4.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df6a36a2a9da1406bc50428437f657f0bd8c842ae54bee5fb3ad30e01d50c0f5", size = 342558, upload-time = "2026-02-09T15:23:25.656Z" }, - { url = "https://files.pythonhosted.org/packages/b3/e1/55cfe9474f91d174c7a4b04d257b5fc6d4d06f3d3680f2da672ee59ccc10/pytest_codspeed-4.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bec30f4fc9c4973143cd80f0d33fa780e9fa3e01e4dbe8cedf229e72f1212c62", size = 347383, upload-time = "2026-02-09T15:23:26.68Z" }, - { url = "https://files.pythonhosted.org/packages/7f/3b/8fd781d959bbe789b3de8ce4c50d5706a684a0df377147dfb27b200c20c1/pytest_codspeed-4.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e6584e641cadf27d894ae90b87c50377232a97cbfd76ee0c7ecd0c056fa3f7f4", size = 342481, upload-time = "2026-02-09T15:23:27.686Z" }, - { url = "https://files.pythonhosted.org/packages/bb/0c/368045133c6effa2c665b1634b7b8a9c88b307f877fa31f1f8df47885b51/pytest_codspeed-4.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df0d1f6ea594f29b745c634d66d5f5f1caa1c3abd2af82fea49d656038e8fc77", size = 353680, upload-time = "2026-02-09T15:23:28.726Z" }, - { url = "https://files.pythonhosted.org/packages/59/21/e543abcd72244294e25ae88ec3a9311ade24d6913f8c8f42569d671700bc/pytest_codspeed-4.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2f5bb6d8898bea7db45e3c8b916ee48e36905b929477bb511b79c5a3ccacda4", size = 347888, upload-time = "2026-02-09T15:23:30.443Z" }, - { url = "https://files.pythonhosted.org/packages/55/d9/b8a53c20cf5b41042c205bb9d36d37da00418d30fd1a94bf9eb147820720/pytest_codspeed-4.3.0-py3-none-any.whl", hash = "sha256:05baff2a61dc9f3e92b92b9c2ab5fb45d9b802438f5373073f5766a91319ed7a", size = 125224, upload-time = "2026-02-09T15:23:33.774Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/52/bc/9070fdbfb479a0e92a12652a68875de157dc9be7dc4865a06a519e3a1877/pytest_codspeed-4.4.0.tar.gz", hash = "sha256:edb7c101d9c50439a42cf02cfa9c0ac92da618841636bbebf87c3fa54669442a", size = 201093, upload-time = "2026-04-14T15:13:20.014Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3e/70/4a401b37f80aaebbcbfb2803b0fab75331af554cd75755bc2059f7809bb4/pytest_codspeed-4.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a5c1d51e7ca72ffe247c99b9a97a54191185e8f7a27528e2200d7416da2a68b", size = 820334, upload-time = "2026-04-14T15:13:03.605Z" }, + { url = "https://files.pythonhosted.org/packages/16/52/beb46293d414d65163f8f3218aaa2f05e53bdc5cf64f24cc3843c31d3ca4/pytest_codspeed-4.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:215170441e57bfcbefd179dfd86ccd54ed0ee235e0602a068ce4448b35f13cb2", size = 829269, upload-time = "2026-04-14T15:13:05.197Z" }, + { url = "https://files.pythonhosted.org/packages/78/53/031793dab3a0edbbcbbd8755648ace0853f4cfb92a0e09e620f301f9ef5d/pytest_codspeed-4.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee3e1964446011ca192eebf0350227df231a5b88af57e518f2a4328fc8ca5131", size = 820300, upload-time = "2026-04-14T15:13:06.791Z" }, + { url = "https://files.pythonhosted.org/packages/e7/66/0c3530c0dd9959b7f0930551b3de296db391040e5e8ad3e0cab917736980/pytest_codspeed-4.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:340dbb1cc5a21434e0e29bd68ab03c7dc7ad9bfde09d1980b7161352c4c2f048", size = 829201, upload-time = "2026-04-14T15:13:08Z" }, + { url = "https://files.pythonhosted.org/packages/f2/8a/24c7997d95f8bda081b8d4346750a5db0d9d8405183ee5cb9062f7381476/pytest_codspeed-4.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:413666266762f9cef1321ba971a9e127b97a1f1dad40ddfd2184c2bc5ac157f9", size = 820242, upload-time = "2026-04-14T15:13:09.191Z" }, + { url = "https://files.pythonhosted.org/packages/8b/7f/3912bf6c2bcddb69189d23213f28e5bc058fd4c78fca15dd0010938154b0/pytest_codspeed-4.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e258e6c3d5a8a02ae02a64831be3acd44c19210ffbf13321bdbb8c111c5c6fe4", size = 829190, upload-time = "2026-04-14T15:13:10.762Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f4/2cc5e10847aee4233690aa511df6b6f1c2c09f9d8ae506628a138f4ba201/pytest_codspeed-4.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d5dd94dcb69460f916acb9c69865d0171b98acec3ce256645d0c0275b553d7", size = 827557, upload-time = "2026-04-14T15:13:12.553Z" }, + { url = "https://files.pythonhosted.org/packages/7f/57/982ce8aa81089b285730dca8404c76af648af41e46d95012be54452913e6/pytest_codspeed-4.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:33c38e0e797c74506004f231fc53eab0e412987de281755f714018334381aa3a", size = 835388, upload-time = "2026-04-14T15:13:14.232Z" }, + { url = "https://files.pythonhosted.org/packages/99/36/9e84323c6be426728e897133f8e9f3e65a90c26c137e190ca9b27bf304c3/pytest_codspeed-4.4.0-py3-none-any.whl", hash = "sha256:a6aab2fa73523f538e7729c20ccf4a1e8e921324c9877a816b05334135950fd9", size = 203809, upload-time = "2026-04-14T15:13:18.72Z" }, ] [[package]] From f585742162a89c1ea9b5c3ebb533a935405d95a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 17 Apr 2026 12:58:51 +0000 Subject: [PATCH 16/25] Fix run-only benchmark: remove unused arg, add teardown for cleanup Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/e645afe0-8441-4d40-a914-d6d34ad285d0 Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com> --- tests/benchmark/test_benchmarking.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 153a27c3b..42a55c0c9 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -68,7 +68,10 @@ def test_benchmark_process_run( def setup() -> None: uvloop.run(process.init()) - def _run(process: Process) -> None: + def _run() -> None: uvloop.run(process.run()) - benchmark.pedantic(_run, setup=setup, rounds=5) + def teardown() -> None: + uvloop.run(process.destroy()) + + benchmark.pedantic(_run, setup=setup, teardown=teardown, rounds=5) From 787dc56a930f83136b3cb478251cea6d25d62c12 Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Fri, 17 Apr 2026 13:19:20 +0000 Subject: [PATCH 17/25] Support AARCH64 --- pyproject.toml | 4 ++++ uv.lock | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c763cf684..bec67f829 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -116,6 +116,10 @@ fallback_version = "0.0.0" [tool.uv] package = true default-groups = ["all"] +required-environments = [ + # AARCH64 linux support required for Codspeed benchmarks + "sys_platform == 'linux' and platform_machine == 'aarch64'" +] [tool.uv.workspace] members = ["plugboard-schemas"] diff --git a/uv.lock b/uv.lock index 0d3038444..9b617f0f8 100644 --- a/uv.lock +++ b/uv.lock @@ -6,12 +6,15 @@ resolution-markers = [ "python_full_version >= '3.14' and sys_platform == 'emscripten'", "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version == '3.13.*' and sys_platform == 'win32'", - "python_full_version == '3.13.*' and sys_platform == 'emscripten'", - "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.13' and sys_platform == 'win32'", + "python_full_version == '3.13.*' and sys_platform == 'emscripten'", "python_full_version < '3.13' and sys_platform == 'emscripten'", + "python_full_version == '3.13.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.13' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] +required-markers = [ + "platform_machine == 'aarch64' and sys_platform == 'linux'", +] [manifest] members = [ From 71910d3e4c4722a450880aec909404863e925f8e Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Fri, 17 Apr 2026 13:35:15 +0000 Subject: [PATCH 18/25] Upgrade greenlet --- uv.lock | 76 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/uv.lock b/uv.lock index 9b617f0f8..f19201e51 100644 --- a/uv.lock +++ b/uv.lock @@ -1565,41 +1565,49 @@ wheels = [ [[package]] name = "greenlet" -version = "3.3.0" +version = "3.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c7/e5/40dbda2736893e3e53d25838e0f19a2b417dfc122b9989c91918db30b5d3/greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb", size = 190651, upload-time = "2025-12-04T14:49:44.05Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/0a/a3871375c7b9727edaeeea994bfff7c63ff7804c9829c19309ba2e058807/greenlet-3.3.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b01548f6e0b9e9784a2c99c5651e5dc89ffcbe870bc5fb2e5ef864e9cc6b5dcb", size = 276379, upload-time = "2025-12-04T14:23:30.498Z" }, - { url = "https://files.pythonhosted.org/packages/43/ab/7ebfe34dce8b87be0d11dae91acbf76f7b8246bf9d6b319c741f99fa59c6/greenlet-3.3.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349345b770dc88f81506c6861d22a6ccd422207829d2c854ae2af8025af303e3", size = 597294, upload-time = "2025-12-04T14:50:06.847Z" }, - { url = "https://files.pythonhosted.org/packages/a4/39/f1c8da50024feecd0793dbd5e08f526809b8ab5609224a2da40aad3a7641/greenlet-3.3.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8e18ed6995e9e2c0b4ed264d2cf89260ab3ac7e13555b8032b25a74c6d18655", size = 607742, upload-time = "2025-12-04T14:57:42.349Z" }, - { url = "https://files.pythonhosted.org/packages/77/cb/43692bcd5f7a0da6ec0ec6d58ee7cddb606d055ce94a62ac9b1aa481e969/greenlet-3.3.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c024b1e5696626890038e34f76140ed1daf858e37496d33f2af57f06189e70d7", size = 622297, upload-time = "2025-12-04T15:07:13.552Z" }, - { url = "https://files.pythonhosted.org/packages/75/b0/6bde0b1011a60782108c01de5913c588cf51a839174538d266de15e4bf4d/greenlet-3.3.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:047ab3df20ede6a57c35c14bf5200fcf04039d50f908270d3f9a7a82064f543b", size = 609885, upload-time = "2025-12-04T14:26:02.368Z" }, - { url = "https://files.pythonhosted.org/packages/49/0e/49b46ac39f931f59f987b7cd9f34bfec8ef81d2a1e6e00682f55be5de9f4/greenlet-3.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d9ad37fc657b1102ec880e637cccf20191581f75c64087a549e66c57e1ceb53", size = 1567424, upload-time = "2025-12-04T15:04:23.757Z" }, - { url = "https://files.pythonhosted.org/packages/05/f5/49a9ac2dff7f10091935def9165c90236d8f175afb27cbed38fb1d61ab6b/greenlet-3.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83cd0e36932e0e7f36a64b732a6f60c2fc2df28c351bae79fbaf4f8092fe7614", size = 1636017, upload-time = "2025-12-04T14:27:29.688Z" }, - { url = "https://files.pythonhosted.org/packages/6c/79/3912a94cf27ec503e51ba493692d6db1e3cd8ac7ac52b0b47c8e33d7f4f9/greenlet-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7a34b13d43a6b78abf828a6d0e87d3385680eaf830cd60d20d52f249faabf39", size = 301964, upload-time = "2025-12-04T14:36:58.316Z" }, - { url = "https://files.pythonhosted.org/packages/02/2f/28592176381b9ab2cafa12829ba7b472d177f3acc35d8fbcf3673d966fff/greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739", size = 275140, upload-time = "2025-12-04T14:23:01.282Z" }, - { url = "https://files.pythonhosted.org/packages/2c/80/fbe937bf81e9fca98c981fe499e59a3f45df2a04da0baa5c2be0dca0d329/greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808", size = 599219, upload-time = "2025-12-04T14:50:08.309Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ff/7c985128f0514271b8268476af89aee6866df5eec04ac17dcfbc676213df/greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54", size = 610211, upload-time = "2025-12-04T14:57:43.968Z" }, - { url = "https://files.pythonhosted.org/packages/79/07/c47a82d881319ec18a4510bb30463ed6891f2ad2c1901ed5ec23d3de351f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30a6e28487a790417d036088b3bcb3f3ac7d8babaa7d0139edbaddebf3af9492", size = 624311, upload-time = "2025-12-04T15:07:14.697Z" }, - { url = "https://files.pythonhosted.org/packages/fd/8e/424b8c6e78bd9837d14ff7df01a9829fc883ba2ab4ea787d4f848435f23f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527", size = 612833, upload-time = "2025-12-04T14:26:03.669Z" }, - { url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256, upload-time = "2025-12-04T15:04:25.276Z" }, - { url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483, upload-time = "2025-12-04T14:27:30.804Z" }, - { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, - { url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671, upload-time = "2025-12-04T14:23:05.267Z" }, - { url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360, upload-time = "2025-12-04T14:50:10.026Z" }, - { url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160, upload-time = "2025-12-04T14:57:45.41Z" }, - { url = "https://files.pythonhosted.org/packages/93/79/d2c70cae6e823fac36c3bbc9077962105052b7ef81db2f01ec3b9bf17e2b/greenlet-3.3.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dcd2bdbd444ff340e8d6bdf54d2f206ccddbb3ccfdcd3c25bf4afaa7b8f0cf45", size = 671388, upload-time = "2025-12-04T15:07:15.789Z" }, - { url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166, upload-time = "2025-12-04T14:26:05.099Z" }, - { url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193, upload-time = "2025-12-04T15:04:27.041Z" }, - { url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653, upload-time = "2025-12-04T14:27:32.366Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, - { url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638, upload-time = "2025-12-04T14:25:20.941Z" }, - { url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145, upload-time = "2025-12-04T14:50:11.039Z" }, - { url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236, upload-time = "2025-12-04T14:57:47.007Z" }, - { url = "https://files.pythonhosted.org/packages/69/cc/1e4bae2e45ca2fa55299f4e85854606a78ecc37fead20d69322f96000504/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2662433acbca297c9153a4023fe2161c8dcfdcc91f10433171cf7e7d94ba2221", size = 662506, upload-time = "2025-12-04T15:07:16.906Z" }, - { url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783, upload-time = "2025-12-04T14:26:06.225Z" }, - { url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857, upload-time = "2025-12-04T15:04:28.484Z" }, - { url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034, upload-time = "2025-12-04T14:27:33.531Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/86/94/a5935717b307d7c71fe877b52b884c6af707d2d2090db118a03fbd799369/greenlet-3.4.0.tar.gz", hash = "sha256:f50a96b64dafd6169e595a5c56c9146ef80333e67d4476a65a9c55f400fc22ff", size = 195913, upload-time = "2026-04-08T17:08:00.863Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/8b/3669ad3b3f247a791b2b4aceb3aa5a31f5f6817bf547e4e1ff712338145a/greenlet-3.4.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:1a54a921561dd9518d31d2d3db4d7f80e589083063ab4d3e2e950756ef809e1a", size = 286902, upload-time = "2026-04-08T15:52:12.138Z" }, + { url = "https://files.pythonhosted.org/packages/38/3e/3c0e19b82900873e2d8469b590a6c4b3dfd2b316d0591f1c26b38a4879a5/greenlet-3.4.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:16dec271460a9a2b154e3b1c2fa1050ce6280878430320e85e08c166772e3f97", size = 606099, upload-time = "2026-04-08T16:24:38.408Z" }, + { url = "https://files.pythonhosted.org/packages/b5/33/99fef65e7754fc76a4ed14794074c38c9ed3394a5bd129d7f61b705f3168/greenlet-3.4.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:90036ce224ed6fe75508c1907a77e4540176dcf0744473627785dd519c6f9996", size = 618837, upload-time = "2026-04-08T16:30:58.298Z" }, + { url = "https://files.pythonhosted.org/packages/44/57/eae2cac10421feae6c0987e3dc106c6d86262b1cb379e171b017aba893a6/greenlet-3.4.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6f0def07ec9a71d72315cf26c061aceee53b306c36ed38c35caba952ea1b319d", size = 624901, upload-time = "2026-04-08T16:40:38.981Z" }, + { url = "https://files.pythonhosted.org/packages/36/f7/229f3aed6948faa20e0616a0b8568da22e365ede6a54d7d369058b128afd/greenlet-3.4.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a1c4f6b453006efb8310affb2d132832e9bbb4fc01ce6df6b70d810d38f1f6dc", size = 615062, upload-time = "2026-04-08T15:56:33.766Z" }, + { url = "https://files.pythonhosted.org/packages/6a/8a/0e73c9b94f31d1cc257fe79a0eff621674141cdae7d6d00f40de378a1e42/greenlet-3.4.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:0e1254cf0cbaa17b04320c3a78575f29f3c161ef38f59c977108f19ffddaf077", size = 423927, upload-time = "2026-04-08T16:43:05.293Z" }, + { url = "https://files.pythonhosted.org/packages/08/97/d988180011aa40135c46cd0d0cf01dd97f7162bae14139b4a3ef54889ba5/greenlet-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9b2d9a138ffa0e306d0e2b72976d2fb10b97e690d40ab36a472acaab0838e2de", size = 1573511, upload-time = "2026-04-08T16:26:20.058Z" }, + { url = "https://files.pythonhosted.org/packages/d4/0f/a5a26fe152fb3d12e6a474181f6e9848283504d0afd095f353d85726374b/greenlet-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8424683caf46eb0eb6f626cb95e008e8cc30d0cb675bdfa48200925c79b38a08", size = 1640396, upload-time = "2026-04-08T15:57:30.88Z" }, + { url = "https://files.pythonhosted.org/packages/42/cf/bb2c32d9a100e36ee9f6e38fad6b1e082b8184010cb06259b49e1266ca01/greenlet-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0a53fb071531d003b075c444014ff8f8b1a9898d36bb88abd9ac7b3524648a2", size = 238892, upload-time = "2026-04-08T17:03:10.094Z" }, + { url = "https://files.pythonhosted.org/packages/b7/47/6c41314bac56e71436ce551c7fbe3cc830ed857e6aa9708dbb9c65142eb6/greenlet-3.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:f38b81880ba28f232f1f675893a39cf7b6db25b31cc0a09bb50787ecf957e85e", size = 235599, upload-time = "2026-04-08T15:52:54.3Z" }, + { url = "https://files.pythonhosted.org/packages/7a/75/7e9cd1126a1e1f0cd67b0eda02e5221b28488d352684704a78ed505bd719/greenlet-3.4.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:43748988b097f9c6f09364f260741aa73c80747f63389824435c7a50bfdfd5c1", size = 285856, upload-time = "2026-04-08T15:52:45.82Z" }, + { url = "https://files.pythonhosted.org/packages/9d/c4/3e2df392e5cb199527c4d9dbcaa75c14edcc394b45040f0189f649631e3c/greenlet-3.4.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5566e4e2cd7a880e8c27618e3eab20f3494452d12fd5129edef7b2f7aa9a36d1", size = 610208, upload-time = "2026-04-08T16:24:39.674Z" }, + { url = "https://files.pythonhosted.org/packages/da/af/750cdfda1d1bd30a6c28080245be8d0346e669a98fdbae7f4102aa95fff3/greenlet-3.4.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1054c5a3c78e2ab599d452f23f7adafef55062a783a8e241d24f3b633ba6ff82", size = 621269, upload-time = "2026-04-08T16:30:59.767Z" }, + { url = "https://files.pythonhosted.org/packages/e0/93/c8c508d68ba93232784bbc1b5474d92371f2897dfc6bc281b419f2e0d492/greenlet-3.4.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:98eedd1803353daf1cd9ef23eef23eda5a4d22f99b1f998d273a8b78b70dd47f", size = 628455, upload-time = "2026-04-08T16:40:40.698Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/0cbc693622cd54ebe25207efbb3a0eb07c2639cb8594f6e3aaaa0bb077a8/greenlet-3.4.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f82cb6cddc27dd81c96b1506f4aa7def15070c3b2a67d4e46fd19016aacce6cf", size = 617549, upload-time = "2026-04-08T15:56:34.893Z" }, + { url = "https://files.pythonhosted.org/packages/7f/46/cfaaa0ade435a60550fd83d07dfd5c41f873a01da17ede5c4cade0b9bab8/greenlet-3.4.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:b7857e2202aae67bc5725e0c1f6403c20a8ff46094ece015e7d474f5f7020b55", size = 426238, upload-time = "2026-04-08T16:43:06.865Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c0/8966767de01343c1ff47e8b855dc78e7d1a8ed2b7b9c83576a57e289f81d/greenlet-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:227a46251ecba4ff46ae742bc5ce95c91d5aceb4b02f885487aff269c127a729", size = 1575310, upload-time = "2026-04-08T16:26:21.671Z" }, + { url = "https://files.pythonhosted.org/packages/b8/38/bcdc71ba05e9a5fda87f63ffc2abcd1f15693b659346df994a48c968003d/greenlet-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5b99e87be7eba788dd5b75ba1cde5639edffdec5f91fe0d734a249535ec3408c", size = 1640435, upload-time = "2026-04-08T15:57:32.572Z" }, + { url = "https://files.pythonhosted.org/packages/a1/c2/19b664b7173b9e4ef5f77e8cef9f14c20ec7fce7920dc1ccd7afd955d093/greenlet-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:849f8bc17acd6295fcb5de8e46d55cc0e52381c56eaf50a2afd258e97bc65940", size = 238760, upload-time = "2026-04-08T17:04:03.878Z" }, + { url = "https://files.pythonhosted.org/packages/9b/96/795619651d39c7fbd809a522f881aa6f0ead504cc8201c3a5b789dfaef99/greenlet-3.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:9390ad88b652b1903814eaabd629ca184db15e0eeb6fe8a390bbf8b9106ae15a", size = 235498, upload-time = "2026-04-08T17:05:00.584Z" }, + { url = "https://files.pythonhosted.org/packages/78/02/bde66806e8f169cf90b14d02c500c44cdbe02c8e224c9c67bafd1b8cadd1/greenlet-3.4.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:10a07aca6babdd18c16a3f4f8880acfffc2b88dfe431ad6aa5f5740759d7d75e", size = 286291, upload-time = "2026-04-08T17:09:34.307Z" }, + { url = "https://files.pythonhosted.org/packages/05/1f/39da1c336a87d47c58352fb8a78541ce63d63ae57c5b9dae1fe02801bbc2/greenlet-3.4.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:076e21040b3a917d3ce4ad68fb5c3c6b32f1405616c4a57aa83120979649bd3d", size = 656749, upload-time = "2026-04-08T16:24:41.721Z" }, + { url = "https://files.pythonhosted.org/packages/d3/6c/90ee29a4ee27af7aa2e2ec408799eeb69ee3fcc5abcecac6ddd07a5cd0f2/greenlet-3.4.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e82689eea4a237e530bb5cb41b180ef81fa2160e1f89422a67be7d90da67f615", size = 669084, upload-time = "2026-04-08T16:31:01.372Z" }, + { url = "https://files.pythonhosted.org/packages/d2/4a/74078d3936712cff6d3c91a930016f476ce4198d84e224fe6d81d3e02880/greenlet-3.4.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:06c2d3b89e0c62ba50bd7adf491b14f39da9e7e701647cb7b9ff4c99bee04b19", size = 673405, upload-time = "2026-04-08T16:40:42.527Z" }, + { url = "https://files.pythonhosted.org/packages/07/49/d4cad6e5381a50947bb973d2f6cf6592621451b09368b8c20d9b8af49c5b/greenlet-3.4.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4df3b0b2289ec686d3c821a5fee44259c05cfe824dd5e6e12c8e5f5df23085cf", size = 665621, upload-time = "2026-04-08T15:56:35.995Z" }, + { url = "https://files.pythonhosted.org/packages/79/3e/df8a83ab894751bc31e1106fdfaa80ca9753222f106b04de93faaa55feb7/greenlet-3.4.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:070b8bac2ff3b4d9e0ff36a0d19e42103331d9737e8504747cd1e659f76297bd", size = 471670, upload-time = "2026-04-08T16:43:08.512Z" }, + { url = "https://files.pythonhosted.org/packages/37/31/d1edd54f424761b5d47718822f506b435b6aab2f3f93b465441143ea5119/greenlet-3.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8bff29d586ea415688f4cec96a591fcc3bf762d046a796cdadc1fdb6e7f2d5bf", size = 1622259, upload-time = "2026-04-08T16:26:23.201Z" }, + { url = "https://files.pythonhosted.org/packages/b0/c6/6d3f9cdcb21c4e12a79cb332579f1c6aa1af78eb68059c5a957c7812d95e/greenlet-3.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a569c2fb840c53c13a2b8967c63621fafbd1a0e015b9c82f408c33d626a2fda", size = 1686916, upload-time = "2026-04-08T15:57:34.282Z" }, + { url = "https://files.pythonhosted.org/packages/63/45/c1ca4a1ad975de4727e52d3ffe641ae23e1d7a8ffaa8ff7a0477e1827b92/greenlet-3.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:207ba5b97ea8b0b60eb43ffcacf26969dd83726095161d676aac03ff913ee50d", size = 239821, upload-time = "2026-04-08T17:03:48.423Z" }, + { url = "https://files.pythonhosted.org/packages/71/c4/6f621023364d7e85a4769c014c8982f98053246d142420e0328980933ceb/greenlet-3.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:f8296d4e2b92af34ebde81085a01690f26a51eb9ac09a0fcadb331eb36dbc802", size = 236932, upload-time = "2026-04-08T17:04:33.551Z" }, + { url = "https://files.pythonhosted.org/packages/d4/8f/18d72b629783f5e8d045a76f5325c1e938e659a9e4da79c7dcd10169a48d/greenlet-3.4.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d70012e51df2dbbccfaf63a40aaf9b40c8bed37c3e3a38751c926301ce538ece", size = 294681, upload-time = "2026-04-08T15:52:35.778Z" }, + { url = "https://files.pythonhosted.org/packages/9e/ad/5fa86ec46769c4153820d58a04062285b3b9e10ba3d461ee257b68dcbf53/greenlet-3.4.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a58bec0751f43068cd40cff31bb3ca02ad6000b3a51ca81367af4eb5abc480c8", size = 658899, upload-time = "2026-04-08T16:24:43.32Z" }, + { url = "https://files.pythonhosted.org/packages/43/f0/4e8174ca0e87ae748c409f055a1ba161038c43cc0a5a6f1433a26ac2e5bf/greenlet-3.4.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05fa0803561028f4b2e3b490ee41216a842eaee11aed004cc343a996d9523aa2", size = 665284, upload-time = "2026-04-08T16:31:02.833Z" }, + { url = "https://files.pythonhosted.org/packages/ef/92/466b0d9afd44b8af623139a3599d651c7564fa4152f25f117e1ee5949ffb/greenlet-3.4.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c4cd56a9eb7a6444edbc19062f7b6fbc8f287c663b946e3171d899693b1c19fa", size = 665872, upload-time = "2026-04-08T16:40:43.912Z" }, + { url = "https://files.pythonhosted.org/packages/19/da/991cf7cd33662e2df92a1274b7eb4d61769294d38a1bba8a45f31364845e/greenlet-3.4.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e60d38719cb80b3ab5e85f9f1aed4960acfde09868af6762ccb27b260d68f4ed", size = 661861, upload-time = "2026-04-08T15:56:37.269Z" }, + { url = "https://files.pythonhosted.org/packages/0d/14/3395a7ef3e260de0325152ddfe19dffb3e49fe10873b94654352b53ad48e/greenlet-3.4.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:1f85f204c4d54134ae850d401fa435c89cd667d5ce9dc567571776b45941af72", size = 489237, upload-time = "2026-04-08T16:43:09.993Z" }, + { url = "https://files.pythonhosted.org/packages/36/c5/6c2c708e14db3d9caea4b459d8464f58c32047451142fe2cfd90e7458f41/greenlet-3.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7f50c804733b43eded05ae694691c9aa68bca7d0a867d67d4a3f514742a2d53f", size = 1622182, upload-time = "2026-04-08T16:26:24.777Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4c/50c5fed19378e11a29fabab1f6be39ea95358f4a0a07e115a51ca93385d8/greenlet-3.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2d4f0635dc4aa638cda4b2f5a07ae9a2cff9280327b581a3fcb6f317b4fbc38a", size = 1685050, upload-time = "2026-04-08T15:57:36.453Z" }, + { url = "https://files.pythonhosted.org/packages/db/72/85ae954d734703ab48e622c59d4ce35d77ce840c265814af9c078cacc7aa/greenlet-3.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1a4a48f24681300c640f143ba7c404270e1ebbbcf34331d7104a4ff40f8ea705", size = 245554, upload-time = "2026-04-08T17:03:50.044Z" }, ] [[package]] From 4c5223f0e704d8d1c04b7df4388f96f47ddee38f Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Sun, 19 Apr 2026 20:36:15 +0100 Subject: [PATCH 19/25] Fixup the run-only test --- tests/benchmark/test_benchmarking.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 42a55c0c9..4e57af276 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -63,15 +63,16 @@ def test_benchmark_process_run( ray_ctx: None, ) -> None: """Benchmark running of a Plugboard Process.""" - process = _build_process(connector_cls, process_cls) - def setup() -> None: - uvloop.run(process.init()) + def _setup() -> tuple[tuple[Process], dict]: + async def _init() -> Process: + process = _build_process(connector_cls, process_cls) + await process.init() + return process - def _run() -> None: - uvloop.run(process.run()) + return (uvloop.run(_init()),), {} - def teardown() -> None: - uvloop.run(process.destroy()) + def _run(process: Process) -> None: + uvloop.run(process.run()) - benchmark.pedantic(_run, setup=setup, teardown=teardown, rounds=5) + benchmark.pedantic(_run, setup=_setup, rounds=5) From 9356ef96ee5f4f47f1d13223999949cc6f4eb6e4 Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Sun, 19 Apr 2026 20:56:05 +0100 Subject: [PATCH 20/25] Quick test --- tests/benchmark/test_benchmarking.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 4e57af276..1fca5cbe6 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -76,3 +76,28 @@ def _run(process: Process) -> None: uvloop.run(process.run()) benchmark.pedantic(_run, setup=_setup, rounds=5) + + +def _setup_process() -> tuple[tuple[Process], dict]: + comp_a = A(name="comp_a", iters=1000) + comp_b1 = B(name="comp_b1", factor=1) + comp_b2 = B(name="comp_b2", factor=2) + components = [comp_a, comp_b1, comp_b2] + connectors = [ + AsyncioConnector(spec=ConnectorSpec(source="comp_a.out_1", target="comp_b1.in_1")), + AsyncioConnector(spec=ConnectorSpec(source="comp_b1.out_1", target="comp_b2.in_1")), + ] + process = LocalProcess(components=components, connectors=connectors) + # Initialise process so that this is excluded from the benchmark timing + uvloop.run(process.init()) + # Return args and kwargs tuple for benchmark.pedantic + return (process,), {} + + +def _run_process(process: Process) -> None: + uvloop.run(process.run()) + + +def test_temp(benchmark: BenchmarkFixture) -> None: + """Benchmark the running of a Plugboard Process.""" + benchmark.pedantic(_run_process, setup=_setup_process, rounds=5) From 0415516fa743276fc90fbdb484ac621b9ae458e4 Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Sun, 19 Apr 2026 21:07:42 +0100 Subject: [PATCH 21/25] Revert "Quick test" This reverts commit 9356ef96ee5f4f47f1d13223999949cc6f4eb6e4. --- tests/benchmark/test_benchmarking.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/tests/benchmark/test_benchmarking.py b/tests/benchmark/test_benchmarking.py index 1fca5cbe6..4e57af276 100644 --- a/tests/benchmark/test_benchmarking.py +++ b/tests/benchmark/test_benchmarking.py @@ -76,28 +76,3 @@ def _run(process: Process) -> None: uvloop.run(process.run()) benchmark.pedantic(_run, setup=_setup, rounds=5) - - -def _setup_process() -> tuple[tuple[Process], dict]: - comp_a = A(name="comp_a", iters=1000) - comp_b1 = B(name="comp_b1", factor=1) - comp_b2 = B(name="comp_b2", factor=2) - components = [comp_a, comp_b1, comp_b2] - connectors = [ - AsyncioConnector(spec=ConnectorSpec(source="comp_a.out_1", target="comp_b1.in_1")), - AsyncioConnector(spec=ConnectorSpec(source="comp_b1.out_1", target="comp_b2.in_1")), - ] - process = LocalProcess(components=components, connectors=connectors) - # Initialise process so that this is excluded from the benchmark timing - uvloop.run(process.init()) - # Return args and kwargs tuple for benchmark.pedantic - return (process,), {} - - -def _run_process(process: Process) -> None: - uvloop.run(process.run()) - - -def test_temp(benchmark: BenchmarkFixture) -> None: - """Benchmark the running of a Plugboard Process.""" - benchmark.pedantic(_run_process, setup=_setup_process, rounds=5) From 29feb109778af95077791a262de3b5ef0cf42084 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Apr 2026 20:23:45 +0000 Subject: [PATCH 22/25] ci: use ubuntu-latest runner and default CodSpeed mode Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/d0198a73-2b53-48d6-a373-3d0276122cf4 Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com> --- .github/workflows/benchmarks.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/benchmarks.yaml b/.github/workflows/benchmarks.yaml index 6c8714c52..a05250671 100644 --- a/.github/workflows/benchmarks.yaml +++ b/.github/workflows/benchmarks.yaml @@ -15,7 +15,7 @@ on: jobs: benchmark: name: Run benchmarks - runs-on: codspeed-macro + runs-on: ubuntu-latest permissions: contents: read id-token: write @@ -43,6 +43,5 @@ jobs: RAY_ENABLE_UV_RUN_RUNTIME_ENV: 0 PLUGBOARD_IO_READ_TIMEOUT: 5.0 with: - mode: walltime run: uv run pytest tests/benchmark/ --codspeed From f4ee50be6e40ef061d79f83a261a071ef628e76f Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Sun, 19 Apr 2026 21:27:09 +0100 Subject: [PATCH 23/25] Set mode --- .github/workflows/benchmarks.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/benchmarks.yaml b/.github/workflows/benchmarks.yaml index a05250671..37eb3d16d 100644 --- a/.github/workflows/benchmarks.yaml +++ b/.github/workflows/benchmarks.yaml @@ -43,5 +43,6 @@ jobs: RAY_ENABLE_UV_RUN_RUNTIME_ENV: 0 PLUGBOARD_IO_READ_TIMEOUT: 5.0 with: + mode: simulation run: uv run pytest tests/benchmark/ --codspeed From 76af6651c3701fbb3faa2a55e79f51cb85a4edd9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Apr 2026 20:43:19 +0000 Subject: [PATCH 24/25] fix: disable Ray dashboard in benchmarks to avoid MetricsHead timeout in CI Agent-Logs-Url: https://github.com/plugboard-dev/plugboard/sessions/fba811b4-cfe6-408b-976c-314de91e50c8 Co-authored-by: toby-coleman <13170610+toby-coleman@users.noreply.github.com> --- .github/workflows/benchmarks.yaml | 1 - tests/benchmark/conftest.py | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/benchmark/conftest.py diff --git a/.github/workflows/benchmarks.yaml b/.github/workflows/benchmarks.yaml index 37eb3d16d..a05250671 100644 --- a/.github/workflows/benchmarks.yaml +++ b/.github/workflows/benchmarks.yaml @@ -43,6 +43,5 @@ jobs: RAY_ENABLE_UV_RUN_RUNTIME_ENV: 0 PLUGBOARD_IO_READ_TIMEOUT: 5.0 with: - mode: simulation run: uv run pytest tests/benchmark/ --codspeed diff --git a/tests/benchmark/conftest.py b/tests/benchmark/conftest.py new file mode 100644 index 000000000..b092679ac --- /dev/null +++ b/tests/benchmark/conftest.py @@ -0,0 +1,17 @@ +"""Configuration for benchmark tests.""" + +import typing as _t + +import pytest +import ray + + +@pytest.fixture(scope="session") +def ray_ctx() -> _t.Iterator[None]: + """Initialises and shuts down Ray for benchmarks. + + Dashboard is disabled to avoid MetricsHead timeout in CI. + """ + ray.init(num_cpus=5, num_gpus=1, resources={"custom_hardware": 10}, include_dashboard=False) + yield + ray.shutdown() From 0f59fff06e6fbfc6379b5a16a96e0360e90f55bc Mon Sep 17 00:00:00 2001 From: Toby Coleman Date: Sun, 19 Apr 2026 21:47:40 +0100 Subject: [PATCH 25/25] Fixup and reduce permissions --- .github/workflows/benchmarks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmarks.yaml b/.github/workflows/benchmarks.yaml index a05250671..0461d1950 100644 --- a/.github/workflows/benchmarks.yaml +++ b/.github/workflows/benchmarks.yaml @@ -18,7 +18,6 @@ jobs: runs-on: ubuntu-latest permissions: contents: read - id-token: write steps: - name: Checkout uses: actions/checkout@v4 @@ -43,5 +42,6 @@ jobs: RAY_ENABLE_UV_RUN_RUNTIME_ENV: 0 PLUGBOARD_IO_READ_TIMEOUT: 5.0 with: + mode: simulation run: uv run pytest tests/benchmark/ --codspeed