docs: update differences.md sections 3-6 and 9 to reflect implemented features
Update comparison tables for protocol parsing (tracing, MIME headers, INFO caching, Span-based MSG), subscriptions (generation ID, Stats, SubjectsCollide, token utils, account limits), auth (deny enforcement, LRU cache, response permissions, auth expiry), configuration (CLI flags, MaxSubs, Tags, file logging), and logging (trace/debug modes, file output). Mark 11 summary items as resolved.
This commit is contained in:
@@ -135,16 +135,16 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
| Feature | Go | .NET | Notes |
|
| Feature | Go | .NET | Notes |
|
||||||
|---------|:--:|:----:|-------|
|
|---------|:--:|:----:|-------|
|
||||||
| Multi-client-type command routing | Y | N | Go checks `c.kind` to allow/reject commands |
|
| Multi-client-type command routing | Y | N | Go checks `c.kind` to allow/reject commands |
|
||||||
| Protocol tracing in parser | Y | N | Go calls `traceInOp()` per operation |
|
| Protocol tracing in parser | Y | Y | `TraceInOp()` logs `<<- OP arg` at `LogLevel.Trace` via optional `ILogger` |
|
||||||
| Subject mapping (input→output) | Y | N | Go transforms subjects via mapping rules |
|
| Subject mapping (input→output) | Y | N | Go transforms subjects via mapping rules |
|
||||||
| MIME header parsing | Y | N | .NET delegates header handling to client layer |
|
| MIME header parsing | Y | Y | `NatsHeaderParser.Parse()` — status line + key-value headers from `ReadOnlySpan<byte>` |
|
||||||
| Message trace event initialization | Y | N | |
|
| Message trace event initialization | Y | N | |
|
||||||
|
|
||||||
### Protocol Writing
|
### Protocol Writing
|
||||||
| Aspect | Go | .NET | Notes |
|
| Aspect | Go | .NET | Notes |
|
||||||
|--------|:--:|:----:|-------|
|
|--------|:--:|:----:|-------|
|
||||||
| INFO serialization | Once at startup | Every send | .NET re-serializes JSON each time |
|
| INFO serialization | Once at startup | Once at startup | Cached at startup; nonce connections serialize per-connection |
|
||||||
| MSG/HMSG construction | Direct buffer write | String interpolation → byte encode | More allocations in .NET |
|
| MSG/HMSG construction | Direct buffer write | Span-based buffer write | `int.TryFormat` + `CopyTo` into rented buffer, no string allocations |
|
||||||
| Pre-encoded constants | Y | Y | Both pre-encode PING/PONG/OK |
|
| Pre-encoded constants | Y | Y | Both pre-encode PING/PONG/OK |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -159,18 +159,18 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
| Result caching (1024 max) | Y | Y | Same limits |
|
| Result caching (1024 max) | Y | Y | Same limits |
|
||||||
| `plist` optimization (>256 subs) | Y | N | Go converts high-fanout nodes to array |
|
| `plist` optimization (>256 subs) | Y | N | Go converts high-fanout nodes to array |
|
||||||
| Async cache sweep (background) | Y | N | .NET sweeps inline under write lock |
|
| Async cache sweep (background) | Y | N | .NET sweeps inline under write lock |
|
||||||
| Atomic generation ID for invalidation | Y | N | .NET clears cache explicitly |
|
| Atomic generation ID for invalidation | Y | Y | `Interlocked.Increment` on insert/remove; cached results store generation |
|
||||||
| Cache eviction strategy | Random | First-N | Semantic difference minimal |
|
| Cache eviction strategy | Random | First-N | Semantic difference minimal |
|
||||||
|
|
||||||
### Missing SubList Features
|
### SubList Features
|
||||||
| Feature | Go | .NET | Notes |
|
| Feature | Go | .NET | Notes |
|
||||||
|---------|:--:|:----:|-------|
|
|---------|:--:|:----:|-------|
|
||||||
| `Stats()` — comprehensive statistics | Y | N | Matches, cache hits, inserts, removes, fanout |
|
| `Stats()` — comprehensive statistics | Y | Y | Matches, cache hits, inserts, removes tracked via `Interlocked` |
|
||||||
| `HasInterest()` — fast bool check | Y | N | |
|
| `HasInterest()` — fast bool check | Y | Y | Walks trie without allocating result list |
|
||||||
| `NumInterest()` — fast count | Y | N | |
|
| `NumInterest()` — fast count | Y | Y | Counts plain + queue subs without allocation |
|
||||||
| `ReverseMatch()` — pattern→literal query | Y | N | |
|
| `ReverseMatch()` — pattern→literal query | Y | Y | Finds subscriptions whose wildcards match a literal subject |
|
||||||
| `RemoveBatch()` — efficient bulk removal | Y | N | |
|
| `RemoveBatch()` — efficient bulk removal | Y | Y | Single generation increment for batch; increments `_removes` per sub |
|
||||||
| `All()` — enumerate all subscriptions | Y | N | |
|
| `All()` — enumerate all subscriptions | Y | Y | Recursive trie walk returning all subscriptions |
|
||||||
| Notification system (interest changes) | Y | N | |
|
| Notification system (interest changes) | Y | N | |
|
||||||
| Local/remote subscription filtering | Y | N | |
|
| Local/remote subscription filtering | Y | N | |
|
||||||
| Queue weight expansion (remote subs) | Y | N | |
|
| Queue weight expansion (remote subs) | Y | N | |
|
||||||
@@ -181,16 +181,16 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
|---------|:--:|:----:|-------|
|
|---------|:--:|:----:|-------|
|
||||||
| Basic validation (empty tokens, wildcards) | Y | Y | |
|
| Basic validation (empty tokens, wildcards) | Y | Y | |
|
||||||
| Literal subject check | Y | Y | |
|
| Literal subject check | Y | Y | |
|
||||||
| UTF-8/null rune validation | Y | N | Go has `checkRunes` parameter |
|
| UTF-8/null rune validation | Y | Y | `IsValidSubject(string, bool checkRunes)` rejects null bytes |
|
||||||
| Collision detection (`SubjectsCollide`) | Y | N | |
|
| Collision detection (`SubjectsCollide`) | Y | Y | Token-by-token wildcard comparison; O(n) via upfront `Split` |
|
||||||
| Token utilities (`tokenAt`, `numTokens`) | Y | N | |
|
| Token utilities (`tokenAt`, `numTokens`) | Y | Y | `TokenAt` returns `ReadOnlySpan<char>`; `NumTokens` counts separators |
|
||||||
| Stack-allocated token buffer | Y | N | Go uses `[32]string{}` on stack |
|
| Stack-allocated token buffer | Y | N | Go uses `[32]string{}` on stack |
|
||||||
|
|
||||||
### Subscription Lifecycle
|
### Subscription Lifecycle
|
||||||
| Feature | Go | .NET | Notes |
|
| Feature | Go | .NET | Notes |
|
||||||
|---------|:--:|:----:|-------|
|
|---------|:--:|:----:|-------|
|
||||||
| Per-account subscription limit | Y | N | |
|
| Per-account subscription limit | Y | Y | `Account.IncrementSubscriptions()` returns false when `MaxSubscriptions` exceeded |
|
||||||
| Auto-unsubscribe on max messages | Y | Y | .NET enforces at delivery time (NatsServer.cs:269-270) |
|
| Auto-unsubscribe on max messages | Y | Y | Enforced at delivery; sub removed from trie + client dict when exhausted |
|
||||||
| Subscription routing propagation | Y | N | For clusters |
|
| Subscription routing propagation | Y | N | For clusters |
|
||||||
| Queue weight (`qw`) field | Y | N | For remote queue load balancing |
|
| Queue weight (`qw`) field | Y | N | For remote queue load balancing |
|
||||||
|
|
||||||
@@ -217,10 +217,10 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
| Feature | Go | .NET | Notes |
|
| Feature | Go | .NET | Notes |
|
||||||
|---------|:--:|:----:|-------|
|
|---------|:--:|:----:|-------|
|
||||||
| Per-account SubList isolation | Y | Y | |
|
| Per-account SubList isolation | Y | Y | |
|
||||||
| Multi-account user resolution | Y | N | .NET has basic account, no resolution |
|
| Multi-account user resolution | Y | Y | `AccountConfig` per account in `NatsOptions.Accounts`; `GetOrCreateAccount` wires limits |
|
||||||
| Account exports/imports | Y | N | |
|
| Account exports/imports | Y | N | |
|
||||||
| Per-account connection limits | Y | N | |
|
| Per-account connection limits | Y | Y | `Account.AddClient()` returns false when `MaxConnections` exceeded |
|
||||||
| Per-account subscription limits | Y | N | |
|
| Per-account subscription limits | Y | Y | `Account.IncrementSubscriptions()` enforced in `ProcessSub()` |
|
||||||
| Account JetStream limits | Y | N | Excluded per scope |
|
| Account JetStream limits | Y | N | Excluded per scope |
|
||||||
|
|
||||||
### Permissions
|
### Permissions
|
||||||
@@ -228,11 +228,12 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
|---------|:--:|:----:|-------|
|
|---------|:--:|:----:|-------|
|
||||||
| Publish allow list | Y | Y | |
|
| Publish allow list | Y | Y | |
|
||||||
| Subscribe allow list | Y | Y | |
|
| Subscribe allow list | Y | Y | |
|
||||||
| Publish deny list | Y | Partial | .NET has deny in struct but limited enforcement |
|
| Publish deny list | Y | Y | Full enforcement with LRU-cached results |
|
||||||
| Subscribe deny list | Y | Partial | Same |
|
| Subscribe deny list | Y | Y | Queue-aware deny checking in `IsSubscribeAllowed` |
|
||||||
| Message-level deny filtering | Y | N | Go filters at delivery time |
|
| Message-level deny filtering | Y | Y | `IsDeliveryAllowed()` checked before MSG send; auto-unsub cleanup on deny |
|
||||||
| Permission caching (128 entries) | Y | N | |
|
| Permission caching (128 entries) | Y | Y | `PermissionLruCache` — Dictionary+LinkedList LRU, matching Go's `maxPermCacheSize` |
|
||||||
| Response permissions (reply tracking) | Y | N | Dynamic reply subject authorization |
|
| Response permissions (reply tracking) | Y | Y | `ResponseTracker` with configurable TTL + max messages; not LRU-cached |
|
||||||
|
| Auth expiry enforcement | Y | Y | `Task.Delay` timer closes client when JWT/auth expires |
|
||||||
| Permission templates (JWT) | Y | N | e.g., `{{name()}}`, `{{account-tag(...)}}` |
|
| Permission templates (JWT) | Y | N | e.g., `{{name()}}`, `{{account-tag(...)}}` |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -247,7 +248,7 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
| `-n/--name` (ServerName) | Y | Y | |
|
| `-n/--name` (ServerName) | Y | Y | |
|
||||||
| `-m/--http_port` (monitoring) | Y | Y | |
|
| `-m/--http_port` (monitoring) | Y | Y | |
|
||||||
| `-c` (config file) | Y | Stub | Flag parsed, stored in `ConfigFile`, no config parser |
|
| `-c` (config file) | Y | Stub | Flag parsed, stored in `ConfigFile`, no config parser |
|
||||||
| `-D/-V/-DV` (debug/trace) | Y | N | |
|
| `-D/-V/-DV` (debug/trace) | Y | Y | Sets `Debug`/`Trace` on `NatsOptions`, adjusts Serilog minimum level |
|
||||||
| `--tlscert/--tlskey/--tlscacert` | Y | Y | |
|
| `--tlscert/--tlskey/--tlscacert` | Y | Y | |
|
||||||
| `--tlsverify` | Y | Y | |
|
| `--tlsverify` | Y | Y | |
|
||||||
| `--http_base_path` | Y | Y | |
|
| `--http_base_path` | Y | Y | |
|
||||||
@@ -259,12 +260,12 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
| Config file parsing | Y | N | Go has custom `conf` parser with includes |
|
| Config file parsing | Y | N | Go has custom `conf` parser with includes |
|
||||||
| Hot reload (SIGHUP) | Y | N | |
|
| Hot reload (SIGHUP) | Y | N | |
|
||||||
| Config change detection | Y | N | Go tracks `inConfig`/`inCmdLine` origins |
|
| Config change detection | Y | N | Go tracks `inConfig`/`inCmdLine` origins |
|
||||||
| ~450 option fields | Y | ~54 | .NET covers core options only |
|
| ~450 option fields | Y | ~62 | .NET covers core + debug/trace/logging/limits/tags options |
|
||||||
|
|
||||||
### Missing Options Categories
|
### Missing Options Categories
|
||||||
- Logging options (file, rotation, syslog, trace levels)
|
- ~~Logging options (file, rotation, syslog, trace levels)~~ — File logging (`-l`), `LogSizeLimit`, Debug/Trace implemented; syslog/color/timestamp not yet
|
||||||
- Advanced limits (MaxSubs, MaxSubTokens, MaxPending, WriteDeadline)
|
- ~~Advanced limits (MaxSubs, MaxSubTokens, MaxPending, WriteDeadline)~~ — `MaxSubs`, `MaxSubTokens` implemented; MaxPending/WriteDeadline already existed
|
||||||
- Tags/metadata
|
- ~~Tags/metadata~~ — `Tags` dictionary implemented in `NatsOptions`
|
||||||
- OCSP configuration
|
- OCSP configuration
|
||||||
- WebSocket/MQTT options
|
- WebSocket/MQTT options
|
||||||
- Operator mode / account resolver
|
- Operator mode / account resolver
|
||||||
@@ -350,11 +351,11 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
| Feature | Go | .NET | Notes |
|
| Feature | Go | .NET | Notes |
|
||||||
|---------|:--:|:----:|-------|
|
|---------|:--:|:----:|-------|
|
||||||
| Structured logging | Partial | Y | .NET uses Serilog with ILogger<T> |
|
| Structured logging | Partial | Y | .NET uses Serilog with ILogger<T> |
|
||||||
| File logging with rotation | Y | N | |
|
| File logging with rotation | Y | Y | `-l` flag + `LogSizeLimit` option via Serilog.Sinks.File with `fileSizeLimitBytes` |
|
||||||
| Syslog (local and remote) | Y | N | |
|
| Syslog (local and remote) | Y | N | |
|
||||||
| Log reopening (SIGUSR1) | Y | N | |
|
| Log reopening (SIGUSR1) | Y | N | |
|
||||||
| Trace mode (protocol-level) | Y | N | |
|
| Trace mode (protocol-level) | Y | Y | `-V`/`-DV` flags; parser `TraceInOp()` logs `<<- OP arg` at Trace level |
|
||||||
| Debug mode | Y | N | |
|
| Debug mode | Y | Y | `-D`/`-DV` flags lower Serilog minimum to Debug/Verbose |
|
||||||
| Per-subsystem log control | Y | N | |
|
| Per-subsystem log control | Y | N | |
|
||||||
| Color output on TTY | Y | N | |
|
| Color output on TTY | Y | N | |
|
||||||
| Timestamp format control | Y | N | |
|
| Timestamp format control | Y | N | |
|
||||||
@@ -378,16 +379,16 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
## Summary: Critical Gaps for Production Use
|
## Summary: Critical Gaps for Production Use
|
||||||
|
|
||||||
### High Priority
|
### High Priority
|
||||||
1. **Slow consumer detection** — unbounded writes can exhaust memory (stat fields exist but no detection logic)
|
1. ~~**Slow consumer detection**~~ — implemented (pending bytes threshold + write deadline)
|
||||||
2. **Write coalescing / batch flush** — performance gap for high-throughput scenarios
|
2. ~~**Write coalescing / batch flush**~~ — implemented (channel-based write loop)
|
||||||
|
|
||||||
### Medium Priority
|
### Medium Priority
|
||||||
3. **Verbose mode** — clients expect `+OK` when `verbose: true`
|
3. ~~**Verbose mode**~~ — implemented (`+OK` on CONNECT/SUB/UNSUB/PUB)
|
||||||
4. **Permission deny enforcement at delivery** — deny lists checked at SUB/PUB time but not during message delivery
|
4. ~~**Permission deny enforcement at delivery**~~ — implemented (`IsDeliveryAllowed` + auto-unsub cleanup)
|
||||||
5. **Config file parsing** — needed for production deployment (CLI stub exists)
|
5. **Config file parsing** — needed for production deployment (CLI stub exists)
|
||||||
6. **Hot reload** — needed for zero-downtime config changes (SIGHUP stub exists)
|
6. **Hot reload** — needed for zero-downtime config changes (SIGHUP stub exists)
|
||||||
7. **File logging with rotation** — needed for production logging
|
7. ~~**File logging with rotation**~~ — implemented (Serilog.Sinks.File with `-l` flag)
|
||||||
8. **No-responders validation** — flag parsed but not enforced
|
8. ~~**No-responders validation**~~ — implemented (CONNECT validation + 503 HMSG)
|
||||||
|
|
||||||
### Lower Priority
|
### Lower Priority
|
||||||
9. **Dynamic buffer sizing** — delegated to Pipe, less optimized for long-lived connections
|
9. **Dynamic buffer sizing** — delegated to Pipe, less optimized for long-lived connections
|
||||||
@@ -395,8 +396,8 @@ Go implements a sophisticated slow consumer detection system:
|
|||||||
11. **TLS certificate mapping** — property exists, not implemented
|
11. **TLS certificate mapping** — property exists, not implemented
|
||||||
12. **OCSP support** — certificate revocation checking
|
12. **OCSP support** — certificate revocation checking
|
||||||
13. **Subject mapping** — input→output subject transformation
|
13. **Subject mapping** — input→output subject transformation
|
||||||
14. **Protocol tracing** — no trace-level logging
|
14. ~~**Protocol tracing**~~ — implemented (`TraceInOp` at `LogLevel.Trace`)
|
||||||
15. **Subscription statistics** — SubList has no stats collection
|
15. ~~**Subscription statistics**~~ — implemented (`Stats()`, `HasInterest()`, `NumInterest()`, etc.)
|
||||||
16. **Per-account limits** — connections, subscriptions per account
|
16. ~~**Per-account limits**~~ — implemented (connection + subscription limits via `AccountConfig`)
|
||||||
17. **Reply subject tracking** — dynamic response permissions
|
17. ~~**Reply subject tracking**~~ — implemented (`ResponseTracker` with TTL + max messages)
|
||||||
18. **Windows Service integration** — needed for Windows deployment
|
18. **Windows Service integration** — needed for Windows deployment
|
||||||
|
|||||||
Reference in New Issue
Block a user