mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-07 13:53:12 +00:00
fix(replication): make sync delivery target-granular (#5630)
This commit is contained in:
@@ -660,6 +660,27 @@ impl ReplicateDecision {
|
||||
self.targets_map.values().any(|t| t.synchronous)
|
||||
}
|
||||
|
||||
/// Split admitted targets by their configured delivery mode.
|
||||
///
|
||||
/// Non-replicating entries are intentionally omitted from both decisions.
|
||||
/// Callers must not promote an async target merely because another target is
|
||||
/// synchronous, and unsupported operation paths can keep both partitions
|
||||
/// empty or explicitly async.
|
||||
pub fn partition_by_sync(&self) -> (Self, Self) {
|
||||
let mut synchronous = Self::new();
|
||||
let mut asynchronous = Self::new();
|
||||
|
||||
for target in self.targets_map.values().filter(|target| target.replicate) {
|
||||
if target.synchronous {
|
||||
synchronous.set(target.clone());
|
||||
} else {
|
||||
asynchronous.set(target.clone());
|
||||
}
|
||||
}
|
||||
|
||||
(synchronous, asynchronous)
|
||||
}
|
||||
|
||||
/// Updates ReplicateDecision with target's replication decision
|
||||
pub fn set(&mut self, target: ReplicateTargetDecision) {
|
||||
self.targets_map.insert(target.arn.clone(), target);
|
||||
@@ -1067,6 +1088,32 @@ mod tests {
|
||||
assert_eq!(entry.target_arns, vec!["arn:target-a".to_string()]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn partition_by_sync_keeps_mixed_targets_independent() {
|
||||
let mut decision = ReplicateDecision::new();
|
||||
decision.set(ReplicateTargetDecision::new("arn:sync".to_string(), true, true));
|
||||
decision.set(ReplicateTargetDecision::new("arn:async".to_string(), true, false));
|
||||
decision.set(ReplicateTargetDecision::new("arn:disabled".to_string(), false, true));
|
||||
|
||||
let (synchronous, asynchronous) = decision.partition_by_sync();
|
||||
|
||||
assert_eq!(synchronous.replicate_target_arns(), vec!["arn:sync".to_string()]);
|
||||
assert_eq!(asynchronous.replicate_target_arns(), vec!["arn:async".to_string()]);
|
||||
assert!(synchronous.is_synchronous());
|
||||
assert!(!asynchronous.is_synchronous());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn partition_by_sync_does_not_promote_async_targets() {
|
||||
let mut decision = ReplicateDecision::new();
|
||||
decision.set(ReplicateTargetDecision::new("arn:async".to_string(), true, false));
|
||||
|
||||
let (synchronous, asynchronous) = decision.partition_by_sync();
|
||||
|
||||
assert!(!synchronous.replicate_any());
|
||||
assert_eq!(asynchronous.replicate_target_arns(), vec!["arn:async".to_string()]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn target_state_reads_resync_timestamp_from_target_reset_header_key() {
|
||||
let arn = "arn:rustfs:replication:us-east-1:target:bucket";
|
||||
|
||||
Reference in New Issue
Block a user