Rebuild: completeness as indexed, file totals from any counter, pausable tails, progress by articles
Test and deploy / test (push) Successful in 21s
Test and deploy / deploy (push) Skipped

- releases.complete is computed with every batch (files >= the
  counter's total) instead of only when a release settles after 6 quiet
  hours: the 'complete' filter matched nothing in a fresh catalog.
- A release's file total comes from any counter form (counterTotal:
  '(01/10)', 'File 27 of 132', …), not only [i/M]; the post rule's key
  keeps the [i/M] total, so keys are unchanged. Both implementations.
- groups.tail: a group's live tail can be paused (its history and owner
  priority stay), e.g. to let other groups' history go first.
- Stats: history by articles, and the current pass (history ranges
  before those deferred 2000 priorities behind) as its own figure; the
  header showed 0.1% of ranges counting 145k deferred ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Daan MeijerandClaude Opus 5.5 committed 2026-10-09 13:06:03 +02:00
1 parent 7b7175c229
commit d0f3497ec9
8 files changed
+57 -17

No files matched your search

+6 -2
View File
@@ -164,13 +164,17 @@ async function loadStats() {
const readable = stats.releases ? Math.round((100 * stats.readableReleases) / stats.releases) : 0
// Estimated from Postgres statistics and a sample.
const about = stats.approximate ? '≈ ' : ''
const history = stats.ranges.history ? (100 * stats.ranges.historyDone) / stats.ranges.history : 0
const percent = ({ done, total }) => {
const p = total ? (100 * done) / total : 0
return `${p < 10 ? p.toFixed(1) : Math.round(p)}%`
}
const items = [
['Releases', about + number.format(stats.releases)],
['Readable', `${about}${readable}%`],
['Files', about + number.format(stats.files)],
['Size', about + formatSize(stats.size)],
['History', `${history < 10 ? history.toFixed(1) : Math.round(history)}%`],
['History', percent(stats.history)],
...(stats.pass.total < stats.history.total ? [['Pass', percent(stats.pass)]] : []),
['Live', formatAge(stats.tailIndexedAt) || '–'],
]
$('#stats').replaceChildren(...items.map(([dt, dd]) => el('div', {}, el('dt', { text: dt }), el('dd', { text: dd }))))