summaryrefslogtreecommitdiff
path: root/android/local.properties
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-08-05 00:36:18 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-08-05 00:36:18 +0000
commit7b9eb14db9b953b3c5882b3b85c819d9baa2dd2c (patch)
treea5d4fa8959186d8f34da6dede582d4b0c58ce154 /android/local.properties
parent0400e59e5d4a0140e98af01ad1acbc83d3f3f0a7 (diff)
Widget: fix "complete works once, then stops" race between overlapping completions
Root cause traced from server logs, not guessed: every completion request was succeeding server-side (100% 200s, including a 5-tap burst spanning different tasks), and each successful completion's response payload was correctly shrinking. So the failure wasn't dispatch or network -- it was that a successful completion could still get silently undone client-side. fetchAndPersist does an unconditional full overwrite of the cached item list on every successful GET. CompleteWorker/DeferWorker run one instance per task id with no ordering guarantee between different ids' workers (different unique work names, no KEEP protection across them -- that protection only ever covered same-task double-taps). So: tapping complete on task A starts a GET that's still in flight; tapping complete on task B before A's GET returns optimistically removes B locally; A's slower GET response, captured before B's completion landed, then overwrites the cache and silently resurrects B. Fix: track locally-optimistic removals with a timestamp (PendingRemovals.kt) and filter them out of every fetchAndPersist write for a bounded TTL (2 min), regardless of which worker's fetch is doing the writing. The TTL means a completion that never actually confirms (permanent network failure) still self-heals via the next periodic refresh, matching an existing self-healing property already relied on elsewhere in this codebase, instead of hiding the task forever. Added PendingRemovalsTest.kt (pure-function unit tests, no Android runtime needed) covering the exact race scenario plus TTL expiry and edge cases. Verified the tests actually catch a regression by deliberately reverting the fix to a no-op against a real backup, confirming 3 tests failed with the exact expected assertion, then restoring and confirming green again. Built, tested, and published as doot-widget.apk.
Diffstat (limited to 'android/local.properties')
0 files changed, 0 insertions, 0 deletions