forked from EduCraft/curriculum-project-hub
fix(hub): raise Docmind OSS upload timeout past httpx 3s default
SubmitDocParserJobAdvance uploads PDFs to Aliyun OSS via tea/httpx, which defaults readTimeout to 3000ms when RuntimeOptions is empty. Multi-MB teacher PDFs on para silo failed with ReadTimeout(3000) before the job could start. Set connectTimeout=15s and readTimeout=5m.
This commit is contained in:
@@ -26,7 +26,11 @@ const client = new DocmindClient.default({
|
|||||||
} as never);
|
} as never);
|
||||||
|
|
||||||
const fileStream = createReadStream(pdfPath);
|
const fileStream = createReadStream(pdfPath);
|
||||||
const runtime = new RuntimeOptions({});
|
const runtime = new RuntimeOptions({
|
||||||
|
connectTimeout: 15_000,
|
||||||
|
// httpx defaults to 3000ms; OSS upload of multi-MB PDFs needs far more.
|
||||||
|
readTimeout: 5 * 60_000,
|
||||||
|
});
|
||||||
|
|
||||||
console.log("Submitting job...");
|
console.log("Submitting job...");
|
||||||
const submitResp = await client.submitDocParserJobAdvance(
|
const submitResp = await client.submitDocParserJobAdvance(
|
||||||
|
|||||||
@@ -62,6 +62,23 @@ export class DocmindClientError extends Error {
|
|||||||
const COST_PER_PAGE_USD = 0.0056;
|
const COST_PER_PAGE_USD = 0.0056;
|
||||||
const POLL_INTERVAL_MS = 10_000;
|
const POLL_INTERVAL_MS = 10_000;
|
||||||
const POLL_TIMEOUT_MS = 5 * 60_000;
|
const POLL_TIMEOUT_MS = 5 * 60_000;
|
||||||
|
/**
|
||||||
|
* httpx (tea transport) defaults read/connect timeout to 3000ms when unset.
|
||||||
|
* SubmitDocParserJobAdvance uploads the PDF to OSS; multi-MB files routinely
|
||||||
|
* exceed 3s on the silo host (production: ReadTimeout(3000) on
|
||||||
|
* docmind-api-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com).
|
||||||
|
*/
|
||||||
|
export const DOCMIND_CONNECT_TIMEOUT_MS = 15_000;
|
||||||
|
/** Allow slow / large PDF OSS uploads up to the same bound as job polling. */
|
||||||
|
export const DOCMIND_READ_TIMEOUT_MS = POLL_TIMEOUT_MS;
|
||||||
|
|
||||||
|
/** RuntimeOptions for Docmind SDK calls that may upload or wait on the wire. */
|
||||||
|
export function createDocmindRuntimeOptions(): RuntimeOptions {
|
||||||
|
return new RuntimeOptions({
|
||||||
|
connectTimeout: DOCMIND_CONNECT_TIMEOUT_MS,
|
||||||
|
readTimeout: DOCMIND_READ_TIMEOUT_MS,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
type DocmindConfig = ConstructorParameters<typeof $DocmindClient.default>[0];
|
type DocmindConfig = ConstructorParameters<typeof $DocmindClient.default>[0];
|
||||||
|
|
||||||
@@ -90,7 +107,7 @@ export class AliyunDocmindClient implements CapabilityProviderClient {
|
|||||||
outputFormat: ["markdown"],
|
outputFormat: ["markdown"],
|
||||||
formulaEnhancement: true,
|
formulaEnhancement: true,
|
||||||
});
|
});
|
||||||
const runtime = new RuntimeOptions({});
|
const runtime = createDocmindRuntimeOptions();
|
||||||
let submitResponse;
|
let submitResponse;
|
||||||
try {
|
try {
|
||||||
submitResponse = await client.submitDocParserJobAdvance(advanceRequest, runtime);
|
submitResponse = await client.submitDocParserJobAdvance(advanceRequest, runtime);
|
||||||
|
|||||||
@@ -1,8 +1,24 @@
|
|||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { tmpdir } from "node:os";
|
import { tmpdir } from "node:os";
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import { AliyunDocmindClient, DocmindClientError } from "../../src/capability/docmindClient.js";
|
import {
|
||||||
|
AliyunDocmindClient,
|
||||||
|
DocmindClientError,
|
||||||
|
DOCMIND_CONNECT_TIMEOUT_MS,
|
||||||
|
DOCMIND_READ_TIMEOUT_MS,
|
||||||
|
createDocmindRuntimeOptions,
|
||||||
|
} from "../../src/capability/docmindClient.js";
|
||||||
|
|
||||||
|
describe("createDocmindRuntimeOptions", () => {
|
||||||
|
it("overrides httpx's 3s default so PDF OSS uploads can complete", () => {
|
||||||
|
const runtime = createDocmindRuntimeOptions();
|
||||||
|
// Production failure: ReadTimeout(3000) on docmind OSS upload.
|
||||||
|
expect(DOCMIND_CONNECT_TIMEOUT_MS).toBeGreaterThan(3_000);
|
||||||
|
expect(DOCMIND_READ_TIMEOUT_MS).toBeGreaterThan(3_000);
|
||||||
|
expect(runtime.connectTimeout).toBe(DOCMIND_CONNECT_TIMEOUT_MS);
|
||||||
|
expect(runtime.readTimeout).toBe(DOCMIND_READ_TIMEOUT_MS);
|
||||||
|
});
|
||||||
|
});
|
||||||
describe("AliyunDocmindClient local file open", () => {
|
describe("AliyunDocmindClient local file open", () => {
|
||||||
it("rejects a missing input file without crashing the process", async () => {
|
it("rejects a missing input file without crashing the process", async () => {
|
||||||
const client = new AliyunDocmindClient();
|
const client = new AliyunDocmindClient();
|
||||||
|
|||||||
Reference in New Issue
Block a user