Files
natsdotnet/gaps/stillmissing.md
2026-02-25 15:12:52 -05:00

144 lines
8.3 KiB
Markdown

# LOC Comparison: Go Reference vs .NET Port
> Generated 2026-02-25 (gap inventory populated). Lines of code counted with `wc -l` (includes blanks and comments).
## Summary
| Metric | Go | .NET | .NET / Go |
|--------|---:|-----:|----------:|
| **Source files** | 123 | 249 | 2.0x |
| **Source LOC** | 134,140 | 51,303 | 38% |
| **Test files** | 127 | 562 | 4.4x |
| **Test LOC** | 260,730 | 165,630 | 64% |
| **Total files** | 250 | 811 | 3.2x |
| **Total LOC** | 394,870 | 216,933 | 55% |
The .NET port has **more files** (smaller, focused C# files vs Go's monolithic files) but **fewer total lines**. Source code is at 38% of Go LOC. Test code is at 64% of Go LOC. The higher file count reflects C#'s convention of one class/type per file.
---
## Source Code by Functional Area
| Functional Area | Go Files | Go LOC | .NET Files | .NET LOC | .NET/Go | Detail File | Notes |
|-----------------|:--------:|-------:|:----------:|----------|--------:|-------------|-------|
| Core Server | 10 | 21,223 | 13 | 3,597 | 17% | [core-server.md](core-server.md) | Go `server.go` + `client.go` = 13K+ combined |
| Protocol | 3 | 1,829 | 6 | 1,156 | 63% | [protocol.md](protocol.md) | Parser, wire protocol, constants |
| Subscriptions | 2 | 2,416 | 10 | 2,142 | 89% | [subscriptions.md](subscriptions.md) | Subject matching, trie, transforms |
| Auth & Accounts | 5 | 7,260 | 41 | 3,445 | 47% | [auth-and-accounts.md](auth-and-accounts.md) | .NET includes Imports/ (12 files, 264 LOC) |
| Configuration | 3 | 1,871 | 12 | 4,559 | 244% | [configuration.md](configuration.md) | .NET exceeds Go; includes rich config parsing |
| Routes | 1 | 3,314 | 3 | 1,139 | 34% | [routes.md](routes.md) | Cluster full-mesh routing |
| Gateways | 1 | 3,426 | 6 | 1,368 | 40% | [gateways.md](gateways.md) | Inter-cluster bridges |
| Leaf Nodes | 1 | 3,470 | 5 | 1,553 | 45% | [leaf-nodes.md](leaf-nodes.md) | Hub-and-spoke edge topology |
| **JetStream** | **20** | **55,228** | **68** | **16,630** | **30%** | [jetstream.md](jetstream.md) | Largest module; see breakdown below |
| RAFT | 1 | 5,037 | 20 | 3,045 | 60% | [raft.md](raft.md) | Consensus protocol |
| MQTT | 1 | 5,882 | 10 | 1,853 | 31% | [mqtt.md](mqtt.md) | MQTT protocol adapter |
| WebSocket | 1 | 1,550 | 8 | 1,531 | 99% | [websocket.md](websocket.md) | Near-complete |
| Monitoring | 2 | 4,396 | 15 | 2,308 | 53% | [monitoring.md](monitoring.md) | HTTP endpoints (/varz, /connz, etc.) |
| Events | 2 | 4,133 | 5 | 1,642 | 40% | [events.md](events.md) | System events, message tracing |
| TLS / Security | 12 | 4,207 | 7 | 516 | 12% | [tls-security.md](tls-security.md) | OCSP, certs, ciphersuites, proxy proto |
| Internal DS | 34 | 4,020 | 7 | 4,225 | 105% | [internal-ds.md](internal-ds.md) | AVL, stree, THW, GSL, PSE, sysmem |
| Logging | 4 | 936 | 0 | 0 | -- | [logging.md](logging.md) | .NET uses Microsoft.Extensions.Logging |
| Utilities & Other | 19 | 3,282 | 3 | 244 | 7% | [utilities-and-other.md](utilities-and-other.md) | Ring, sendq, errors, ats, elastic, tpm |
| Misc / Uncategorized | 1 | 660 | 6 | 70 | -- | [misc-uncategorized.md](misc-uncategorized.md) | |
| **TOTAL** | **123** | **134,140** | **249** | **51,303** | **38%** | | |
### JetStream Breakdown
| JetStream Sub-area | Go Files | Go LOC | .NET Files | .NET LOC | .NET/Go |
|--------------------|:--------:|-------:|:----------:|----------|--------:|
| Core (orchestration, API, stream, consumer, store) | 10 | 28,150 | 5 | 1,656 | 6% |
| API handlers | -- | (in Core) | 13 | 2,011 | -- |
| Consumers | -- | (in Core) | 10 | 2,147 | -- |
| Models | -- | (in Core) | 4 | 230 | -- |
| Publish | -- | (in Core) | 5 | 639 | -- |
| MirrorSource | -- | (in Core) | 2 | 1,085 | -- |
| Snapshots | -- | (in Core) | 1 | 210 | -- |
| Validation | -- | (in Core) | 1 | 60 | -- |
| Storage (filestore, memstore, dirstore) | 9 | 16,191 | 19 | 6,254 | 39% |
| Cluster (jetstream_cluster.go) | 1 | 10,887 | 8 | 2,338 | 21% |
| **JetStream Total** | **20** | **55,228** | **68** | **16,630** | **30%** |
Go consolidates JetStream into a few massive files: `consumer.go` (~6K), `jetstream_api.go` (~5K), `stream.go` (~8K), `filestore.go` (~12K), `jetstream_cluster.go` (~11K). The .NET port decomposes these into smaller, focused files.
---
## Test Code by Functional Area
| Functional Area | Go Files | Go LOC | .NET Files | .NET LOC | .NET/Go |
|-----------------|:--------:|-------:|:----------:|----------|--------:|
| Core Server | 7 | 18,011 | 173* | 25,024* | 139%* |
| Protocol | 5 | 2,020 | 4 | 1,433 | 71% |
| Subscriptions | 2 | 2,711 | 8 | 1,211 | 45% |
| Auth & Accounts | 6 | 15,448 | 26 | 10,170 | 66% |
| Configuration | 3 | 5,281 | 12 | 8,237 | 156% |
| Routes | 1 | 5,041 | 18 | 6,025 | 120% |
| Gateways | 1 | 7,667 | 17 | 5,914 | 77% |
| Leaf Nodes | 2 | 11,778 | 22 | 7,238 | 61% |
| JetStream (all) | 22 | 105,284 | 160 | 65,314 | 62% |
| RAFT | 3 | 6,140 | 33 | 9,154 | 149% |
| MQTT | 3 | 9,793 | 25 | 5,953 | 61% |
| WebSocket | 1 | 4,982 | 13 | 2,590 | 52% |
| Monitoring | 1 | 6,603 | 19 | 5,989 | 91% |
| Events | 2 | 9,344 | 8 | 3,091 | 33% |
| NoRace / Stress | 2 | 12,009 | 3 | 2,342 | 20% |
| Internal DS | 7 | 3,557 | 6 | 3,837 | 108% |
| Integration (test/) | 35 | 29,812 | -- | -- | -- |
| Other / Misc | 14 | 2,904 | 14 | 2,058 | 71% |
| **TOTAL** | **127** | **260,730** | **562** | **165,630** | **64%** |
*\* The .NET "Core Server" root test directory (173 files, 25,024 LOC) contains mixed-purpose tests spanning multiple functional areas (server lifecycle, client protocol, pubsub, integration). Not directly comparable to the Go "Core Server" test files.*
### JetStream Test Breakdown
| JetStream Test Area | Go Files | Go LOC | .NET Files | .NET LOC | .NET/Go |
|---------------------|:--------:|-------:|:----------:|----------|--------:|
| Core tests | 9 | 42,582 | 50* | 14,824* | 35% |
| Storage tests | 4 | 16,930 | 32 | 14,672 | 87% |
| Cluster tests | 8 | 43,426 | 41 | 24,737 | 57% |
| Consumer tests | -- | (in Core) | 22 | 7,701 | -- |
| API tests | -- | (in Core) | 9 | 2,162 | -- |
| Other (mirror, snap, stream) | -- | (in Core) | 6 | 1,918 | -- |
| Benchmark | 1 | 2,346 | -- | -- | -- |
| **JetStream Test Total** | **22** | **105,284** | **160** | **65,314** | **62%** |
*\* JetStream root-level test files not in a named subdirectory.*
---
## Areas Where .NET Exceeds Go LOC
| Area | Go LOC | .NET LOC | Ratio | Explanation |
|------|-------:|----------|------:|-------------|
| Configuration | 1,871 | 4,559 | 2.4x | Richer config parser with lexer/token model |
| Internal DS | 4,020 | 4,225 | 1.05x | Full parity on AVL, stree, THW, GSL |
| WebSocket | 1,550 | 1,531 | 0.99x | Near-identical coverage |
---
## Largest Gaps (Source LOC)
| Area | Go LOC | .NET LOC | Gap (LOC) | .NET/Go |
|------|-------:|----------|----------:|--------:|
| Core Server | 21,223 | 3,877 | 17,346 | 18% |
| JetStream Core | 28,150 | 8,038 | 20,112 | 29% |
| JetStream Storage | 16,191 | 6,254 | 9,937 | 39% |
| JetStream Cluster | 10,887 | 2,338 | 8,549 | 21% |
| Auth & Accounts | 7,260 | 3,445 | 3,815 | 47% |
| MQTT | 5,882 | 1,853 | 4,029 | 31% |
| Monitoring | 4,396 | 2,308 | 2,088 | 53% |
| Events | 4,133 | 1,642 | 2,491 | 40% |
| TLS / Security | 4,207 | 516 | 3,691 | 12% |
| Utilities & Other | 3,282 | 244 | 3,038 | 7% |
---
## Notes
- **LOC counts include blank lines and comments.** Go tends to be more verbose with explicit error handling; C# uses exceptions and has less boilerplate per line. A 1:1 LOC ratio is not the goal.
- **Go's monolithic files vs .NET's granular files.** Go's `client.go` is 6,700+ lines; the .NET equivalent is split across `NatsClient.cs`, `ClientFlags.cs`, `ClientKind.cs`, `INatsClient.cs`, etc. File count comparisons favor .NET.
- **Go `test/` directory** (35 files, 29,812 LOC) contains integration/acceptance tests with no direct .NET equivalent directory; .NET integration tests are spread across subdirectories.
- **Go `norace_*_test.go`** files (12,009 LOC) contain long-running race-condition tests that cross multiple subsystems. .NET equivalents are in `Stress/` (2,342 LOC).
- **Configuration .NET > Go** because .NET implements a full lexer/parser/token pipeline for the NATS config format rather than using Go's simpler approach.
- **.NET Logging = 0 LOC** because it uses `Microsoft.Extensions.Logging` + `Serilog` as NuGet packages rather than custom logging code.
- **Internal Data Structures .NET >= Go** — the AVL, subject tree, time hash wheel, and GSL implementations are at or above Go parity.