Fix synthesis fetch failures from Node's default 5-minute HTTP timeout
Nothing published for hours, every cluster failing with "fetch failed". Ollama's own log showed the real story: requests being cancelled at exactly 5m0s with a 500, not a model or server error. Node's global fetch (undici) defaults to a 5-minute headers/body timeout, and CPU-only prompt processing on the reference hardware (i5-6600K, no GPU, ~17 tok/s) legitimately takes longer than that once prompts carry full article bodies instead of short blurbs (the previous fix in this same line of work) — every generate() call past a few thousand tokens got killed client-side before Ollama could finish. OllamaProvider.generate() now passes a dedicated undici Agent with headersTimeout/bodyTimeout disabled as the fetch dispatcher, so the request runs as long as it actually needs to. Verified the failure mode and the fix directly: a short-timeout dispatcher against a deliberately slow server reproduces the exact same "fetch failed" / UND_ERR_HEADERS_TIMEOUT error seen in production, and a zero-timeout dispatcher completes the same slow request without issue. undici was already a transitive dependency (via jsdom); added directly since ollama-provider.ts now imports from it.
This commit is contained in:
Generated
+2
-1
@@ -15,7 +15,8 @@
|
||||
"fastify": "^5.10.0",
|
||||
"jsdom": "^29.1.1",
|
||||
"rss-parser": "^3.13.0",
|
||||
"telegram": "^2.26.22"
|
||||
"telegram": "^2.26.22",
|
||||
"undici": "^7.28.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsdom": "^28.0.3",
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"fastify": "^5.10.0",
|
||||
"jsdom": "^29.1.1",
|
||||
"rss-parser": "^3.13.0",
|
||||
"telegram": "^2.26.22"
|
||||
"telegram": "^2.26.22",
|
||||
"undici": "^7.28.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jsdom": "^28.0.3",
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
import { Agent } from 'undici';
|
||||
import type { InferenceProvider } from './provider.js';
|
||||
|
||||
/**
|
||||
* Node's global fetch (undici) defaults to a 5-minute headers/body timeout — fine for
|
||||
* ordinary HTTP calls, but a real problem for /api/generate on CPU-only inference: a
|
||||
* near-full context window can legitimately take longer than that just for prompt
|
||||
* processing on the reference hardware (i5-6600K, no GPU, ~17 tokens/sec). Once
|
||||
* synthesis prompts started carrying full article bodies instead of short blurbs, every
|
||||
* generate() call past a few thousand tokens got killed at exactly 5m0s — visible in
|
||||
* Ollama's own log as the request being cancelled, not a genuine model/server error —
|
||||
* so no cluster could ever finish synthesizing. No timeout at all here; Ollama's own
|
||||
* process is the natural backstop, not a clock tuned for hardware this doesn't run on.
|
||||
*/
|
||||
const noTimeoutDispatcher = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
|
||||
|
||||
/**
|
||||
* Default context window / max-generation length requested from Ollama when a caller
|
||||
* doesn't specify its own. Ollama otherwise falls back to whatever the model's
|
||||
@@ -51,8 +65,11 @@ export class OllamaProvider implements InferenceProvider {
|
||||
num_ctx: opts.numCtx ?? DEFAULT_NUM_CTX,
|
||||
num_predict: opts.numPredict ?? DEFAULT_NUM_PREDICT
|
||||
}
|
||||
})
|
||||
});
|
||||
}),
|
||||
// Not in the ambient RequestInit type this project resolves to, but Node's global
|
||||
// fetch (built on undici) honors it at runtime — see noTimeoutDispatcher above.
|
||||
dispatcher: noTimeoutDispatcher
|
||||
} as RequestInit);
|
||||
if (!res.ok) throw new Error(`Ollama generate failed: ${res.status} ${await res.text()}`);
|
||||
const data = (await res.json()) as { response: string };
|
||||
return data.response;
|
||||
|
||||
Reference in New Issue
Block a user