Skip to content

Commit ba1bcb3

Browse files
chriscrosstalkclaude
authored andcommitted
fix: prevent embedding retry storm when Ollama is not installed
When Ollama isn't installed, every ZIM download dispatches embedding jobs that fail and retry 30x with 60s backoff. With many ZIM files downloading in parallel, this exhausts Redis connections with EPIPE/ECONNRESET errors. Two changes: 1. Don't dispatch embedding jobs when Ollama isn't installed (belt) 2. Use BullMQ UnrecoverableError for "not installed" so jobs fail immediately without retrying (suspenders) Closes #351 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ec0d30d commit ba1bcb3

File tree

2 files changed

+23
-12
lines changed

2 files changed

+23
-12
lines changed

admin/app/jobs/embed_file_job.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Job } from 'bullmq'
1+
import { Job, UnrecoverableError } from 'bullmq'
22
import { QueueService } from '#services/queue_service'
33
import { EmbedJobWithProgress } from '../../types/rag.js'
44
import { RagService } from '#services/rag_service'
@@ -42,7 +42,15 @@ export class EmbedFileJob {
4242
const ragService = new RagService(dockerService, ollamaService)
4343

4444
try {
45-
// Check if Ollama and Qdrant services are ready
45+
// Check if Ollama and Qdrant services are installed and ready
46+
// Use UnrecoverableError for "not installed" so BullMQ won't retry —
47+
// retrying 30x when the service doesn't exist just wastes Redis connections
48+
const ollamaUrl = await dockerService.getServiceURL('nomad_ollama')
49+
if (!ollamaUrl) {
50+
logger.warn('[EmbedFileJob] Ollama is not installed. Skipping embedding for: %s', fileName)
51+
throw new UnrecoverableError('Ollama service is not installed. Install AI Assistant to enable file embeddings.')
52+
}
53+
4654
const existingModels = await ollamaService.getModels()
4755
if (!existingModels) {
4856
logger.warn('[EmbedFileJob] Ollama service not ready yet. Will retry...')
@@ -51,8 +59,8 @@ export class EmbedFileJob {
5159

5260
const qdrantUrl = await dockerService.getServiceURL('nomad_qdrant')
5361
if (!qdrantUrl) {
54-
logger.warn('[EmbedFileJob] Qdrant service not ready yet. Will retry...')
55-
throw new Error('Qdrant service not ready yet')
62+
logger.warn('[EmbedFileJob] Qdrant is not installed. Skipping embedding for: %s', fileName)
63+
throw new UnrecoverableError('Qdrant service is not installed. Install AI Assistant to enable file embeddings.')
5664
}
5765

5866
logger.info(`[EmbedFileJob] Services ready. Processing file: ${fileName}`)

admin/app/jobs/run_download_job.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,17 @@ export class RunDownloadJob {
8282
const zimService = new ZimService(dockerService)
8383
await zimService.downloadRemoteSuccessCallback([url], true)
8484

85-
// Dispatch an embedding job for the downloaded ZIM file
86-
try {
87-
await EmbedFileJob.dispatch({
88-
fileName: url.split('/').pop() || '',
89-
filePath: filepath,
90-
})
91-
} catch (error) {
92-
console.error(`[RunDownloadJob] Error dispatching EmbedFileJob for URL ${url}:`, error)
85+
// Only dispatch embedding job if AI Assistant (Ollama) is installed
86+
const ollamaUrl = await dockerService.getServiceURL('nomad_ollama')
87+
if (ollamaUrl) {
88+
try {
89+
await EmbedFileJob.dispatch({
90+
fileName: url.split('/').pop() || '',
91+
filePath: filepath,
92+
})
93+
} catch (error) {
94+
console.error(`[RunDownloadJob] Error dispatching EmbedFileJob for URL ${url}:`, error)
95+
}
9396
}
9497
} else if (filetype === 'map') {
9598
const mapsService = new MapService()

0 commit comments

Comments
 (0)