The coordinator (38) and the prober (8) had a fixed split; with history paused the coordinator's stood idle while the prober's were its limit. nntp_shares: each process syncs every 15 s (priority, minimum, what it could use, what it has open) and gets what it may open: minimums first, then by priority what each wants, growing only into connections the others closed or gave up. The pool's size and the prober's lanes follow the grant; the coordinator doubles its want while work waits for a connection, else asks for its peak in use and a margin; the prober wants its maximum unless the queue is dry. Claims scale with the lanes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
27 lines
970 B
TypeScript
27 lines
970 B
TypeScript
import { BaseSchema } from '@adonisjs/lucid/schema'
|
|
|
|
/**
|
|
* nntp_shares: the account's connections shared by the processes that read articles (app/services/nntp_shares.ts).
|
|
* Each process's row says what it could use and has open, and what it may open; a row without a heartbeat for a
|
|
* minute is a process gone (its connections closed with it). The split was fixed per process: with history paused
|
|
* the coordinator's 38 stood idle while the prober's 8 were the limit (LOG.md 2026-10-18 (75)).
|
|
*/
|
|
export default class extends BaseSchema {
|
|
async up() {
|
|
this.schema.raw(`
|
|
CREATE TABLE IF NOT EXISTS nntp_shares (
|
|
name text PRIMARY KEY,
|
|
priority integer NOT NULL,
|
|
min integer NOT NULL,
|
|
want integer NOT NULL,
|
|
open integer NOT NULL,
|
|
granted integer NOT NULL,
|
|
heartbeat_at timestamptz NOT NULL DEFAULT now()
|
|
)`)
|
|
}
|
|
|
|
async down() {
|
|
this.schema.raw(`DROP TABLE IF EXISTS nntp_shares`)
|
|
}
|
|
}
|