Repository navigation
fix(offline): stop the launch cleanup exhausting file descriptors and clearing downloaded books - #1336
Merged
Conversation
…eleting unreadable books The launch sweep checked every book directory with an early-exited directory enumerator. Each one kept its descriptor open until an autorelease pool drained, and the sweep runs as a single job, so libraries past roughly 250 downloaded books ran the process out of file descriptors. From then on every directory read failed, read as empty, and downloaded books were treated as having lost their content: the sweep tried to delete them and reset them to not downloaded, while downloads, database writes, and logging failed alongside. The directory check now reads each level in one call and throws when a directory cannot be read. The sweep skips directories it cannot inspect and reports them once.
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
With a large offline library, launching the app could make downloads fail with
SQLite error 14: unable to open database fileand leave downloaded books cleared.The launch sweep (
cleanupOrphanedFiles) checks every book directory for files. That check used a directory enumerator and returned as soon as it found a file, which leaves the enumerator holding an open descriptor until an autorelease pool drains. The sweep walks all book directories as one job, so past roughly 250 downloaded books the process ran out of file descriptors.From that point every directory read failed, and the check reported a failed read as "no files". The sweep then treated the remaining downloaded books as having lost their content: it tried to delete their directories and reset them to not downloaded. Because the limit is process-wide, downloads, database writes, and log writes failed during the same window.
The reporter's exported log shows this after each launch: thousands of
Failed to cleanup orphaned directory(POSIX 24, too many open files) andFailed to persist download status(SQLite 14) entries.Change
directoryContainsFilesreads each directory level in one call instead of keeping an enumerator open, so the sweep holds no descriptors between books.removeBookDirectoryIfEmptyleaves the directory in place when it cannot be read.repo-conventionsskill records the invariant: an unreadable directory is not an empty one.Books that an earlier build already reset to not downloaded are not restored; they need to be downloaded again.
Validation
make build-ios,make build-macos,make build-tvospass.Includes build 687.
Related to #1330.
🤖 Generated with Claude Code