fix(tika-worker): stream S3 blobs to Tika instead of buffering (#189)#191
Merged
Conversation
TikaWorker materialized each blob fully in memory before sending it to Tika (peak ~2-3x blob size). A single large S3-tiered PDF/image OOM-killed a small worker pod (256Mi) into CrashLoopBackOff. _extract now streams the S3 path: get_object()['Body'].iter_chunks() is handed straight to httpx as the request content, with Content-Length from the object metadata. The worker's memory stays ~flat regardless of blob size. The PG-bytea path (small sub-threshold inline blobs) still sends bytes. Blob-location logic is split into _blob_source() so _extract streams while _fetch_blob keeps materializing for its callers. Closes #189 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
TikaWorkermaterialized each blob entirely in memory before sending it to Tika — peak ≈ 2–3× the blob size (S3download_fileobjbuffer +getvalue()copy + httpx request body). On a deployment with S3-tiered blobs and a small worker pod (256Mi limit), a single large PDF/image OOM-killed the worker (exit 137) intoCrashLoopBackOff, stalling extraction. Raising the memory limit only masks it.Fix
_extract()now streams the S3 path straight from S3 into the Tika request body:Bytes flow S3 → worker → Tika in 1 MiB chunks, so the worker never holds the whole blob and its memory stays roughly constant regardless of blob size.
Content-Lengthfromget_objectavoids chunked transfer-encoding.Blob-location logic is split into
_blob_source()(returns abytesors3descriptor without materializing S3);_extract()streams S3 while_fetch_blob()keeps materializing for its remaining callers. The PG-bytea path (small inline blobs below the S3 tiering threshold) is unchanged.Pairs with the configurable
TIKA_WORKER_HTTP_TIMEOUT(#183).Tests
tests/test_tika_worker_extras.py— 2 new: the S3 path hands theiter_chunksiterator (not a bytes buffer) to httpx withContent-Lengthand never callsdownload_fileobj; the PG-bytea path still sends bytes._extract's existing tests adjusted for the_blob_sourcesplit. 18 passed, 2 skipped.Closes #189
🤖 Generated with Claude Code