Skip to content

v0.4.6

Choose a tag to compare

@justin-stanley justin-stanley released this 06 Oct 17:58
· 12 commits to main since this release
aaa18bd

FeatherReader 0.4.6 stops renames from losing data:

  • Renaming a subscription can no longer erase another atproto client's edit made at the same moment.
  • Renaming a folder now changes only its name instead of rebuilding the record.

Full engineering detail is in CHANGELOG.md.

Upgrade notes

  • No schema change and no new settings. Upgrading from 0.4.5 is a deploy, and rolling back to 0.4.5 is a redeploy. Both were rehearsed on a fork of a production volume: 0.4.6 booted with db: ok and served its pages, and 0.4.5 then booted on the result, also with db: ok.
  • Rename writes now carry swapRecord. A rename that races another client's edit is retried once against the fresh record, and the other client's change is kept. If it still conflicts, the reader sees "changed elsewhere … Reload and try again" instead of a false success. A folder rename that fails now shows an error. It used to redirect as if it had worked.
  • The manage page posts the values it showed (seen_url, seen_title, seen_folder, seen_name), so a change made elsewhere after the page loaded is detected too. A form posted without them still works.

Fixed

  • A subscription rename could erase another client's concurrent edit (#267, closes #149).
    • Every write path: putRecord takes swapRecord on the Rust OAuth client, the app-password client and the sidecar.
    • The rename: it writes against the CID it read. On InvalidSwap it re-reads and merges per field against what the reader first saw:
      • a field the reader didn't touch keeps the fresh value;
      • a field only the reader changed takes the reader's value;
      • a field both sides changed to different values is reported as a conflict.
    • Repeated saves: a double-submitted Save reports success and writes once.
    • Cache ordering: the local cache is updated only after the PDS write lands.
  • Renaming a folder overwrote the folder record (#269, closes #268). A rename rebuilt the record, which reset position, replaced createdAt with the rename time and dropped any field another client had added. Now it changes only name, keeps unknown fields through a catch-all on Folder, writes with compare-and-swap, uses the same merge-and-retry, and never re-creates a folder that was deleted elsewhere.

Known

  • Subscription has no catch-all for unknown fields either, so a subscription rename still drops fields the struct doesn't name. The fields it does name are kept. This is a follow-up.