Seed relay: nodes get their headers through the seed API
The seed API keeps a pool of NNTP connections (SEED_NNTP_CONNECTIONS) and serves GET /api/v1/seed/ranges/:id/chunk?from=&to= for leased ranges: the gzip stream the news server sent, passed on unopened. seed:node fetches that way by default (SEED_FETCH=relay), so a node needs only a token and SEED_CONNECTIONS; SEED_FETCH=direct keeps its own NNTP connections. All fetching then comes from the indexer's IP (the account allows two). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3d5cfb2527
commit
41859636d3
13 files changed
+289
-33
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import type { HttpContext } from '@adonisjs/core/http'
|
||||
import SeedOrchestrator, { LeaseLost } from '#services/SeedOrchestrator'
|
||||
import SeedFetchPool from '#services/SeedFetchPool'
|
||||
import type { SeedBatch } from '#lib/seed/wire'
|
||||
|
||||
/**
|
||||
@@ -31,6 +32,27 @@ export default class SeedController {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/v1/seed/ranges/:id/chunk?from=&to= → the overviews of those
|
||||
* articles as a zlib/gzip stream (relay nodes fetch through the indexer).
|
||||
*/
|
||||
async chunk({ seedNode, params, request, response }: HttpContext) {
|
||||
if (SeedFetchPool.size === 0) return response.serviceUnavailable({ error: 'Relay is off (SEED_NNTP_CONNECTIONS=0); fetch directly' })
|
||||
const from = Number(request.input('from'))
|
||||
const to = Number(request.input('to'))
|
||||
if (!Number.isSafeInteger(from) || !Number.isSafeInteger(to)) return response.badRequest({ error: 'Expected ?from=&to=' })
|
||||
return this.leased(response, async () => {
|
||||
try {
|
||||
const raw = await SeedOrchestrator.chunk(seedNode.id, Number(params.id), from, to)
|
||||
response.header('content-type', 'application/octet-stream')
|
||||
return response.send(raw)
|
||||
} catch (error) {
|
||||
if (error instanceof RangeError) return response.badRequest({ error: error.message })
|
||||
throw error
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** POST /api/v1/seed/ranges/:id/done */
|
||||
async done({ seedNode, params, response }: HttpContext) {
|
||||
return this.leased(response, async () => {
|
||||
|
||||
Reference in new issue
Block a user