fix(ops): wonder site config gains required audit DB path; explicit LocalDb read-page cap; rate-limited observer drop logging
F1: deploy/wonder-app-vd03/appsettings.Site.json (outside git, WP1.2's StartupValidator gate applies live on next install/upgrade) was missing the now-required AuditLog:SiteWriter:DatabasePath, added pointing at E:\ApiInstall\ScadaBridge\site\data\auditlog.db alongside the file's existing SiteEventLog/LocalDb paths; scanned deploy/ for other Site-role appsettings with the same gap (none) and confirmed wonder does not pin LocalDb:Replication:MaxBatchSize (F2 doesn't apply there). F2: re-pin an explicit LocalDb:Replication:MaxBatchSize=64 on docker/site-a node-a and node-b. MaxBatchBytes (2 MB default) only bounds the wire message via the per-message split in SyncSession.PumpLoopAsync; MaxBatchSize separately bounds the DB read page in OplogStore.ReadBatchAboveAsync/SnapshotStreamer, which materializes the whole page into memory before that split runs. Left at the 500 default, a reconnect drain of worst-case config_json rows could transiently allocate ~35 MB per read even though every wire message stayed within budget. Updated the CLAUDE.md LocalDb bullet to stop implying the row cap is fully redundant with the byte budget (topology-guide.md has no matching claim). F3: StoreAndForwardService's observer-queue onDropped callback logged a Warning per dropped item, flooding logs at sweep rate for a stuck observer with a large queue. LogObserverQueueDrop now logs once immediately on the first drop of an episode, then throttles to at most one rollup Warning per minute while drops continue, reporting the count dropped since the last log; the cumulative ObserverQueueDroppedCount counter is unaffected. Extended StoreAndForwardServiceTests with ObserverQueue_ManyDropsInOneEpisode_LogsExactlyOneWarning, which floods the bounded queue and pins exactly one drop-related Warning log for the episode via a small CapturingLogger test double. dotnet build ZB.MOM.WW.ScadaBridge.slnx: 0 warnings, 0 errors. dotnet test StoreAndForward.Tests: 134/134 passed. dotnet test Host.Tests: 490/490 passed.
This commit is contained in:
@@ -104,14 +104,18 @@
|
||||
"ApiKey": "dev-site-a-localdb-sync-key",
|
||||
// ---- Phase 2 sizing, from the Task 1 rig soak (not from the defaults) ----
|
||||
//
|
||||
// The MaxBatchSize = 16 pin is RETIRED as of LocalDb 0.2.0 (arch-review WP3.3).
|
||||
// It existed only as a hand-computed proxy for a byte budget: batching was
|
||||
// row-count-only, and 70 KB of production config_json x the 500 default is
|
||||
// ~35 MB against gRPC's 4 MB receive limit. The library now bounds a batch by
|
||||
// MaxBatchBytes (default 2 MB of summed serialized size), with the row count
|
||||
// demoted to a secondary cap, so both are left at their defaults here - a
|
||||
// deliberately unset MaxBatchBytes is the 2 MB default, and the widest row no
|
||||
// longer has to be guessed at deploy time.
|
||||
// The old MaxBatchSize = 16 pin (a hand-computed byte-budget proxy) was retired
|
||||
// when LocalDb 0.2.0 added MaxBatchBytes (arch-review WP3.3) - but MaxBatchSize
|
||||
// is NOT purely redundant with it. MaxBatchBytes bounds the WIRE message via a
|
||||
// per-message split in SyncSession.PumpLoopAsync; MaxBatchSize separately bounds
|
||||
// the DB READ page in OplogStore.ReadBatchAboveAsync / SnapshotStreamer, which
|
||||
// materializes the whole page into memory BEFORE the byte-budget split runs. At
|
||||
// the unset 500 default, a reconnect drain of 70 KB worst-case config_json rows
|
||||
// can transiently allocate ~35 MB per read even though every wire message stays
|
||||
// under the 2 MB MaxBatchBytes default (arch-review adversarial finding F2). Pin
|
||||
// it explicitly here to bound that transient allocation; MaxBatchBytes is left
|
||||
// unset (its 2 MB default) to bound the wire message.
|
||||
"MaxBatchSize": 64,
|
||||
//
|
||||
// Backlog caps bound the oplog while the peer is offline. Exceeding them is
|
||||
// NOT data loss: the oplog is pruned to the ceiling and needs_snapshot is set,
|
||||
|
||||
Reference in New Issue
Block a user