summaryrefslogtreecommitdiffstats
path: root/src/notmuchworker.cpp
AgeCommit message (Collapse)AuthorFilesLines
2026-08-06fix(sync): hold tag edits made during a background syncDanilo M.1-1/+10
A tag edit sent while another process holds notmuch's write lock does not fail: the read-write open blocks and then succeeds. Measured against Slackware's notmuch, 9.158s against a 12s hold, status SUCCESS. Since the worker is a single thread, that blocked open holds up every read queued behind it, so the message pane freezes on whichever thread was selected first and replays the queue when the lock releases. The window now defers instead. While SyncMonitor reports a sync running, a tag change is held rather than sent, and flushed when the sync ends. The optimistic update stands in the meantime, so the row keeps its tag and the edit still counts toward the unsynced indicator, which is what the quit prompt reads. The original diagnosis was that the open fails and the edit is discarded, and a retry was built on it. That was wrong: the error branch in notmuchworker.cpp is unreachable through lock contention. The premise was taken from a plausible-looking error path without provoking the condition, and measurement disproved it. The backlog entry records this rather than quietly correcting it. Verified by hand against a real blocking open, which the tests cannot reach: they drive the deferral through the meta-object and never take a lock. Both locks held for 100s with a tag edit made during the hold. Row kept the tag, status did not expire, indicator rose, window stayed responsive, held edit sent itself on release. The 2s SyncMonitor polling window is knowingly left open: a sync starting between polls is invisible for up to 2s and an edit there still blocks. SyncMonitor::lockHeldIn() would close it at the cost of one file read per tag action, and is recorded as the option to revisit. Also fixes revertPendingTagChange() clearing the entire undo stack after any rejected write, found while working on this. Backlog: item 37 done, and item 46 added for a test that fails only under the offscreen platform, where an 800x800 screen clamps a restored 940px window. Pre-existing and unrelated; the suite is green otherwise.
2026-08-04feat(worker): list every tag in the databaseDanilo M.1-0/+21
Query bar completion cannot offer tag names without a way to enumerate them, and libnotmuch had no call wired up for it. Follows the existing generation-counter pattern; the result crosses the thread boundary as a QStringList. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04Add GPLv2-only license and per-file headersDanilo M.1-0/+18
Confirmed with the maintainer as v2-only rather than v2-or-later. LICENSE is the official text from gnu.org. Every file under src/ and tests/ carries the matching notice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04feat: add NotmuchWorker with batched queries and tag mutationDanilo M.1-0/+316
Owns the only notmuch database handle. Queries run read-only and emit threads in batches of 200 with a generation counter so the UI can discard superseded results. Tag mutation closes the read-only handle, opens read-write, applies, and closes, holding the process-wide write lock for milliseconds rather than blocking a concurrent `notmuch new`. Tested against a throwaway database built in a QTemporaryDir, superseding the spec's original "no unit test" position: applyTags is the only code here that writes to a notmuch index. The fixture never touches ~/Mail or ~/.notmuch-config. Two fixes against the drafted implementation, both caught by mutating the code and confirming exactly one test failed: - loadThread conflated "no query given" with "query matched nothing in this thread", so filtering a thread down to zero matches rendered every message expanded. Tracked with an explicit haveMatchSet flag. - applyTags now documents why a stale message id must skip rather than abort: notmuch_database_find_message reports SUCCESS with a null message for an unknown id, and the live ids alongside it still need tagging. Note for fixture authors: notmuch synchronizes maildir flags with tags at index time, so a file named `...:2,S` is indexed without the unread tag no matter what [new] tags requests. Unread fixture messages go in new/. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>