The prober stores, per probed article that starts a file, the MD5 of its
first 16 KiB (file_hashes), and per par2 body the set's whole file list
(par2_files, par2_sets): FileDesc holds the same hash per file, whatever
the file was renamed to. releases:merge (the merger service, no NNTP)
merges every minute the releases of one group, posted within 48 hours of
a release holding the set's par2, whose files the set describes, into the
one with the most files: chunks, probe candidates, inspections, hashes and
counts move; the par2's shared name when none was readable; release_merges
keeps what went where. Obfuscated uploads whose files were each a release
of their own ("[9/20] - "14f5999a…"", hep: 13,232) become one.
Also: corpus_sweep.py counts the marked ranges without psql's command tag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import { BaseCommand, flags } from '@adonisjs/core/ace'
|
|
import type { CommandOptions } from '@adonisjs/core/types/ace'
|
|
import { Par2Merger } from '#services/par2_merger'
|
|
|
|
/** The par2 merge (REBUILD.md, phase 2): releases whose files one par2 set describes become one. */
|
|
export default class ReleasesMerge extends BaseCommand {
|
|
static commandName = 'releases:merge'
|
|
static description = 'Merges the releases whose files one par2 set describes (what the prober read), every minute'
|
|
static options: CommandOptions = { startApp: true, staysAlive: true }
|
|
|
|
@flags.boolean({ description: 'One round over every set, then exit' })
|
|
declare once: boolean
|
|
|
|
async run() {
|
|
const merger = new Par2Merger()
|
|
if (this.once) {
|
|
const round = await merger.round()
|
|
this.logger.info(`${round.sets} sets checked: ${round.releases} releases merged into ${round.merges}.`)
|
|
await this.terminate()
|
|
return
|
|
}
|
|
let done: () => void
|
|
const finished = new Promise<void>((resolve) => (done = resolve))
|
|
this.app.terminating(async () => {
|
|
merger.stop()
|
|
await finished
|
|
})
|
|
await merger.run()
|
|
this.logger.info('Merger stopped.')
|
|
done!()
|
|
await this.terminate()
|
|
}
|
|
}
|