mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-08-29 00:17:12 +00:00
refactor: use replication factor of the layout versions in calculate_sync_map_min_with_quorum
This commit is contained in:
@@ -28,7 +28,6 @@ pub struct SyncLayoutDigest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct LayoutHelper {
|
pub struct LayoutHelper {
|
||||||
replication_factor: ReplicationFactor,
|
|
||||||
consistency_mode: ConsistencyMode,
|
consistency_mode: ConsistencyMode,
|
||||||
layout: Option<LayoutHistory>,
|
layout: Option<LayoutHistory>,
|
||||||
|
|
||||||
@@ -51,7 +50,6 @@ pub struct LayoutHelper {
|
|||||||
|
|
||||||
impl LayoutHelper {
|
impl LayoutHelper {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
replication_factor: ReplicationFactor,
|
|
||||||
consistency_mode: ConsistencyMode,
|
consistency_mode: ConsistencyMode,
|
||||||
mut layout: LayoutHistory,
|
mut layout: LayoutHistory,
|
||||||
mut ack_lock: HashMap<u64, AtomicUsize>,
|
mut ack_lock: HashMap<u64, AtomicUsize>,
|
||||||
@@ -97,8 +95,7 @@ impl LayoutHelper {
|
|||||||
// consistency on those).
|
// consistency on those).
|
||||||
// This value is calculated using quorums to allow progress even
|
// This value is calculated using quorums to allow progress even
|
||||||
// if not all nodes have successfully completed a sync.
|
// if not all nodes have successfully completed a sync.
|
||||||
let sync_map_min =
|
let sync_map_min = layout.calculate_sync_map_min_with_quorum(&all_nongateway_nodes);
|
||||||
layout.calculate_sync_map_min_with_quorum(replication_factor, &all_nongateway_nodes);
|
|
||||||
|
|
||||||
let trackers_hash = layout.calculate_trackers_hash();
|
let trackers_hash = layout.calculate_trackers_hash();
|
||||||
let staging_hash = layout.calculate_staging_hash();
|
let staging_hash = layout.calculate_staging_hash();
|
||||||
@@ -111,7 +108,6 @@ impl LayoutHelper {
|
|||||||
let is_check_ok = layout.check().is_ok();
|
let is_check_ok = layout.check().is_ok();
|
||||||
|
|
||||||
LayoutHelper {
|
LayoutHelper {
|
||||||
replication_factor,
|
|
||||||
consistency_mode,
|
consistency_mode,
|
||||||
layout: Some(layout),
|
layout: Some(layout),
|
||||||
ack_map_min,
|
ack_map_min,
|
||||||
@@ -134,7 +130,6 @@ impl LayoutHelper {
|
|||||||
let changed = f(self.layout.as_mut().unwrap());
|
let changed = f(self.layout.as_mut().unwrap());
|
||||||
if changed {
|
if changed {
|
||||||
*self = Self::new(
|
*self = Self::new(
|
||||||
self.replication_factor,
|
|
||||||
self.consistency_mode,
|
self.consistency_mode,
|
||||||
self.layout.take().unwrap(),
|
self.layout.take().unwrap(),
|
||||||
std::mem::take(&mut self.ack_lock),
|
std::mem::take(&mut self.ack_lock),
|
||||||
|
|||||||
+15
-11
@@ -123,13 +123,9 @@ impl LayoutHistory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn calculate_sync_map_min_with_quorum(
|
/// This function calculates the minimum layout version from which
|
||||||
&self,
|
/// it is safe to read if we want to maintain read-after-write consistency.
|
||||||
replication_factor: ReplicationFactor,
|
pub(crate) fn calculate_sync_map_min_with_quorum(&self, all_nongateway_nodes: &[Uuid]) -> u64 {
|
||||||
all_nongateway_nodes: &[Uuid],
|
|
||||||
) -> u64 {
|
|
||||||
// This function calculates the minimum layout version from which
|
|
||||||
// it is safe to read if we want to maintain read-after-write consistency.
|
|
||||||
// In the general case the computation can be a bit expensive so
|
// In the general case the computation can be a bit expensive so
|
||||||
// we try to optimize it in several ways.
|
// we try to optimize it in several ways.
|
||||||
|
|
||||||
@@ -139,8 +135,6 @@ impl LayoutHistory {
|
|||||||
return self.current().version;
|
return self.current().version;
|
||||||
}
|
}
|
||||||
|
|
||||||
let quorum = replication_factor.write_quorum(ConsistencyMode::Consistent);
|
|
||||||
|
|
||||||
let min_version = self.min_stored();
|
let min_version = self.min_stored();
|
||||||
let global_min = self
|
let global_min = self
|
||||||
.update_trackers
|
.update_trackers
|
||||||
@@ -153,7 +147,16 @@ impl LayoutHistory {
|
|||||||
// This is represented by reading from the layout with version
|
// This is represented by reading from the layout with version
|
||||||
// number global_min, the smallest layout version for which all nodes
|
// number global_min, the smallest layout version for which all nodes
|
||||||
// have completed a sync.
|
// have completed a sync.
|
||||||
if quorum == self.current().replication_factor {
|
//
|
||||||
|
// While we currently do not support changing the replication factor
|
||||||
|
// between layout versions, this calculation is future-proofing for the
|
||||||
|
// case where this might be possible.
|
||||||
|
if self
|
||||||
|
.versions
|
||||||
|
.iter()
|
||||||
|
.filter(|v| v.version >= global_min)
|
||||||
|
.all(|v| v.write_quorum(ConsistencyMode::Consistent) == v.replication_factor)
|
||||||
|
{
|
||||||
return global_min;
|
return global_min;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +198,8 @@ impl LayoutHistory {
|
|||||||
.map(|x| self.update_trackers.sync_map.get(x, min_version))
|
.map(|x| self.update_trackers.sync_map.get(x, min_version))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
sync_values.sort();
|
sync_values.sort();
|
||||||
let set_min = sync_values[sync_values.len() - quorum];
|
let set_min =
|
||||||
|
sync_values[sync_values.len() - v.write_quorum(ConsistencyMode::Consistent)];
|
||||||
if set_min < current_min {
|
if set_min < current_min {
|
||||||
current_min = set_min;
|
current_min = set_min;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,12 +64,8 @@ impl LayoutManager {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cluster_layout = LayoutHelper::new(
|
let mut cluster_layout =
|
||||||
replication_factor,
|
LayoutHelper::new(consistency_mode, cluster_layout, Default::default());
|
||||||
consistency_mode,
|
|
||||||
cluster_layout,
|
|
||||||
Default::default(),
|
|
||||||
);
|
|
||||||
cluster_layout.update_update_trackers(node_id.into());
|
cluster_layout.update_update_trackers(node_id.into());
|
||||||
|
|
||||||
let layout = Arc::new(RwLock::new(cluster_layout));
|
let layout = Arc::new(RwLock::new(cluster_layout));
|
||||||
|
|||||||
Reference in New Issue
Block a user