mirror of
https://github.com/wekan/wekan.git
synced 2026-11-07 11:02:33 -05:00
#6520: the Problems "Status" page showed "Board data-repair — 146/146 boards" running forever (plus a matching "Migration or repair" login warning), and the CPU area showed dozens of "new problems" on an idle server. Board repair stuck at "running": getInProgress() trusted the raw `running` flag. The startup repair DOES write running:false on completion, but its progress callback also fired a NON-awaited running:true write when boardsDone === boardsTotal; being fire-and-forget, that write could land AFTER the awaited completion write and pin the doc at "running, 146/146". A process killed mid-repair leaves running:true too. Both now clear: * the startup progress callback no longer writes the terminal boardsDone === boardsTotal update (the completion write owns the final state), closing the race at the source; * getInProgress() now asks the new pure isStatusActive() instead of reading `running` directly - a doc is "in progress" only while running AND not in a terminal phase (completed/error/done) AND not already finished by count (done >= total) AND updated recently (a running flag with no recent progress write is a crashed run). This also heals docs already stuck on an instance, and fixes the same class of stale flag for the text migration. Because the login "Migration or repair" warning keys off getInProgress(), it clears too. CPU "57 new problems" on an idle server: the count in eventLogProblemAreas counted every unacknowledged row in a stream. The CPU monitor writes one 'detected' row when a high-CPU period starts and several severity:'info' rows ('remediated' when it ends, 'rate-limited' for mitigation, FerretDB governor chatter), so each brief, already-over spike looked like several "new problems". The count now excludes severity:'info' rows (via the new newProblemsSelector) - notices that a problem was handled or cleared are not problems. Rows with no severity are still counted, so nothing unclassified is silently dropped. Both decisions are pure, unit- and negative-tested (statusActive.test.cjs, eventLogProblems.test.cjs), and registered in test:unit:node. Thanks to Alishara and xet7 ! Fixes #6520,
26 lines
1.2 KiB
JavaScript
26 lines
1.2 KiB
JavaScript
'use strict';
|
|
|
|
// Selector for the Admin Panel → Problems "new problems" count of one event
|
|
// stream: events newer than that stream's acknowledgment, EXCLUDING purely
|
|
// informational rows. (#6520)
|
|
//
|
|
// The CPU stream records a 'detected' row (severity medium/high) when a sustained
|
|
// high-CPU period STARTS, and severity:'info' 'remediated' / 'rate-limited' rows
|
|
// when it is mitigated and when it ENDS — plus info rows for the FerretDB
|
|
// governor talking to FerretDB. So each brief, already-over CPU spike wrote
|
|
// several rows, only one of which is a problem. Counting every row made a handful
|
|
// of short spikes look like dozens of "new problems" (the reporter saw "57 new
|
|
// problems" on an idle server).
|
|
//
|
|
// Informational rows are notices that a problem was handled or has cleared, not
|
|
// problems, so they are not counted. Rows with NO severity are still counted: an
|
|
// unclassified event is treated as a possible problem rather than silently
|
|
// dropped (Mongo's `$ne` matches documents where the field is missing).
|
|
function newProblemsSelector(stream, ackAt) {
|
|
const selector = { stream, severity: { $ne: 'info' } };
|
|
if (ackAt) selector.at = { $gt: ackAt };
|
|
return selector;
|
|
}
|
|
|
|
module.exports = { newProblemsSelector };
|