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.KpiHistory` |
|
||||
| Design doc | `docs/requirements/Component-KpiHistory.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
|
||||
@@ -305,3 +305,26 @@ from KpiHistory-003.
|
||||
**Resolution**
|
||||
|
||||
Resolved 2026-06-20 (commit `fd618cf1`): corrected the `KpiSeriesBucketer` param XML doc — dropped the false 'largest-timestamp-wins / stable ties' claim; now states it requires ascending-sorted input and selects last-in-iteration otherwise. Doc-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:** The diff adds an in-flight guard (`_sampleInFlight` bool field) to `KpiHistoryRecorderActor` so overlapping sample passes can never run concurrently. `HandleSampleTick` now skips (coalesces) a `SampleTick` and logs at debug if a pass is already in flight; otherwise it raises the guard before launching the off-thread `RunSamplePass`. The `SampleComplete` receive handler lowers the guard (it fires on both success and fault paths via the PipeTo projection). XML doc comments were updated accordingly. Tests: a new deterministic regression test (`OverlappingTick_WhileFirstPassInFlight_DoesNotStartSecondPass`) uses a gated repository to prove the second tick is skipped and the guard correctly resets; the pre-existing recovery test was hardened to re-send the tick per poll to avoid racing the asynchronous guard reset.
|
||||
|
||||
**Verdict:** The change is sound, minimal, and regression-free. It faithfully mirrors the already-shipped `NotificationOutboxActor` dispatch in-flight-guard pattern (skip-if-busy, raise-before-launch, lower-on-PipeTo-completion). The guard field is read and written only on the actor thread, so there is no thread-safety hazard; it cannot wedge permanently because `RunSamplePass` never throws and both PipeTo success and failure projections emit `SampleComplete`. The skip-on-overlap behaviour is consistent with the design doc, which describes best-effort per-tick sampling with no strict "a sample must land every interval" guarantee. The new behaviour is covered by a deterministic regression test, and all 4 actor tests pass. No new issues found.
|
||||
|
||||
| # | Category | Examined | Notes |
|
||||
|---|----------|----------|-------|
|
||||
| 1 | Correctness & logic bugs | ☑ | Guard raised before launch, lowered on both success+fault PipeTo paths; cannot wedge (RunSamplePass never throws). 1:1 raise/lower pairing — no double-lower. No issues found. |
|
||||
| 2 | Akka.NET conventions | ☑ | Off-thread work via PipeTo to Self; guard mutated only on the actor thread in the SampleComplete handler. Matches the documented NotificationOutboxActor pattern. No issues found. |
|
||||
| 3 | Concurrency & thread safety | ☑ | _sampleInFlight is touched only on the actor thread (HandleSampleTick + SampleComplete receive); no shared mutable state or captured this/sender in the off-thread pass. No issues found. |
|
||||
| 4 | Error handling & resilience | ☑ | Faulted pass still produces SampleComplete (belt-and-braces failure projection), so the guard always clears; best-effort observability contract preserved. No issues found. |
|
||||
| 5 | Security | ☑ | No new I/O, no secrets, no user input, no injection surface introduced. Debug-level skip log carries no sensitive data. No issues found. |
|
||||
| 6 | Performance & resource management | ☑ | The guard's purpose is precisely to avoid load amplification on a slow/recovering DB by preventing overlapping passes. No new allocations or leaks; field is reset on restart. No issues found. |
|
||||
| 7 | Design-document adherence | ☑ | Component-KpiHistory.md describes best-effort per-tick sampling with no strict per-interval landing guarantee; coalescing overlaps is consistent and the doc already says the recorder mirrors NotificationOutboxActor. No drift. |
|
||||
| 8 | Code organization & conventions | ☑ | Single new private bool field with thorough XML doc; inline comments accurate. Consistent with the sibling actor's naming/structure. No issues found. |
|
||||
| 9 | Testing coverage | ☑ | New deterministic gated-repository regression test pins one-pass-per-tick and guard reset; existing recovery test hardened against the async-reset race. All 4 tests pass. Coverage is adequate for the delta. |
|
||||
| 10 | Documentation & comments | ☑ | Field, handler, and SampleComplete XML docs updated to explain the guard, the enqueue-not-coalesce timer rationale, and the lower-on-fault behaviour. Accurate and clear. No issues found. |
|
||||
|
||||
_No new findings — the changes in this module are clean._
|
||||
|
||||
Reference in New Issue
Block a user