Files
mxaccessgw/docs/ToolchainLinks.md
T
Joseph Doherty bfcf82975c
ci / nightly-windev (push) Has been skipped
ci / windows-x86 (push) Successful in 1m14s
ci / java (push) Successful in 2m19s
ci / portable (push) Successful in 8m48s
test(windev): buffer the test named pipes so the full-suite testhost exits
The windev full-suite wedge — every test reported, then the x64 testhost sitting
at ~0 CPU forever while `dotnet test` never returns — was one test blocked on a
pipe write, not a leaked thread or an undisposed fixture.

`dotnet-stack report` on the wedged host showed no thread running test code:
xUnit's RunTestsInAssembly was parked on WaitHandle.WaitOne() waiting for the
assembly-finished event, so the wait lived in a suspended async state machine.
`dotnet-dump analyze -c dumpasync` named the frame — WorkerClientTests
.StagingChannelOverflowFaultsWorkerWithoutWaitingForFullModeTimeout awaiting
WorkerFrameWriter.WriteAsync on a 63-byte frame, with <extra>5__15 = 6, i.e. the
seventh of the twelve events the test pushes past the client's staging bound.

That test faults the worker client on purpose, and a faulted client stops its
read loop by design. The test-side pipe came from the NamedPipeServerStream
overload without buffer arguments, which passes inBufferSize: 0 / outBufferSize: 0
to CreateNamedPipe; on Windows that reserves no buffer at all, so a write
completes only once the peer reads it. Measured on windev, that pipe absorbed
0 bytes against a non-reading peer where the same pipe declared with 64 KiB
buffers absorbed 65 520. On macOS and Linux .NET backs named pipes with Unix
domain sockets whose socket buffer swallows the writes regardless, which is why
the identical test never hung there and the bug read as environmental.

Test-owned server pipes now go through TestSupport/TestNamedPipe.CreateServer in
both test projects, declaring explicit 64 KiB buffers so those tests exercise the
gateway's own staging/queue backpressure rather than the OS pipe's flow control.

Separately, every fake-worker write in WorkerClientTests now goes through
PipePair.WriteAsync, bounded by the class's five-second TestTimeout. That is
where the severity came from: a test method that never returns keeps xUnit from
raising ITestAssemblyFinished, so one unbounded await cost the whole suite its
result. A blocked write is now a named test failure instead of a silent wedge.

The fix also retires a wrong belief the wedge had created. windev reported 855
where macOS reported 879, and that gap was recorded in GatewayTesting.md as
Unix-gated test cases; it was really the results lost when the wedged host was
torn down. The same clone now reports 879 passed, matching macOS exactly.

Product code is unaffected. SessionWorkerClientFactory.CreatePipe keeps the
unbuffered declaration deliberately: both ends run continuous read loops and every
gateway write is bounded by the worker client's _stopCts, so a stalled peer
cancels the write rather than blocking on it.

Verified on windev at this SHA: gateway suite x64 three times (879 passed,
exit 0, no surviving testhost each time) and Worker.Tests x86 twice (400 passed,
11 skipped, exit 0, clean), plus the macOS gateway suite once (879 passed).

Docs: GatewayTesting.md replaces the --blame-hang workaround section with the
root cause and corrects the baseline to 879, CLAUDE.md's Source Update Workflow
no longer tells readers the windev suite wedges, and ToolchainLinks.md records
dotnet-stack and dotnet-dump as installed on windev.
2026-08-10 10:01:57 -04:00

194 lines
7.2 KiB
Markdown

