refactor(diagnostics): split the flap window and episode rule apart
android / Build + lint + test (push) Successful in 4m8s
android / Build + lint + test (push) Successful in 4m8s
detekt ReturnCount. Extracting the pruning and the is-this-an-episode predicate reads better than suppressing it, and the cooldown rule now has a name and a docstring of its own.
This commit is contained in:
+20
-10
@@ -33,20 +33,30 @@ class TransportFlapDetector(
|
||||
*/
|
||||
fun onChange(observation: TransportObservation): List<TransportObservation>? {
|
||||
recent.addLast(observation)
|
||||
while (recent.isNotEmpty() &&
|
||||
observation.atElapsedMs - recent.first().atElapsedMs > windowMs
|
||||
) {
|
||||
recent.removeFirst()
|
||||
}
|
||||
if (recent.size < minChanges) return null
|
||||
// One episode, one summary. A sustained fault would otherwise emit a
|
||||
// summary per reading and bury the per-change events underneath them.
|
||||
val since = lastSummaryAtMs
|
||||
if (since != null && observation.atElapsedMs - since < summaryCooldownMs) return null
|
||||
dropReadingsOlderThan(observation.atElapsedMs)
|
||||
if (!isEpisode(observation.atElapsedMs)) return null
|
||||
lastSummaryAtMs = observation.atElapsedMs
|
||||
return recent.toList()
|
||||
}
|
||||
|
||||
private fun dropReadingsOlderThan(nowMs: Long) {
|
||||
while (recent.isNotEmpty() && nowMs - recent.first().atElapsedMs > windowMs) {
|
||||
recent.removeFirst()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enough changes packed together, and far enough from the last thing we
|
||||
* wrote down. The cooldown is what keeps one episode to one summary: a
|
||||
* sustained fault produces a change every poll, and a summary per reading
|
||||
* would bury the per-change events underneath them.
|
||||
*/
|
||||
private fun isEpisode(nowMs: Long): Boolean {
|
||||
val since = lastSummaryAtMs
|
||||
val cooled = since == null || nowMs - since >= summaryCooldownMs
|
||||
return recent.size >= minChanges && cooled
|
||||
}
|
||||
|
||||
/** Forget everything — call when the route changes or casting ends. */
|
||||
fun reset() {
|
||||
recent.clear()
|
||||
|
||||
Reference in New Issue
Block a user