Skip to content

Safely apply OTA DB updates: reuse live DB handle, use native download, and reorganize app init#1535

Closed
CraigBuckmaster wants to merge 1 commit into
masterfrom
codex/investigate-app-crash-after-db-download-4y6bgo
Closed

Safely apply OTA DB updates: reuse live DB handle, use native download, and reorganize app init#1535
CraigBuckmaster wants to merge 1 commit into
masterfrom
codex/investigate-app-crash-after-db-download-4y6bgo

Conversation

@CraigBuckmaster
Copy link
Copy Markdown
Owner

Motivation

  • Avoid crashes and memory issues when applying OTA content DB updates while the app holds an open SQLite handle.
  • Use the native file download path to prevent large ArrayBuffer/base64 memory spikes and Obj-C exceptions observed with the legacy XHR+write path.
  • Ensure user-scoped initialization (user DB, stores, Sentry anon id) is performed consistently both on cold init and after a first-launch DB download.

Description

  • Reorganized app startup in App.tsx by extracting hydrateAppState() and calling it only after content DB initialization, and set dbStatus early when initDatabase() returns needs_download.
  • Updated DbDownloadScreen onComplete to be async-capable and await post-download initialization steps (initDatabase, initUserDatabase, Sentry anon id set, store hydrations, and pruneEvents) before setting dbStatus to ready.
  • Added getDbIfInitialized() and closeDatabaseConnection() helpers in src/db/database.ts to expose/close the live content DB handle without forcing open/close churn.
  • In services/ContentUpdater.ts added an early check using getDbIfInitialized() to defer OTA applies when a live DB handle is open, reused the live handle inside getInstalledVersion() to avoid opening a second connection, switched full-DB downloads to File.downloadFileAsync, and replaced the memory-heavy file checksum step with validation that opens the downloaded DB and checks db_meta.content_hash plus PRAGMA integrity_check before swapping files.
  • Updated __tests__/services/ContentUpdater.test.ts to mock native downloadFileAsync, introduce mockGetDbIfInitialized, and add tests covering live-handle reuse/deferral, native download usage, integrity-check failure, and adjusted download progress expectations while removing the legacy chunked-write assertions.

Testing

  • Ran the jest unit test suite for the ContentUpdater service (__tests__/services/ContentUpdater.test.ts) which exercises manifest fetching, delta/full update flows, and the new live-DB and native-download paths, and the tests passed.
  • Verified that ContentUpdater tests asserting the native download, deferral when live DB is open, and integrity-check behavior all succeed under the updated mocks.

Codex Task

@CraigBuckmaster
Copy link
Copy Markdown
Owner Author

Closing. Two structural issues:

  1. Branched from stale master. This PR's base is cd4e84c5 (pre-fix + diagnostic: native DB download, correct startup ordering, JS error handler #1529). It duplicates work already merged in fix + diagnostic: native DB download, correct startup ordering, JS error handler #1529 (native download path, hydration ordering, onComplete error surfacing), duplicates getDbIfInitialized() / live-handle reuse from the open PR refactor: DB lifecycle hardening during OTA content updates #1532, and reintroduces the PRAGMA integrity_check that fix(ContentUpdater): remove full-DB PRAGMA integrity_check (iOS 26 FTS5 teardown crash) #1534 just removed — which was the confirmed root cause of the build-20 FTS5 teardown crash.

  2. Misdiagnoses the build-21 crash. The description claims the fix is to force native File.downloadFileAsync instead of the XHR+ArrayBuffer path. But scripture.db is ~100MB, which exceeds the 25MB LARGE_DB_NATIVE_DOWNLOAD_THRESHOLD_BYTES already on master — build 21 was already taking the native path. Removing the XHR fallback entirely doesn't address the confirmed crash path, and the PR's reference to "TestFlight 1.0.7(20) at SQLiteModule.closeDatabase" in the defer-OTA comment is conflating the build-20 segfault (fixed in fix(ContentUpdater): remove full-DB PRAGMA integrity_check (iOS 26 FTS5 teardown crash) #1534) with the build-21 SIGABRT (different crash, different root cause, still under investigation).

The defer-OTA idea was evaluated in #1533 and closed — it cannot be implemented as-is because the DB is always open after startup, which would mean updates never fire. Long-term direction (defer-to-cold-start architecture) is documented as Option B in #1532's TODO block.

For the build-21 crash we're waiting on Sentry data or adding a native-exception diagnostic before the next build. Shipping speculative fixes without knowing what broke would burn EAS credits without informing the diagnosis.

@CraigBuckmaster CraigBuckmaster deleted the codex/investigate-app-crash-after-db-download-4y6bgo branch April 21, 2026 02:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant