fix(xmtp_mls): defer unknown task kinds instead of deleting them - #4020
Conversation
An older client that finds a task kind it does not understand — only possible when a newer client shares the same local database — deleted the row. That discards work the newer client still expects to run, and `run_and_reschedule_task` already treats `TaskOutcome::Done` as a delete. Reschedule instead. The row survives for whichever client does understand it, and `expires_at_ns` still bounds how long an unclaimed row can linger, so an old client running alone cannot accumulate them forever.
|
Claude finished @tylerhawkes's task —— View job Code Review CompletedReview Date: August 19, 2026 at 20:07 UTC
Review FeedbackThe implementation is solid and well-reasoned. The approach of deferring unknown task kinds instead of deleting them correctly handles the multi-version database sharing scenario. Strengths:
Minor observations:
No blocking issues. The change addresses the stated problem correctly and follows the codebase's patterns for task handling. |
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Small, self-contained bug fix by the designated code owner. Changes unknown task handling from deletion to 1-hour deferral for multi-version database compatibility, with clear rationale documented in comments. You can add or adjust custom eligibility rules. Learn more. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4020 +/- ##
==========================================
- Coverage 85.93% 85.92% -0.01%
==========================================
Files 417 417
Lines 68170 68172 +2
==========================================
- Hits 58579 58575 -4
- Misses 9591 9597 +6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Follow-up to #4018, addressing a Macroscope finding raised on #4011.
#4018 added a
KpLivenessarm torun_taskfor the task variant the proto regen introduced. Nothing in this crate schedules that kind yet, so the arm deleted the row.A row of an unknown kind can only appear one way: a newer client wrote it into a database this build also opens. Deleting it discards work that newer client still expects to run, and it is not recoverable — the scheduling decision lived in the row.
Reschedule instead. The row survives for whichever client understands it, and
expires_at_ns(checked at the top ofrun_and_reschedule_task) still bounds how long an unclaimed row can sit there, so an old client running alone cannot accumulate them.One hour was picked so an old client sharing the database wakes on it rarely, while a newer client still picks it up promptly after a restart.
Independent of the app-data callback stack — it touches only
worker/tasks.rsand is based directly on main.🤖 Generated with Claude Code
https://claude.ai/code/session_01AdY7WKkNbJmdzpmUWvW1my
Note
Defer unknown task kinds instead of deleting them in MLS worker
Previously, unrecognized task kinds (such as
KpLivenessin older builds) were deleted when encountered. Now they are rescheduled 1 hour into the future using a newUNKNOWN_TASK_DEFER_NSconstant, preserving tasks for future processing by a compatible build.Behavioral Change: unknown tasks are no longer permanently deleted; they persist and retry every hour until a build that recognizes them is deployed.
Macroscope summarized 38ff2e2.