mirror of
https://github.com/pgsty/minio.git
synced 2026-10-30 04:20:36 +03:00
fix: drop the broken bucket-metadata reload publication guard (issue #105 T3)
The #105 T3 change (PR #156) tried to keep the resident metadata cache monotonic by guarding peer-reload publication on lastUpdate(). But lastUpdate() is the max of per-config timestamps and cannot order whole records: a node caching {policy@20, CORS@10} that receives a newer CORS@15 still has lastUpdate()==20, so the guard rejects the legitimately-newer record and the periodic refresh (same comparator) cannot repair it. A paused reload could also resurrect deleted resident state. Per the maintainer decision, revert the reload publication to its original unconditional (acceptable-until-refresh) behavior: - remove setReloaded and restore the plain Set plus notification/target registry updates in LoadBucketMetadataHandler; - restore refreshBucketsMetadataLoop's own lastUpdate() staleness check and globalEventNotifier.set / globalBucketTargetSys.set publication; - restore the unconditional GetConfig cache-miss publication; - document the known freshness limitation at the reload site (the periodic refresh is best-effort and cannot repair an equal-maximum-timestamp divergence). The T1 lifecycle merge-under-lock (UpdateExpiryLCConfig) and both T2 fixes (DeleteBucket takes metadata.lock before deleting; saveMetadata and loadBucketMetadataParseUnderLock recheck physical bucket existence) are kept fully intact. Tests: - drop the T3 reproductions (overlapping-reload resident-cache test and the peer-reload-preserves-current-targets publication test); - add lockBucketMetadataAcquireHook, a nil-in-production atomic test hook in the shared metadata.lock path, so tests can deterministically observe a caller (notably DeleteBucket, whose lock is taken through its erasureServerPools receiver and is invisible to an injected object layer) reaching the lock; - rewrite the T2 delete-race ghost test to hold metadata.lock MID-SAVE (past saveMetadata's existence recheck) and synchronize on the delete's actual lock attempt via the hook, so it isolates the lock-before-delete fix: removing only DeleteBucket's metadata.lock (recheck kept) now fails it; - rewrite the cancellation test to observe the delete's actual lock attempt, then cancel and await its error while still holding the lock, so a scheduling-delayed delete stopped by the canceled context can no longer pass on a broken tree. Refs #105. Follows #156. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Feng Ruohang <rh@vonng.com>
This commit is contained in:
+20
-2
@@ -544,8 +544,26 @@ func (s *peerRESTServer) LoadBucketMetadataHandler(mss *grid.MSS) (np grid.NoPay
|
||||
return np, grid.NewRemoteErr(err)
|
||||
}
|
||||
|
||||
// Publish the metadata and derived registries from the same current revision.
|
||||
globalBucketMetadataSys.setReloaded(bucketName, meta)
|
||||
// Publish the reloaded metadata unconditionally. Overlapping peer reloads
|
||||
// may briefly leave the resident cache a revision behind, or momentarily
|
||||
// apply an older reload's derived registries. The resident cache may lag
|
||||
// until another authoritative update advances it; the periodic metadata
|
||||
// refresh is only best-effort here and cannot repair a divergence whose
|
||||
// maximum per-config timestamp already equals the resident record's (its
|
||||
// staleness check compares the same lastUpdate() and would see no change).
|
||||
// This acceptable-until-refresh behavior is deliberate: lastUpdate() is the
|
||||
// max of per-config timestamps and cannot order whole-record revisions, so a
|
||||
// publication guard keyed on it would wrongly reject legitimately newer
|
||||
// records (issue #105 follow-up dropped that guard).
|
||||
globalBucketMetadataSys.Set(bucketName, meta)
|
||||
|
||||
if meta.notificationConfig != nil {
|
||||
globalEventNotifier.AddRulesMap(bucketName, meta.notificationConfig.ToRulesMap())
|
||||
}
|
||||
|
||||
if meta.bucketTargetConfig != nil {
|
||||
globalBucketTargetSys.UpdateAllTargets(bucketName, meta.bucketTargetConfig)
|
||||
}
|
||||
|
||||
return np, nerr
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user