mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-21 20:06:37 +00:00
d6efb65588
The scanner's pending-heal ledger and the MRF journal tracked the same damaged objects with no cross-talk: once the consumer landed an intent with the heal manager, the ledger's retry entry for that target kept re-submitting a heal the manager already owned (backlog#1894 axis B). Fan the acceptance out: both dispatch sites in the MRF queue (the live consumer and the startup replay) record a compact MrfRepairedEvent (bucket, object, version bytes) in a bounded process-wide ring owned by rustfs-common. The scanner drains its own bucket's notices at the top of retry_pending_scanner_heals and clears the matching Object-kind ledger entries in one batched retain + sync (a mass-recovery first sweep must not turn into thousands of full-table ledger clones on the scan task), with nil notice UUIDs mapping to None per the repo-wide defensive-UUID invariant so unversioned entries match unversioned notices only. Notices are best-effort by design — a lost or capped-out notice leaves the entry to expire through its own attempts/age limits, because the ledger is a retry oracle, not a source of truth; other buckets' notices stay queued for their own scanners. Neither persistent format changes; old nodes that keep double-booking remain harmless. Co-authored-by: heihutu <heihutu@gmail.com>