Skip to content

Archive: C# implementation (no merge intended) - #1

Closed
long45343 wants to merge 32 commits into
gofrom
csharp
Closed

long45343 wants to merge 32 commits into
gofrom
csharp

Conversation

@long45343

Copy link
Copy Markdown
Owner

csharp 分支为 C# 实现归档,不计划合并。建此 PR 并立即关闭,以消除首页 Compare & pull request 提示。

long45343 and others added 30 commits August 18, 2026 23:03
- Contract tests: JSON sample corpus (duplicate/unknown fields, illegal
  numbers, depth-4, invalid UTF-8) + byte-level serialization invariants
- NetworkIntegration category (12 cases) over real Kestrel TLS with
  runtime self-signed certs: handshake, TLS 1.2/1.3 probes, frame
  fragmentation, oversize/zero-length 1009 closes, restart with token
  direct reconnect + persisted version baseline, snapshot election,
  graceful-shutdown bye/1001
- SlowHash category: real Argon2 Hash/Verify/NeedsRehash chain
- Unit gap closure: token illegal-number forms, CLI watermark
  allocation/recreate/overflow fail-fast, WithVersion, behavior-level
  duplicate-id idempotency
- CI: SlowHash merged into main test job; NetworkIntegration runs in a
  dedicated job; release workflow uses the same category filter
- docs/server-spec.md rewritten to match v0.3.5+ implementation with
  implementation-gap ledger; added specs/test-and-contract-spec.md and
  specs/spec-decisions.md
- Version 0.3.5 -> 0.4.0
…ag 16-byte)

Aligns with TextCascade-desktop v2.3.0: AES-GCM nonce unified to 12 bytes,
non-12-byte nonces rejected by clients; server remains payload-opaque.
- Reintroduce performance targets (P1-P8) with concrete scenarios S1-S8,
  sampling methods, and pass criteria; benchmark harness is not yet
  implemented, so the document is the measurement contract
- Include memory/CPU/cold-start commands for the deployed systemd service
  and a k6 sketch for latency sampling
- docs/server-spec.md §9 now defers to perf.md; CHANGELOG note added
Measured on the production VPS (2 vCPU / 1.6 GB, Ubuntu 24.04, .NET 10.0.11,
WSS loopback, tools/perf_probe.py):
- 1KB broadcast p95 3.5 ms (target 30 ms, pass); 512KB p95 103 ms (250 ms, pass)
- idle CPU 0.08% (pass); cold start 2 s (borderline pass)
- base memory 125-131 MB and +66 MB per 100 idle connections: old targets
  (50/20 MB) too tight, flagged for revision
- 1000-connection scenario exhausted the 1.6 GB box (same-host generator)
  and forced a VM reset: documented as untestable in this environment
- slow consumer isolated (A p95 7 ms) and silently aborted at ~16 s

Two implementation findings recorded in spec section 15: unbounded
shutdown close-handshake wait (34 s stop phase observed) and silent
queue-full abort without a disconnect security event.
…0-conn result

- CertificateLoader: on Windows load PFX with DefaultKeySet instead of
  EphemeralKeySet (SChannel rejects ephemeral keys for server-side TLS,
  0x8009030E); PEM certificates re-exported to a persisted key on Windows.
  Linux behavior unchanged. Spec 2.1 declares Windows Service hosting,
  which was unusable without this.
- perf.md: S5 verified on local Windows (32 GB) - 1000 connections held
  for 10 minutes, 0 errors, all alive, RSS delta ~211 MB (~211 KB/conn,
  one third of the Linux figure). P8 now passes; findings table updated
  (F4 resolved, F5 recorded as fixed).
A re-run of the 100-connection scenario on a JIT-warm process showed a
+24 MB delta instead of +66 MB: the initial figure mixed in one-time JIT
and GC heap expansion costs from the handshake storm. Marginal per-
connection cost is ~240 KB on Linux vs 211 KB on Windows (same order);
the Windows 211 KB figure benefited from amortization over 1000
connections. P2 revised to near-target; memory does not return to the
OS after connections close (GC segments retained).
…ate OOM

Persistent journal from the previous boot shows all 1000 upgrade requests
arriving in one second against a 40-second-old server process, journald
memory-pressure warnings from 00:50:18, journal silence at 00:51:53, and
a watchdog reset at 01:38:58 - with no OOM-kill records and swap=0.
Steady-state demand (1000 x 240 KB) fit comfortably; the crash was the
transient storm peak causing a kernel reclaim livelock.
A-tier stdlib audit replacements, zero behavior change:
- Auth.cs: Base64Url codec -> System.Buffers.Text.Base64Url
- IClock/SystemClock -> System.TimeProvider (DI singleton, tests pass TimeProvider.System)
- HeartbeatScannerService: System.Threading.Timer -> PeriodicTimer in BackgroundService (scan exceptions logged, stop order preserved)
- SingleInstanceLock: drop PID probing/stale recovery; OpenOrCreate + FileShare.None (OS releases on holder death, leftover files reused)
- ParseLoginRequest: single strict JsonSerializer.DeserializeAsync pass (net10 AllowDuplicateProperties=false, UnmappedMemberHandling.Disallow); 16KB cap via IHttpMaxRequestBodySizeFeature; "Invalid login request." merges into "Invalid JSON." (400/invalid_request unchanged)

Tests: 176/176 passing (Release x2 + Debug x1). Deployed to piyansvm.top and verified.
@long45343 long45343 closed this Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant