Files
LibreMail/config/detekt
JMR-dev 5c564ebeda perf(sync): pace backfill with an inter-slice cooldown and per-run cap
Backfill chained bounded slices back-to-back with no gap, and on a large
mailbox `moreWork` never clears, so a single BackfillWorker run paged
flat-out for its whole session and kept the account's IMAP connection
saturated -- the background load that starves interactive message-opens
(#355) and worsens provider throttling (#360).

Add BackfillPacer, a small in-process primitive that bounds one run:
- inter-slice cooldown: a fixed 30s idle between chained slices;
- per-run slice cap: at most 4 slices per run, then defer to the 30-min
  periodic cadence so one run cannot monopolise the account.

Composes with the two sibling mechanisms instead of duplicating them:
- #355 (InteractiveImapGate): the cooldown is SKIPPED while an interactive
  fetch is active -- the next slice already parks at its per-page yield
  point, so a fixed delay on top would only double the idle (no pathological
  double-delay);
- #360 (AccountThrottleGate): a slice whose only outstanding work is a
  throttled account returns moreWork=false, so the loop stops and no
  cooldown is spent spinning on a backed-off provider.

The cooldown is a cancellable delay and the loop rechecks !isStopped before
each slice, so a WorkManager stop / teardown ends a run promptly. All
breadcrumbs are PII-free (durations/counts only).

Tests: BackfillPacerTest (JVM, virtual time) covers cooldown timing, cap,
cancellation, and the #355/#360 composition; BackfillWorkerTest asserts the
worker caps a flat-out run; BackfillPacerInstrumentedTest proves forward
progress across paced runs, the interactive skip, and prompt cancellation on
the real Android runtime.

Closes #356
2026-07-08 16:57:15 -05:00
..