Rebuild: coordinator (planner, NNTP pool, spool, prefetcher, leases, rule sets), node API and the edge:node worker
- groups:add / ranges:plan / nodes:create / coordinator:run commands - the node API: lease, the range's chunks as one framed stream from the spool, batches, heartbeat, finish, release (node guard, token per node) - edge:node: needs COORDINATOR_URL and NODE_TOKEN only (placeholders for the rest), posts a batch every 10 chunks, gives its range back on SIGTERM - releases are gathered per batch: 1.04 chunk rows per release at 10 chunks per batch (1.35 when built per XOVER chunk) - partitions are checked per batch instead of remembered Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
20910647fa
commit
d5f168d8d2
36 files changed
+1193
-14
No files matched your search
+13
-1
@@ -37,6 +37,9 @@ export default class EdgeBench extends BaseCommand {
|
||||
@flags.number({ description: 'Articles per XOVER', default: 50_000 })
|
||||
declare chunk: number
|
||||
|
||||
@flags.number({ description: 'Chunks per batch (results taken every N chunks)', default: 10 })
|
||||
declare batchChunks: number
|
||||
|
||||
@flags.number({ description: 'Chunks without a new part before an open file is given up', default: 5 })
|
||||
declare idle: number
|
||||
|
||||
@@ -87,6 +90,8 @@ export default class EdgeBench extends BaseCommand {
|
||||
let peakRss = 0
|
||||
const out = { headers: 0, releases: 0, files: 0, segments: 0, payload: 0, candidates: 0, fragments: 0, samples: 0 }
|
||||
const counts = new Map<string, number>()
|
||||
const keys = new Set<string>()
|
||||
let batches = 0
|
||||
const cpuStart = process.cpuUsage()
|
||||
const wall = Date.now()
|
||||
for (const file of files) {
|
||||
@@ -102,12 +107,18 @@ export default class EdgeBench extends BaseCommand {
|
||||
at = performance.now()
|
||||
const next = Number(file.split('-')[2].replace('.gz', '')) + 1
|
||||
indexer.add(overviews, next)
|
||||
if (file === files.at(-1)) indexer.finish()
|
||||
const last = file === files.at(-1)
|
||||
if (last) indexer.finish()
|
||||
t.index += performance.now() - at
|
||||
if (!last && (files.indexOf(file) + 1) % this.batchChunks !== 0) continue
|
||||
at = performance.now()
|
||||
const batch = indexer.take()
|
||||
t.index += performance.now() - at
|
||||
out.headers += batch.headers
|
||||
out.releases += batch.releases.length
|
||||
batches++
|
||||
for (const r of batch.releases) {
|
||||
keys.add(r.key)
|
||||
out.files += r.files
|
||||
out.segments += r.segments
|
||||
out.payload += r.payload.length
|
||||
@@ -124,6 +135,7 @@ export default class EdgeBench extends BaseCommand {
|
||||
this.logger.info(`${group} ${start}–${end}: ${files.length} chunks, ${(compressed / 1e6).toFixed(0)} MB compressed, ${(text / 1e6).toFixed(0)} MB text`)
|
||||
this.logger.info(`${out.headers.toLocaleString('en')} headers in ${(total / 1000).toFixed(1)} s (${Math.round(out.headers / (total / 1000)).toLocaleString('en')}/s on one core; CPU ${cpuS.toFixed(1)} s, wall ${((Date.now() - wall) / 1000).toFixed(1)} s)`)
|
||||
this.logger.info(` inflate ${(t.inflate / 1000).toFixed(1)} s, parse ${(t.parse / 1000).toFixed(1)} s, index ${(t.index / 1000).toFixed(1)} s; peak RSS ${(peakRss / 1e6).toFixed(0)} MB`)
|
||||
this.logger.info(` ${batches} batches of ${this.batchChunks} chunks: ${out.releases} release chunks for ${keys.size} releases (${(out.releases / Math.max(1, keys.size)).toFixed(2)} chunks per release)`)
|
||||
this.logger.info(` kept: ${out.releases} release chunks, ${out.files} files, ${out.segments} segments, payload ${(out.payload / 1e6).toFixed(1)} MB (${(out.payload / Math.max(1, out.segments)).toFixed(1)} B/segment); ${out.candidates} candidates, ${out.fragments} fragments, ${out.samples} samples`)
|
||||
for (const [k, v] of [...counts].sort((a, b) => b[1] - a[1]).slice(0, 8)) this.logger.info(` dropped ${k}: ${v.toLocaleString('en')} articles`)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user