# Toolchain Links
This machine has the project toolchain installed for gateway, worker, dashboard,
protobuf/gRPC contracts, and the planned .NET, Go, Rust, Python, and Java
clients.
If a new terminal cannot find a recently installed tool, refresh PATH in
PowerShell:
```powershell
$env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User')
```
## Core Tools
| Tool | Version | Path |
| --- | --- | --- |
| Git | 2.53.0.windows.2 | `C:\Program Files\Git\cmd\git.exe` |
| winget | 1.28.240 | `C:\Users\dohertj2\AppData\Local\Microsoft\WindowsApps\winget.exe` |
| SQLCMD | 14.0.1000.169 NT | `C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\SQLCMD.EXE` |
| SQLite CLI | 3.53.0 | `C:\Users\dohertj2\AppData\Local\Microsoft\WinGet\Links\sqlite3.exe` |
| grpcurl | 1.9.3 | `C:\Users\dohertj2\AppData\Local\Microsoft\WinGet\Links\grpcurl.exe` |
## .NET And Windows Build Tools
| Tool | Version | Path |
| --- | --- | --- |
| .NET SDK | 10.0.201 | `C:\Program Files\dotnet\dotnet.exe` |
| .NET runtime | 10.0.5 | `C:\Program Files\dotnet\shared\Microsoft.NETCore.App` |
| ASP.NET Core runtime | 10.0.5 | `C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App` |
| Windows Desktop runtime | 10.0.5 | `C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App` |
| MSBuild | 17.14.40.60911 | `C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\MSBuild.exe` |
| Visual Studio Build Tools | 2022 BuildTools | `C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools` |
| VC tools | 14.44.35207 | `C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.44.35207` |
| C compiler x64 | 14.44.35207 | `C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.44.35207\bin\Hostx64\x64\cl.exe` |
| Linker x64 | 14.44.35207 | `C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.44.35207\bin\Hostx64\x64\link.exe` |
| C compiler x86 | 14.44.35207 | `C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.44.35207\bin\Hostx64\x86\cl.exe` |
| Linker x86 | 14.44.35207 | `C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.44.35207\bin\Hostx64\x86\link.exe` |
| LibMan CLI | 3.0.71 | `C:\Users\dohertj2\.dotnet\tools\libman.exe` |
| dotnet-stack | 9.0.661903 | `C:\Users\dohertj2\.dotnet\tools\dotnet-stack.exe` |
| dotnet-dump | 9.0.661903 | `C:\Users\dohertj2\.dotnet\tools\dotnet-dump.exe` |
`dotnet-stack` and `dotnet-dump` are the diagnostics pair for a process that stops
making progress but does not exit. `dotnet-stack report -p <pid>` prints every
managed thread's stack, which is enough when a *thread* is blocked; when nothing is
on a thread the wait lives in a suspended async state machine, and only
`dotnet-dump collect -p <pid>` followed by `dotnet-dump analyze <dump> -c dumpasync`
reveals it. Both were installed user-local with `dotnet tool install -g` while
root-causing the windev test-host hang described in `docs/GatewayTesting.md`.
Reference assemblies:
```text
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8.1
```
Environment:
```text
DOTNET_ROOT=C:\Program Files\dotnet
```
Use `dotnet build` for SDK-style projects. Use the full MSBuild path above when
a .NET Framework or COM interop build needs classic Visual Studio MSBuild.
## Go
| Tool | Version | Path |
| --- | --- | --- |
| Go | 1.26.2 windows/amd64 | `C:\Program Files\Go\bin\go.exe` |
| protoc-gen-go | latest installed by `go install` | `C:\Users\dohertj2\go\bin\protoc-gen-go.exe` |
| protoc-gen-go-grpc | latest installed by `go install` | `C:\Users\dohertj2\go\bin\protoc-gen-go-grpc.exe` |
Environment:
```text
GOROOT=C:\Program Files\Go
GOPATH=C:\Users\dohertj2\go
Go plugin bin=C:\Users\dohertj2\go\bin
```
Installed plugin commands:
```powershell
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
```
## Rust
| Tool | Version | Path |
| --- | --- | --- |
| rustup | 1.29.0 | `C:\Users\dohertj2\.cargo\bin\rustup.exe` |
| rustc | 1.95.0 | `C:\Users\dohertj2\.cargo\bin\rustc.exe` |
| cargo | 1.95.0 | `C:\Users\dohertj2\.cargo\bin\cargo.exe` |
Rust uses the MSVC toolchain installed with Visual Studio Build Tools. The
default Rust linker smoke test has passed.
User cargo bin:
```text
C:\Users\dohertj2\.cargo\bin
```
## Python
| Tool | Version | Path |
| --- | --- | --- |
| Python | 3.12.10 | `C:\Users\dohertj2\AppData\Local\Programs\Python\Python312\python.exe` |
| Python launcher | installed | `C:\Users\dohertj2\AppData\Local\Programs\Python\Launcher\py.exe` |
| pip | 26.0.1 | Python 3.12 site packages |
Installed Python packages:
```text
grpcio==1.80.0
grpcio-tools==1.80.0
protobuf==6.33.6
pytest==9.0.3
pytest-asyncio==1.3.0
click==8.3.3
typer==0.25.0
```
## Java
| Tool | Version | Path |
| --- | --- | --- |
| Java runtime | Temurin 21.0.10+7 LTS | `C:\Program Files\Eclipse Adoptium\jdk-21.0.10.7-hotspot\bin\java.exe` |
| Java compiler | Temurin 21.0.10+7 LTS | `C:\Program Files\Eclipse Adoptium\jdk-21.0.10.7-hotspot\bin\javac.exe` |
| Gradle | 9.4.1 | `C:\Tools\gradle-9.4.1\bin\gradle.bat` |
| Maven | 3.9.15 | `C:\Tools\apache-maven-3.9.15\bin\mvn.cmd` |
The Java client was retargeted 21 -> 17 for Ignition 8.3 (`clients/java/build.gradle`
declares a `JavaLanguageVersion.of(17)` toolchain). Gradle resolves toolchains by
version, so a JDK 17 must be available on the build host even though the runtime
above is Temurin 21 (a 17-targeted build still runs on 21+).
Environment:
```text
JAVA_HOME=C:\Program Files\Eclipse Adoptium\jdk-21.0.10.7-hotspot
GRADLE_HOME=C:\Tools\gradle-9.4.1
MAVEN_HOME=C:\Tools\apache-maven-3.9.15
```
## Protobuf And gRPC
| Tool | Version | Path |
| --- | --- | --- |
| protoc | 34.1 | `C:\Users\dohertj2\AppData\Local\Microsoft\WinGet\Packages\Google.Protobuf_Microsoft.Winget.Source_8wekyb3d8bbwe\bin\protoc.exe` |
| Buf | 1.68.4 | `C:\Users\dohertj2\AppData\Local\Microsoft\WinGet\Links\buf.exe` |
| grpcurl | 1.9.3 | `C:\Users\dohertj2\AppData\Local\Microsoft\WinGet\Links\grpcurl.exe` |
Generated code should be reproducible from the shared `.proto` files. Do not
hand-edit generated protobuf or gRPC code.
## Project-Specific External References
MXAccess analysis:
```text
C:\Users\dohertj2\Desktop\mxaccess
C:\Users\dohertj2\Desktop\mxaccess\docs\MXAccess-Public-API.md
C:\Users\dohertj2\Desktop\mxaccess\docs\MXAccess-Reverse-Engineering.md
```
Galaxy Repository SQL notes:
```text
C:\Users\dohertj2\Desktop\lmxopcua\gr
C:\Users\dohertj2\Desktop\lmxopcua\gr\connectioninfo.md
C:\Users\dohertj2\Desktop\lmxopcua\gr\queries
```
## Smoke Checks Performed
These checks passed after installation:
- `dotnet build` of a temporary `net48` class library.
- `cargo build` of a temporary Rust binary using the MSVC linker.
- `go build` of a temporary Go module.
- `javac` compile of a temporary Java class.
- Python imports for `grpc`, `grpc_tools`, and `pytest`.
## Related Documentation
- [Implementation Plan Index](./ImplementationPlanIndex.md)
- [Client Proto Generation](./ClientProtoGeneration.md)
- [Client Packaging](./ClientPackaging.md)