wordpress-mobile / wordpress-mobile/GutenbergKit
Asset bundle commit is a non-atomic remove-then-copy
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 29
- Forks
- 6
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 41
Description
EditorAssetBundle.copy(to:) commits a downloaded asset bundle by deleting the destination and copying into it. Two editors on the same site can run that concurrently, so one can delete the directory the other is currently serving assets from.
Detail
ios/Sources/GutenbergKit/Sources/Model/EditorAssetBundle.swift:217-223 is directoryExists → removeItem → createDirectory → copyItem, against storageRoot/<manifest-checksum> (EditorAssetLibrary.swift:245).
Nothing serializes two writers. Each EditorViewController builds its own EditorService (EditorViewController.swift:223), which builds its own EditorAssetLibrary — actor isolation is per-instance, so two editors for the same site are two independent actors writing the same path.
How it bites
Cold asset cache (first open of a site, or after deleteAllData), slow connection. The user opens the editor, backs out, and immediately reopens.
Editor B downloads and commits, then starts serving assets from storageRoot/<checksum>. Editor A — still finishing its own download — reaches copy(to:), sees the directory exists, removes it, and re-copies. For the duration of that window every plugin/theme asset request misses the bundle.
The blast radius is smaller than it first looks, and worth stating so nobody over-fixes it:
- The path is checksum-keyed, so identical checksum means identical content. This is a window of absence, not corruption.
EditorAssetBundleProvider.swift:78-85already falls back tofetchFromRemotefor any asset missing from the bundle, so the visible editor degrades to network refetches rather than erroring. Offline, those assets just don't load.prepareAssetBundle()short-circuits onreadAssetBundles().first(EditorService.swift:234-243), so a warm cache never reachescopy(to:)at all.
Suggested fix
Commit via an atomic rename — write to a sibling temp directory and replaceItemAt — or skip the copy entirely when hasBundle(forManifestChecksum:) is already true.
Found while reviewing #651. Pre-existing; the removal of the mid-load cancellation widens the window slightly, but the old cancellation was worse here (see #667).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ios/Sources/GutenbergKit/Sources/Model/EditorAssetBundle.swift:217-223 and trace the storage path from EditorAssetLibrary.swift:245. Review EditorViewController.swift:223 and EditorService.swift:234-243 to understand independent writers and the warm-cache shortcut. Update the commit flow so concurrent bundle commits do not expose a missing directory, then verify the provider fallback in EditorAssetBundleProvider.swift:78-85 still behaves as expected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 65/100