Repository navigation
fix(import): finalise imports over 2 GiB - #364
Merged
Merged
Conversation
recordings.file_size_bytes was a 32-bit INTEGER, so finalising any import over 2 GiB failed with "value out of int32 range". The error path then used the session without rolling it back, raised again, and left the recording UPLOADING with its files gone. The column becomes BIGINT, as documents.file_size_bytes already is; a downgrade clears sizes that no longer fit. A failed finalize now rolls back, cleans up as intended, and marks the recording ERROR.
5 of 17 tasks
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.
Pull Request
Description
Found during the 2.6.0 soak run, straight after #362. With #362 deployed, the 3.3 GB House of Lords MP4 uploaded in 27 seconds with no event-loop stalls, and then finalize failed:
Two bugs, both older than 2.6.0:
recordings.file_size_bytesis a 32-bitINTEGER. Finalising any import over 2 GiB (2,147,483,647 bytes) fails, and feat(import): accept audio from common video and media containers #333 makes that the normal case for screen recordings. The suite runs on SQLite, which has no such limit, so nothing caught it.documents.file_size_bytesis alreadyBigInteger.except Exceptionblock used the session without rolling it back.recording.idraisedPendingRollbackError, the cleanup raised again, and the client got a plain-text 500. The recording stayedUPLOADING, with 3.3 GB of parts and a 3.3 GB assembled file left on disk.Changes:
b182c2378829widens the column toBIGINT, and the model followsdocument.py(sa_column=Column(BigInteger)). The downgrade sets a size that no longer fits to NULL instead of aborting, since the column is informational and nothing reads it to find the file.ERRORwith "Failed to finalize the uploaded recording." as its step, as theHTTPExceptionbranch already did, instead of anUPLOADINGrow with no files.Upgrade and rollback. This is 2.6.0's only schema change. It runs on the first API start, and on a small
recordingstable the rewrite takes moments. Rolling the images back to 2.5.1 now needs the schema rolled back first, because the startup guard refuses a database stamped with a revision the image does not know.Type of change
Checks run
NOJOIN_TEST_POSTGRES_URL=... python scripts/check.py: 2,177 passed, none skipped, with every Postgres-gated test run against a throwaway pgvector/pg18 serverpython scripts/check.py(lint, format, whitespace, filesize, heldpins, typecheck, docs, alembic, tests all OK)scripts/check.pypython3 scripts/validate_alembic.py, headb182c2378829Also run against the throwaway Postgres:
scripts/check_migrations.pypasses all three phases: fresh install, seeded round trip through the new revision, and at head.file_size_bytes = 3292350489, thenalembic downgrade -1. The column isintegerand the size NULL.alembic upgrade headrestoresbigint.New tests in
test_import_audio_task.py:test_an_import_over_2_gib_keeps_its_size_on_postgresreports the assembled file as 3,292,350,489 bytes through a chunked import. On main it fails with the samevalue out of int32 rangeas the live stack.test_a_finalize_that_fails_in_the_database_marks_the_recording_failedruns on SQLite and Postgres. It forces a flush failure inside finalize, then checks for a JSON 500, a recording inERRORwith the message, no assembled file, and nothing queued.Migration impact
Documentation impact
The upgrade and rollback steps go in the 2.6.0 release notes (#360).
Security impact
Manual verification
Before: the failed finalize on the live stack, quoted above. The stranded recording was discarded through the API, which removed its row and its 6.6 GB.
Pending: the full 3.3 GB import on the live stack rebuilt with this merged, through extraction (#333) and processing, before 2.6.0 is tagged.