Fix disk I/O error on sync by relocating the database to the App Group container#17
Merged
Conversation
The app and File Provider extension kept the live SQLite database inside the File Provider domain's state directory (NSFileProviderManager.stateDirectoryURL). fileproviderd deletes that directory on every domain remove/re-add — which the app triggers on Sparkle updates, session recovery, and manual resets. After such an event the app kept writing through the now-unlinked file handle, so the next sync failed with "saveItems step failed: disk I/O error". Move the canonical database, and user-created local file content, to the App Group container. Both processes already reach it via the application-groups entitlement and fileproviderd never reclaims it, so the handle stays valid across domain resets and re-registration no longer needs to snapshot and re-seed. The bundled MCP helper now reads live data instead of a stale snapshot, since it already resolves to the container path. A one-time migration copies any surviving per-site data from the old state-directory database into the container.
The previous check treated an empty last-seen version as a fresh install and recorded the current version without showing the showcase. That key is empty for every upgrader too (earlier versions never wrote it), so the sheet was suppressed for exactly its intended audience. Show it whenever the last-seen version differs from the current one — fresh installs included — and stamp the version on dismiss. The sheet is only attached to the workspace, so onboarding is never interrupted.
Nightly BuildDownload Findle Nightly (unsigned) Built from a591746. Important This build is unsigned. macOS will block it on first launch. To open it:
|
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.
Summary
The 0.2.0 release breaks sync with
saveItems step failed: disk I/O error, and the What's New showcase never appears on upgrade. Both are fixed here.Disk I/O error
The app and File Provider extension kept the live SQLite database inside the File Provider domain's state directory (
NSFileProviderManager.stateDirectoryURL()).fileproviderddeletes that directory on every domain remove/re-add — which the app triggers on Sparkle updates, session-expiry recovery, and manual resets. After such an event the app keeps writing through the now-unlinked file handle, so the next sync fails with a disk I/O error. (Confirmed on disk: the running app held open fds to a state-dir database whose entire domain directory had been reclaimed.)The canonical database (and user-created local file content) now lives in the App Group container, which both processes already reach via the
application-groupsentitlement and whichfileproviderdnever reclaims. The handle survives domain resets, so re-registration no longer needs to snapshot and re-seed. The bundled MCP helper also reads live data now instead of a stale snapshot, since it already resolves to the container path.A one-time migration copies any surviving per-site data from the old state-directory database into the container.
What's New
The previous gate treated an empty last-seen version as a fresh install and suppressed the showcase — but that key is empty for every upgrader too. It now shows whenever the last-seen version differs from the current one (fresh installs included) and stamps the version on dismiss. The sheet is only attached to the workspace, so onboarding is never interrupted.
Testing
xcodebuild build(app + extension + MCP): succeedsRelease
Intended to re-cut the v0.2.0 tag; the CI build number increments so Sparkle still offers the update to anyone on the broken 0.2.0.