A missing first article is an inspection result, not a failure
Eweka answers 'no such article' after ~450 ms; a quarter of inspection requests were for missing articles and each failed job was retried up to three times. Files get content_type 'missing' instead; homelab also records it from failure reports of nodes not rebuilt yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bef68075be
commit
61192690a7
6 files changed
+57
-5
No files matched your search
@@ -156,6 +156,11 @@ class ContentService {
|
||||
const binary = await db.from('binaries').where('file_id', task.fileId).first()
|
||||
const { contentType } = probe
|
||||
await db.from('files').where('id', file.id).update({ content_type: contentType })
|
||||
if (contentType === 'missing') {
|
||||
// Nothing to read; the binary needn't wait for inspection any more.
|
||||
if (binary) await db.from('binaries').where('id', binary.id).update({ awaiting_inspection: null })
|
||||
return result
|
||||
}
|
||||
|
||||
// Fingerprint, so par2 sets (now or later) can name this file exactly.
|
||||
if (binary) {
|
||||
@@ -268,6 +273,7 @@ export function describeContent(filename: string, content: ContentResult | null)
|
||||
)
|
||||
}
|
||||
if (content?.named) lines.push(`"${filename}" got its real name from par2.`)
|
||||
if (content?.contentType === 'missing') lines.push(`"${filename}": the server no longer has its first article.`)
|
||||
if (content?.contentType === 'nzbe') lines.push(`"${filename}" is an encrypted NZB container.`)
|
||||
if (content?.contentType === 'rclone') lines.push(`"${filename}" is rclone-encrypted.`)
|
||||
if (content?.yencName) lines.push(`"${filename}" is "${content.yencName}" (yEnc name).`)
|
||||
|
||||
@@ -7,7 +7,7 @@ import QueueService from '#services/QueueService'
|
||||
import NntpService from '#services/NntpService'
|
||||
import ContentService, { describeContent } from '#services/ContentService'
|
||||
import ArchiveWalkService from '#services/ArchiveWalkService'
|
||||
import type { ContentTask, InspectProbe, InspectTask, WalkProbe } from '#lib/content/probe'
|
||||
import { isMissingArticle, type ContentTask, type InspectProbe, type InspectTask, type WalkProbe } from '#lib/content/probe'
|
||||
|
||||
/** Inspection first; archive walks (D40) only when it has nothing waiting. */
|
||||
const QUEUES = ['collection-queue', 'archive-walk-queue'] as const
|
||||
@@ -90,6 +90,11 @@ class RemoteContentService {
|
||||
/** The probe failed on the node (e.g. a missing article): retried like a local failure. */
|
||||
async fail(queue: QueueName, jobId: string, token: string, error: string) {
|
||||
const job = await this.job(queue, jobId)
|
||||
// A missing first article from a node that predates the probe's own handling: a result,
|
||||
// not something to retry (each try costs Eweka ~450 ms; LOG.md 2026-10-06 (14)).
|
||||
if (queue === 'collection-queue' && job.data.remote && isMissingArticle(error)) {
|
||||
return this.finish(queue, jobId, token, { size: 0, contentType: 'missing', md5_16k: null, yencName: '' })
|
||||
}
|
||||
await this.locked(() => job.moveToFailed(new Error(`node: ${error}`), token, false))
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user