docs(code-review): re-review 17 changed modules at 1f9de8a2 — 8 new findings
Re-reviewed the modules whose source changed since the last review baseline (full-review remediationfd618cf1+ InboundAPI Database-helper fixesb3c90143), focused on whether the fixes are sound and regression-free. 9 of 17 modules clean; 8 new findings (0 Critical, 0 High, 4 Medium, 4 Low), all code-verified by the orchestrator before recording: - DataConnectionLayer-029 (Med): DCL-023's unsubscribe-clears-in-flight reopens a double-subscribe window that leaks an orphaned alarm feed; the alarm completion handler overwrites the subscription id without the tag-path guard at line 908. - InboundAPI-031 (Med): WaitForAttribute's 5s grace backstop is tighter than the CommunicationService Ask's timeout+IntegrationTimeout (30s) round-trip slack, so a slow-but-valid timed-out 'false' arriving in the 5-30s window is cancelled into an unhandled OperationCanceledException/500 (contradicts spec 6 + its own comment). - SiteRuntime-032 (Med): SiteRuntime-029's wasPresent guard skips the deployed-count decrement when deleting a DISABLED instance (absent from both maps), drifting the health-dashboard tally; self-heals on singleton restart (observational, hence Med). - StoreAndForward-028 (Med): StoreAndForward-025 resets the register-guard but not _bufferedCount, so a same-instance Stop->Start re-seeds the depth gauge to ~2N. - AuditLog-017, CentralUI-037, ScriptAnalysis-009, SiteRuntime-033 (Low): a test-coverage gap plus stale doc-comments/spec following the remediation. Header commit/date bumped to1f9de8a2/ 2026-06-24 on all 17 modules; README regenerated (8 pending / 576 total).
This commit is contained in:
@@ -5,9 +5,9 @@
|
||||
| Module | `src/ZB.MOM.WW.ScadaBridge.ExternalSystemGateway` |
|
||||
| Design doc | `docs/requirements/Component-ExternalSystemGateway.md` |
|
||||
| Status | Reviewed |
|
||||
| Last reviewed | 2026-06-20 |
|
||||
| Last reviewed | 2026-06-24 |
|
||||
| Reviewer | claude-agent |
|
||||
| Commit reviewed | `4307c381` |
|
||||
| Commit reviewed | `1f9de8a2` |
|
||||
| Open findings | 0 |
|
||||
|
||||
## Summary
|
||||
@@ -1507,3 +1507,26 @@ whatever scheme is chosen.
|
||||
**Resolution**
|
||||
|
||||
Resolved 2026-06-20 (commit `fd618cf1`): renumbered the inline `// [n]` case labels in `ExecuteWriteAsync` to match the method header's rationale list (cancellation=[1], SqlException=[2], non-Sql=[3]), and realigned the three corresponding labels in the test file. Comment-only.
|
||||
|
||||
## Re-review — 2026-06-24 (commit `1f9de8a2`)
|
||||
|
||||
Focused re-review of the changes since the prior review — verifying the code-review remediation + feature fixes are sound and regression-free. Reviewed by a per-module workflow agent; findings code-verified by the orchestrator.
|
||||
|
||||
**Changes reviewed:** In DatabaseGateway.ExecuteWriteAsync, the catch (SqlException) block now calls cancellationToken.ThrowIfCancellationRequested() before SqlErrorClassifier.Throw(...), so a caller-token cancel that surfaces from the SQL driver as a SqlException (mid-flight cancel, e.g. error number 0/3980) propagates as OperationCanceledException instead of being reclassified as a permanent DB error. The three inline case labels were also renumbered ([2]->[1] cancellation, [1]->[3] non-Sql transient, new [2] for the SqlException branch) to match the method header list and the test labels. A new regression test (CachedWrite_CancellationSurfacingAsSqlException_PropagatesCanceled_NotReclassifiedPermanent) fabricates a cancel-shaped SqlException via reflection and asserts OperationCanceledException propagates with nothing buffered.
|
||||
|
||||
**Verdict:** The change is small, correct, and regression-free. It implements exactly the fix prescribed for ExternalSystemGateway-025 (and its sibling comment-ordering finding -026), matching the recommendation verbatim and mirroring the HTTP path's cancel-not-reclassified contract. Catch ordering is sound: the new ThrowIfCancellationRequested sits in the dedicated SqlException branch ahead of SqlErrorClassifier.Throw, so a cancel-shaped SqlException now propagates as OperationCanceledException while the non-cancel path is a no-op and classifies exactly as before. The project builds clean (0 warnings) and the targeted cancellation/outage tests pass (7/7). No new issues found.
|
||||
|
||||
| # | Category | Examined | Notes |
|
||||
|---|----------|----------|-------|
|
||||
| 1 | Correctness & logic bugs | ☑ | ThrowIfCancellationRequested correctly placed before SqlErrorClassifier.Throw; no-op when token not cancelled, so the classify path is unchanged. No issues found. |
|
||||
| 2 | Akka.NET conventions | ☑ | DatabaseGateway is a plain service, not an actor; no actor-state/Tell/Ask/closure-capture surface touched by the change. No issues found. |
|
||||
| 3 | Concurrency & thread safety | ☑ | No shared mutable state introduced; the change reads the caller's CancellationToken only. No issues found. |
|
||||
| 4 | Error handling & resilience | ☑ | This IS the change: caller cancel now wins over permanent-error reclassification regardless of driver exception shape; transient-vs-permanent classification for S&F is otherwise preserved. No issues found. |
|
||||
| 5 | Security | ☑ | Error context still uses the connection NAME, never the connection string; no credential leakage. SQL still parameterized in RunSqlAsync. No issues found. |
|
||||
| 6 | Performance & resource management | ☑ | RunSqlAsync still disposes connection/command via await using/using; the added token check adds no allocation or resource cost. No issues found. |
|
||||
| 7 | Design-document adherence | ☑ | Component-ExternalSystemGateway.md transient/permanent contract intact; doc need not enumerate driver exception shapes, so no doc drift. No issues found. |
|
||||
| 8 | Code organization & conventions | ☑ | Single classification seam (ExecuteWriteAsync) preserved; catch order mirrors ExternalSystemClient.InvokeHttpAsync. No issues found. |
|
||||
| 9 | Testing coverage | ☑ | New regression test drives a fabricated cancel-shaped SqlException through the production classification via the RawExecuteStubGateway seam and asserts OperationCanceledException with zero buffered rows; 7/7 targeted tests pass. No issues found. |
|
||||
| 10 | Documentation & comments | ☑ | Inline [1]/[2]/[3] labels now align with the method header list and the test file labels, resolving the prior mis-ordering. No issues found. |
|
||||
|
||||
_No new findings — the changes in this module are clean._
|
||||
|
||||
Reference in New Issue
Block a user