You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`POST /api/azure/classifier/documents` accepts multipart training-document uploads for classifiers.
4
+
5
+
## File size limit
6
+
7
+
Each uploaded file may be up to **100 MB**, matching the dataset version upload endpoint in `apps/backend-services/src/benchmark/dataset.controller.ts`.
8
+
9
+
The route configures multer via `FilesInterceptor` with `limits.fileSize: 100 * 1024 * 1024`. Files larger than 100 MB receive **HTTP 413 Payload Too Large** (via `MulterExceptionFilter` for multer rejections and an explicit controller check as a safeguard).
10
+
11
+
## Load testing context
12
+
13
+
Load testing previously reported HTTP 500 for uploads above ~64 KB because the classifier route used `FilesInterceptor("files")` without an explicit limit. The `blob-storage` k6 scenario (256 KB blobs) showed a **20.6 %** failure rate until this limit was aligned with the dataset upload endpoint.
Copy file name to clipboardExpand all lines: docs-md/openshift-deployment/MANUAL_LOAD_TEST_INSTANCE.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -159,7 +159,7 @@ The patch lasts for the life of the ConfigMap; re-running **`oc-deploy-instance.
159
159
The matrix runs in [`tools/load-testing/test-matrix.csv`](../../tools/load-testing/test-matrix.csv) surfaced two reproducible issues that are not specific to the load-test instance — they are **product limits** that any operator will hit. They are documented here so the next person running the suite knows what they are seeing and is not blocked by them.
160
160
161
161
1.**Backend pod becomes unavailable under concurrent large uploads.** Running `payload-sizes` at **`large` (5 MB raw PDF) × 5 VUs** drove the **`backend-services`** pod into a restart that returned **`HTTP 502`** (router→dead pod) followed by **`HTTP 503`** (router→no healthy upstream) for ~30–60 s. **`smoke`** and **`datasets`** were both unreachable during the window. **`large × 1 VU`** runs cleanly. The most likely cause is per-request memory pressure from `JSON.parse` + `Buffer.from(b64,'base64')` + `pdf-lib` normalization at the same time, exceeding the pod's `memory.limit`. Confirm with **`oc describe pod <instance>-backend-services-<id>`** and look for **`Last State: Terminated · Reason: OOMKilled · Exit Code: 137`** after a failing run. Workaround for the load-test instance: raise the deployment **`resources.limits.memory`**. Real fix (in source): stream the upload through pdf-lib instead of holding the full buffer twice, or cap concurrent uploads at the controller via a semaphore.
162
-
2. **Classifier-document upload fails with HTTP 500 above ~64 KB.** The endpoint **`POST /api/azure/classifier/documents`** in **[`apps/backend-services/src/azure/azure.controller.ts`](../../apps/backend-services/src/azure/azure.controller.ts:223)** uses **`@UseInterceptors(FilesInterceptor("files"))`** with no explicit limits. Files **≤ 64 KB** return 201; **≥ 96 KB** consistently return **`HTTP 500 {"statusCode":500,"message":"Internal server error"}`** in under 250 ms. The list and delete endpoints on the same controller (`GET`/`DELETE /api/azure/classifier/documents`) are unaffected. The OCR upload at **`POST /api/upload`** is unaffected because it is JSON-bodied (governed by **`BODY_LIMIT`**), not multipart. Compare with **[`apps/backend-services/src/benchmark/dataset.controller.ts:222`](../../apps/backend-services/src/benchmark/dataset.controller.ts)** where the dataset multipart endpoint explicitly sets **`limits: { fileSize: 100 * 1024 * 1024 }`** — the classifier endpoint should do the same. Without **`oc`** access to read the backend log this could not be confirmed end-to-end, but the failure is fast, deterministic, and size-correlated, which fits a multer **`limits.fileSize`** rejection. Fix: add **`@UseInterceptors(FilesInterceptor("files", { limits: { fileSize: 100 * 1024 * 1024 } }))`** on the classifier upload route, or register a global **`MulterModule.register`** with a project-wide default that matches **`BODY_LIMIT`**.
162
+
2.**Classifier-document upload fails with HTTP 500 above ~64 KB***(fixed)*. The endpoint **`POST /api/azure/classifier/documents`** now sets an explicit **`limits.fileSize: 100 * 1024 * 1024`** on its `FilesInterceptor`, matching **[`apps/backend-services/src/benchmark/dataset.controller.ts:222`](../../apps/backend-services/src/benchmark/dataset.controller.ts)**. Oversized files return **HTTP 413** via **`MulterExceptionFilter`**. See **[`docs-md/CLASSIFIER_DOCUMENT_UPLOAD.md`](../CLASSIFIER_DOCUMENT_UPLOAD.md)**.
163
163
3. **In-cluster MinIO fills up after a few sustained upload runs.** After roughly **~1,500** documents uploaded across **`upload-ocr`** and **`payload-sizes`** runs at 256 KB–5 MB tiers, **`POST /api/upload`** starts returning **`HTTP 400 {"message":"Failed to write blob \"<group>/ocr/<id>/original.pdf\": Storage backend has reached its minimum free drive threshold. Please delete a few objects to proceed."}`**. The latency on the failed call is ~4 s (MinIO retries before erroring), and the error is upstream of the backend — it surfaces directly from the AWS S3 SDK call inside **[`apps/backend-services/src/blob-storage/minio-blob-storage.service.ts:86`](../../apps/backend-services/src/blob-storage/minio-blob-storage.service.ts)**. The MinIO PVC sizing comes from **[`deployments/openshift/kustomize/components/minio/pvc.yml`](../../deployments/openshift/kustomize/components/minio/pvc.yml)** with the size templated by **`scripts/lib/generate-overlay.sh`** (default `5Gi`, override with **`--minio-pvc-size`** or `MINIO_PVC_SIZE` in **`dev.env`**). The storage class **`netapp-file-standard`** has **`allowVolumeExpansion=true`**, so an existing PVC can be grown online with no pod restart and no data loss:
0 commit comments