Make the concurrency harness run on Windows (portability) + document the RR-side caveat#1
Conversation
…the RR-side caveat The concurrency suite was authored for macOS/Linux; on Windows several harness-level assumptions break before any measurement runs. None of these touch the benchmark's methodology or the RocketRide-vs-LangChain numbers — they only let the suite execute on Windows and report honestly. Portability fixes: - harness/__init__.py: force UTF-8 on stdout/stderr. The runners print unicode (→, ×, …); on the legacy cp1252 Windows console a bare print() raises UnicodeEncodeError and aborts a run mid-benchmark (hit in data-isolation). No-op on POSIX. - config.py / nodes/workload/IInstance.py / concurrent-processing/run.py: default the params file and sqlite dirs to the OS temp dir instead of hardcoded /tmp (absent on Windows). Harness and node defaults kept in sync; still overridable via $ROCKETRIDE_BENCH_PARAMS / $BENCH_DB_DIR. Verified out-of-the-box (data-isolation 0-lost with no env set). - config.py: resolve engine.exe on Windows so provenance()/engine_version() work instead of silently recording "unknown". - scripts/provision.sh: add the Windows (win64 .zip) engine branch — the pinned server-v3.2.1 release already ships it; the script just never wired it up — plus the venv Scripts/ layout. - scripts/start_engine.sh: use engine.exe on Windows and actually forward --port=$PORT (previously computed for the health check but never passed to the engine). Honesty fix: - concurrent-processing/run.py: the VERDICT console line hardcoded "ok" for the RR cell regardless of the real status. results.json always recorded the true rr_topM_ok; the print now matches it (shows CHECK when node errors occur). Docs: - concurrent-work/harness/REPRODUCE-WINDOWS.md: Windows setup, what reproduces, and — flagged openly — the one RR-side result that does NOT reproduce clean on Windows: the concurrent-processing cell throws sqlite3.ProgrammingError (thread-affinity) because the node caches a module-level sqlite connection and the v3.2.1 engine dispatches a pipe's objects to different OS threads even at threads=1 (macOS/Linux use one thread per pipe). Process isolation still holds; only thread-affine resources are affected (data-isolation, which uses a GIL-safe list.append, reproduces 0-lost). Includes A/B/C fix options for the team to decide; this PR intentionally does NOT change RR-side numbers or the benchmark's claim. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… produced it Complete input/output evidence from re-running the concurrency suite on Windows 11, laid out like the macOS concurrent-work/runs/ tree so a reviewer/agent has everything in one place — including the RR-side result that does NOT reproduce clean on Windows. New: - harness/run_isolated_windows.py — Windows counterpart to run_isolated.sh (engine lifecycle on port 5566 via psutil, .venv/Scripts python, ROCKETRIDE_URI, restart+prime per warm-pool rep). run_isolated.sh can't drive Windows: it targets runs/, hardcodes port 5565 (held by the VS Code extension), and uses lsof / .venv/bin/python / --host=0.0.0.0. - runs-windows/ (834 KB) — 10x reps per bench (fault-isolation, concurrent-processing, data-isolation) + static authoring-effort, mirroring the runs/ convention: per-run results.json (metrics + full provenance) + run.log; gzipped native trace kept for run-01 only. Plus README.md (Windows scorecard + provenance + the caveat), COMMANDS.md (exact repro), per-bench REPORT.md, and lines-of-code.run.log. Provenance embedded in every results.json: Windows-11, Intel 10c/12t, engine 3.2.1.30 (sha256 b844140a…, the win64 prebuilt), langchain-core 0.3.86. Outcomes across the 10 reps (all captured, nothing hidden): - fault-isolation: RR isolation holds 10/10; in-process LangChain loses all 0/4 (exit 134) 10/10. - data-isolation: RR 0 lost / 0 leaked 10/10; LangChain shared dict silently loses 100–225 of 256. - concurrent-processing: LangChain .batch(shared) crashes 0/64 (sqlite3.ProgrammingError) 10/10; RR cell status=check 10/10 — the documented Windows caveat (module-level sqlite connection is thread-affine and the v3.2.1 engine runs a pipe's objects on different OS threads even at threads=1). Process isolation still holds; RR degrades partially vs LangChain's total loss. - authoring-effort: RR 0 imperative lines + validates; LangChain 14–17 lines, 5 hidden decisions. Data-only: no benchmark logic changed; the caveat is documented in runs-windows/README.md and harness/REPRODUCE-WINDOWS.md with A/B/C fix options for the team to decide. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Data to settle the
|
| version | internal hash | build stamp | engine_sha256 | |
|---|---|---|---|---|
| Mac (darwin-arm64) | 3.2.1.30 |
114509c6 |
2026-05-29T19:19:06Z |
4ad67d11… |
| Windows (win64) | 3.2.1.30 |
114509c6 |
2026-05-29T19:19:06Z |
b844140a… |
Identical version, internal hash, and build stamp. The engine_sha256 differs only because these are two platform compiles of that one build — the pinned public win64 release, not a dev build. So the behavior gap is same code, different platform, not a mismatched build.
2. Per-doc thread IDs — the smoking gun (already instrumented; tid= in every RRBENCH marker)
Distinct OS thread ids per pipe (pid), from the run-01 traces:
| trace | pipes | max tids / pipe | pipes running docs on >1 thread |
|---|---|---|---|
Mac rr.m8 |
8 | 1 | 0 / 8 |
Mac rr.m16 |
16 | 1 | 0 / 16 |
Windows rr.m8 |
8 | 2 | 2 / 8 |
Windows rr.m16 |
16 | 2 | 1 / 16 |
On Mac every pipe runs all its docs on one OS thread. On Windows some pipes rotate their (sequential) docs across two OS threads — confirming pool rotation under node dispatch even at threads=1. Reproduce by parsing tid=/pid= from runs-windows/concurrent-processing/run-01/trace/rr.m*.jsonl.gz.
4. Control — conn=per_call vs conn=module (same 64-doc workload, Windows :5566)
| conn | node_errors | pipes rotating >1 tid |
|---|---|---|
module (one cached connection) |
2 (sqlite3.ProgrammingError) |
2 |
per_call (fresh connection per doc) |
0 | 3 |
Decisive: per_call saw more thread rotation (3 pipes) yet zero errors. yes-per_call / no-module → the failure is purely sqlite connection thread-affinity — a cached, thread-affine handle reused off-thread. No data race, no corruption; the per-doc work itself runs fine across threads. It's only the cached connection.
5. Extension engine on :5565 — ruled out
The harness connected to the freshly-started benchmark engine on :5566, not the extension's :5565:
- the orchestrator sets
ROCKETRIDE_URI=ws://localhost:5566; - the engine emitted 72 valid
workloadRRBENCHmarkers — only the benchmark bundle has that node; the extension's engine would rejectuse()with an unknown-provider error and produce none; results/engine.pidrecorded the :5566 listener each start;provenance.engine_sha256 = b844140a…= thewin643.2.1 binary we extracted.
3. For eng / CTO (data-informed; the invariant call is yours)
Empirically, on Windows threads=1 does not yield one OS thread per pipe — #2 shows pipes rotating across 2 tids, so there is a thread pool/executor under node dispatch that reuses/rotates worker threads; on Mac it's one thread per pipe. The open question is whether one-thread-per-pipe is an intended invariant (then Windows is an engine bug) or incidental (then benchmark/user nodes must never cache thread-affine handles). The control shows either fix closes it:
- A / node: thread-local or per-call connection in the workload node (the
per_callrun above is already clean, 0 errors); - C / engine: pin one OS thread per pipe on Windows, restoring the naive-idiom-safety headline everywhere.
Net: same build; process isolation intact (M pipes = M PIDs); the Windows failure is a cached thread-affine sqlite connection meeting the engine's thread-pool rotation. Full evidence — 10× reps, gzipped traces, provenance — is in concurrent-work/runs-windows/.
PR: Make the concurrency harness run on Windows (portability) + document the RR-side caveat
Branch:
fix/windows-portability→mainScope: OS-portability + honesty fixes only. No change to the benchmark methodology or the RocketRide-vs-LangChain numbers.
Why
Re-ran the full suite on Windows 11 (repo numbers are from a Mac), with the pinned engine (
server-v3.2.1, thewin64build) and pinnedlangchain-core==0.3.86. Four of five headline results reproduced. Several harness-level assumptions broke before any measurement runs, and one RR-side result does not reproduce clean on Windows — documented openly rather than left for a re-runner to trip over.What reproduced on Windows
.batchshared-conn crashes 64/64 (sqlite3.ProgrammingError);.abatch/seq serialize (~6.8s). ✅Portability fixes (this PR)
harness/__init__.py) — runners print unicode (→ × …); on the cp1252 Windows console a bareprint()raisesUnicodeEncodeErrorand aborts a run mid-benchmark (hit in data-isolation). No-op on POSIX./tmp(config.py,nodes/workload/IInstance.py,concurrent-processing/run.py) —/tmpdoesn't exist on Windows. Harness and node defaults kept in sync; still overridable via$ROCKETRIDE_BENCH_PARAMS/$BENCH_DB_DIR. Verified out-of-the-box (data-isolation 0-lost with no env set).engine.exeon Windows (config.py) — soprovenance()/engine_version()work instead of recording "unknown".provision.shwin64 branch — the pinnedserver-v3.2.1release already shipswin64.zip; the script just never wired it up. Also handles the venvScripts/layout.start_engine.sh— useengine.exeon Windows and actually forward--port=$PORT(it was computed for the health check but never passed to the engine).Honesty fix
concurrent-processing/run.py— the VERDICT console line hardcoded"ok"for the RR cell regardless of real status.results.jsonalways recorded the truerr_topM_ok; the print now matches it (showsCHECKwhen node errors occur).Known caveat this PR documents but does NOT fix (RR-side)
On Windows,
concurrent-processing's RocketRide cell isstatus=check— ~8–12 of 72 docs raisesqlite3.ProgrammingError(thread-affinity). Process isolation still holds (M pipes = M PIDs), but the workload node caches a module-level sqlite connection, and the v3.2.1 engine dispatches a pipe's objects to different OS threads even atthreads=1(macOS/Linux use one thread per pipe). Only thread-affine resources are affected —data-isolation(GIL-safelist.append) reproduces 0-lost. The repo's own appendix honesty cell (1 pipe × threadCount=4→ 31 errors) already shows the mechanism; it just wasn't flagged as OS-dependent.Fix options (team decision — see
REPRODUCE-WINDOWS.md):threads=1mean one OS thread per pipe on Windows, restoring the naive-idiom-safety headline everywhere.This PR is Option C-neutral: it only makes the suite run and report honestly on Windows, leaving A/B/C to the team.
Testing
All benches re-run on Windows 11 against the pinned v3.2.1 engine with no manual env vars (only
ROCKETRIDE_URIfor the non-default port): data-isolation 0-lost, fault-isolation 10/10, concurrent-processing runs and now reports the real RR status. No regressions.🤖 Generated with Claude Code