Skip to content

Commit ce3433e

Browse files
rustyconoverclaude
andcommitted
tests: warm the shared fixture worker while the test processes collect
The first tests to reach the launched fixture worker all waited for it to start (about a second of imports), then for the first function listings, which build and encode every function's metadata before it is cached. Each listing costs the one GIL-bound worker 0.2-0.3 s, and the early tests ran them together: the first listing tests took 2-4.5 s against 0.3-0.4 s alone. The controller now launches the worker and runs one listing of each function type on a background thread from pytest_configure, while the xdist workers collect (several seconds). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 4ebbaeb commit ce3433e

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

‎tests/conftest.py‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
"""Shared fixtures for VGI tests."""
44

5+
import contextlib
56
import logging
67
import os
78
import shlex
89
import shutil
910
import subprocess
1011
import sys
12+
import threading
1113
import uuid
1214
from typing import Any
1315

@@ -74,6 +76,38 @@ def _fixture_command(*argv: str) -> str:
7476
SUBPROCESS_FIXTURE_WORKER = "vgi-fixture-worker"
7577

7678

79+
def pytest_configure(config: pytest.Config) -> None:
80+
"""Start the shared fixture worker while the test processes collect.
81+
82+
Otherwise the first tests to reach it all wait for its start (about a
83+
second of imports) and then for the first function listings, which build
84+
and encode every function's metadata before it is cached; each costs
85+
the one GIL-bound worker 0.2-0.3 s, and the early tests run them all at
86+
once. Collection takes several seconds, so warming the worker in the
87+
background here costs nothing. Only the controlling process does it.
88+
"""
89+
if hasattr(config, "workerinput") or TEST_TRANSPORT != "launch":
90+
return
91+
threading.Thread(target=_warm_fixture_worker, name="warm-fixture-worker", daemon=True).start()
92+
93+
94+
def _warm_fixture_worker() -> None:
95+
"""Launch the fixture worker and fill its function-listing caches."""
96+
from vgi.catalog import SchemaObjectType
97+
from vgi.client import Client
98+
99+
# Best effort: a worker that cannot start fails the tests that use it, with
100+
# the real error.
101+
with contextlib.suppress(Exception), Client(FIXTURE_WORKER) as client:
102+
attach = client.catalog_attach(name="example", options={}, data_version_spec=None, implementation_version=None)
103+
for kind in (
104+
SchemaObjectType.TABLE_FUNCTION,
105+
SchemaObjectType.SCALAR_FUNCTION,
106+
SchemaObjectType.AGGREGATE_FUNCTION,
107+
):
108+
list(client.schema_contents(attach_opaque_data=attach.attach_opaque_data, path=["main"], type=kind))
109+
110+
77111
def pytest_unconfigure(config: pytest.Config) -> None:
78112
"""Stop this session's launched workers rather than leaving them to idle out.
79113

0 commit comments

Comments
 (0)