• Stefy Lanza (nextime / spora )'s avatar
    ocr: pdfium is not thread-safe, and 0.3.65 found out in production (v0.3.66) · 43cc57a5
    Stefy Lanza (nextime / spora ) authored
    0.3.65 moved PDF rendering into asyncio.to_thread so a long document would stop
    stalling the event loop. That was correct in intent and broke OCR within the
    hour: until then `load_pages` ran ON the loop, which serialised every
    rasterisation BY ACCIDENT. Removing the accident let documents into pdfium
    concurrently, and pdfium permits exactly one caller at a time. Concurrent use
    corrupts its state and reports
    
        failed to rasterise PDF (pypdfium2): PDFium: Data format error
    
    on documents that are perfectly valid -- so the failure accuses the input, and
    the operator goes looking at their files. Three valid Diogene PDFs that poppler
    parsed cleanly were rejected this way.
    
    Measured: 1 document OK, 8 concurrent = 8 failures, 24 = 24 failures. After the
    fix, 48 concurrent 47-page PDFs all return 47 pages.
    
    Every pdfium call -- document open, page size probe, page render -- now runs
    under one lock, held per CALL rather than per document so documents still
    interleave page by page instead of queueing behind each other's full length.
    Rendering still happens off the event loop, so this is strictly better than
    0.3.64, which serialised AND blocked the loop.
    
    Cost, stated plainly: rasterisation is single-threaded, a ceiling of about one
    core. That is what 0.3.64 effectively was, so it is not a regression against it.
    Rasterising in a process pool (pdfium is safe one-document-per-process) is the
    scalability fix and is deliberately not bolted onto this hotfix.
    
    Two process lessons, in the tests so they outlive the memory of this:
    - this path is only ever exercised concurrently, so testing it sequentially
      tests the one case that cannot fail. I shipped it tested sequentially.
    - the error STRING predated the change, and I used that to argue the behaviour
      did too. "This message is not new" is not evidence of "this is not new".
    Co-Authored-By: 's avatarClaude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HXRMe9ZPUQCCCtBai9uqt3
    43cc57a5
Name
Last commit
Last update
codai Loading commit data...
docs Loading commit data...
packaging Loading commit data...
samples Loading commit data...
tests Loading commit data...
third_party Loading commit data...
tools Loading commit data...
.dockerignore Loading commit data...
.gitignore Loading commit data...
AI.PROMPT Loading commit data...
CODERAI_API_DOCUMENTATION.md Loading commit data...
CoderAI.gif Loading commit data...
DISTRIBUTION.md Loading commit data...
LICENSE.md Loading commit data...
MULTIMODAL_CAPABILITIES.md Loading commit data...
MULTIMODAL_UI_EXAMPLES.md Loading commit data...
README.md Loading commit data...
REQUEST-geoclip-embeddings.md Loading commit data...
REQUEST-vpr-embeddings.md Loading commit data...
amdgpu-coredump-05000.bin Loading commit data...
build-oci.sh Loading commit data...
build.ps1 Loading commit data...
build.sh Loading commit data...
coderai Loading commit data...
coderai-broker-implementation-reference.md Loading commit data...
coderai-integration.md Loading commit data...
commands Loading commit data...
osxbuild.sh Loading commit data...
package-oci.sh Loading commit data...
package-tarball.sh Loading commit data...
requirements-crisperwhisper.txt Loading commit data...
requirements-h3.txt Loading commit data...
requirements-longcat-train.txt Loading commit data...
requirements-longcat.txt Loading commit data...
requirements-melotts.txt Loading commit data...
requirements-nemo.txt Loading commit data...
requirements-nvidia.txt Loading commit data...
requirements-ocr-paddle.txt Loading commit data...
requirements-ocr.txt Loading commit data...
requirements-pyannote.txt Loading commit data...
requirements-surya.txt Loading commit data...
requirements-vllm.txt Loading commit data...
requirements-vulkan.txt Loading commit data...
requirements.txt Loading commit data...
run-oci.sh Loading commit data...
smoke-test-oci.sh Loading commit data...
todo.md Loading commit data...