Skip to content

Commit 2118631

Browse files
committed
default_policy: Builder: forbid preferring racks without DCs
This is an API restriction continuing of what has already been done in bb09756: as the case of providing preferred rack without specifying the preferred datacenter is invalid, in spirit of the principle “Make illegal states unrepresentable”, `DefaultBuilder`'s API is changed accordingly to disallow creating such configuration. A stray backslash is deleted from a docstring. Docs are updated to reflect the API change.
1 parent 9d76db1 commit 2118631

File tree

2 files changed

+53
-57
lines changed

2 files changed

+53
-57
lines changed

docs/source/load-balancing/default-policy.md

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ for queries with non-local consistency mode is also supported.
1010
`builder()` method of `DefaultPolicy` returns a new instance of
1111
`DefaultPolicyBuilder` with the following default values:
1212

13-
- `preferred_datacenter`: `None`
14-
- `preferred_rack`: `None`
13+
- `preferences`: no particular datacenter/rack preference
1514
- `is_token_aware`: `true`
1615
- `permit_dc_failover`: `false`
1716
- `latency_awareness`: `None`
@@ -25,8 +24,7 @@ You can use the builder methods to configure the desired settings and create a
2524
use scylla::load_balancing::DefaultPolicy;
2625

2726
let default_policy = DefaultPolicy::builder()
28-
.prefer_datacenter("dc1".to_string())
29-
.prefer_rack("rack1".to_string())
27+
.prefer_datacenter_and_rack("dc1".to_string(), "rack1".to_string())
3028
.token_aware(true)
3129
.permit_dc_failover(true)
3230
.build();
@@ -35,36 +33,39 @@ let default_policy = DefaultPolicy::builder()
3533

3634
### Semantics of `DefaultPolicy`
3735

38-
#### Preferred Datacenter
36+
#### Preferences
37+
38+
The `preferences` field in `DefaultPolicy` allows the load balancing
39+
policy to prioritize nodes based on their location. It has three modes:
40+
41+
- no preference
42+
- preferred datacenter
43+
- preferred datacenter and rack
3944

40-
The `preferred_datacenter` field in `DefaultPolicy` allows the load balancing
41-
policy to prioritize nodes based on their location. When a preferred datacenter
42-
is set, the policy will treat nodes in that datacenter as "local" nodes, and
43-
nodes in other datacenters as "remote" nodes. This affects the order in which
44-
nodes are returned by the policy when selecting replicas for read or write
45-
operations. If no preferred datacenter is specified, the policy will treat all
46-
nodes as local nodes.
45+
When a datacenter `"my_dc"` is preferred, the policy will treat nodes in `"my_dc"`
46+
as "local" nodes, and nodes in other datacenters as "remote" nodes. This affects
47+
the order in which nodes are returned by the policy when selecting replicas for
48+
read or write operations. If no datacenter is preferred, the policy will treat
49+
all nodes as local nodes.
50+
51+
`preferences` allow the load balancing policy to prioritize nodes based on their
52+
availability zones (racks) in the preferred datacenter, too. When a datacenter
53+
and a rack are preferred, the policy will first return replicas in the local rack
54+
in the preferred datacenter, and then the other replicas in the datacenter
55+
(followed by remote replicas).
4756

4857
When datacenter failover is disabled (`permit_dc_failover` is set to
4958
false), the default policy will only include local nodes in load balancing
5059
plans. Remote nodes will be excluded, even if they are alive and available to
5160
serve requests.
5261

53-
#### Preferred Rack
54-
55-
The `preferred_rack` field in `DefaultPolicy` allows the load balancing policy to
56-
prioritize nodes based on their availability zones in the preferred datacenter.
57-
When a preferred rack is set, the policy will first return replicas in the local rack
58-
in the preferred datacenter, and then the other replicas in the datacenter.
59-
When a preferred datacenter is not set, setting preferred rack will not have any effect.
60-
6162
#### Datacenter Failover
6263

6364
In the event of a datacenter outage or network failure, the nodes in that
6465
datacenter may become unavailable, and clients may no longer be able to access
65-
the data stored on those nodes. To address this, the `DefaultPolicy` supports datacenter
66-
failover, which allows to route requests to nodes in other datacenters if the
67-
local nodes are unavailable.
66+
the data stored on those nodes. To address this, the `DefaultPolicy` supports
67+
datacenter failover, which allows to route requests to nodes in other datacenters
68+
if the local nodes are unavailable.
6869

6970
Datacenter failover can be enabled in `DefaultPolicy` by `permit_dc_failover`
7071
setting in the builder. When this flag is set, the policy will prefer to return

scylla/src/transport/load_balancing/default.rs

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,7 @@ impl Default for DefaultPolicy {
636636
/// # }
637637
#[derive(Clone, Debug)]
638638
pub struct DefaultPolicyBuilder {
639-
preferred_datacenter: Option<String>,
640-
preferred_rack: Option<String>,
639+
preferences: ReplicaLocationPreference,
641640
is_token_aware: bool,
642641
permit_dc_failover: bool,
643642
latency_awareness: Option<LatencyAwarenessBuilder>,
@@ -648,8 +647,7 @@ impl DefaultPolicyBuilder {
648647
/// Creates a builder used to customise configuration of a new DefaultPolicy.
649648
pub fn new() -> Self {
650649
Self {
651-
preferred_datacenter: None,
652-
preferred_rack: None,
650+
preferences: ReplicaLocationPreference::Any,
653651
is_token_aware: true,
654652
permit_dc_failover: false,
655653
latency_awareness: None,
@@ -668,24 +666,8 @@ impl DefaultPolicyBuilder {
668666
Box::new(DefaultPolicy::is_alive)
669667
};
670668

671-
// As the case of providing preferred rack without providing datacenter is invalid, the rack is then ignored.
672-
// According to the principle “Make illegal states unrepresentable”, in the next major release we will
673-
// alter the `DefaultPolicyBuilder`'s API so that it is impossible for the user to create such state.
674-
let preferences = match (self.preferred_datacenter, self.preferred_rack) {
675-
(None, None) => ReplicaLocationPreference::Any,
676-
(None, Some(_)) => {
677-
// This a is case that the user shouldn't be able to represent.
678-
warn!("Preferred rack has effect only if a preferred datacenter is set as well. Ignoring the preferred rack.");
679-
ReplicaLocationPreference::Any
680-
}
681-
(Some(datacenter), None) => ReplicaLocationPreference::Datacenter(datacenter),
682-
(Some(datacenter), Some(rack)) => {
683-
ReplicaLocationPreference::DatacenterAndRack(datacenter, rack)
684-
}
685-
};
686-
687669
Arc::new(DefaultPolicy {
688-
preferences,
670+
preferences: self.preferences,
689671
is_token_aware: self.is_token_aware,
690672
permit_dc_failover: self.permit_dc_failover,
691673
pick_predicate,
@@ -694,22 +676,28 @@ impl DefaultPolicyBuilder {
694676
})
695677
}
696678

697-
/// Sets the rack to be preferred by this policy
679+
/// Sets the datacenter to be preferred by this policy.
698680
///
699-
/// Allows the load balancing policy to prioritize nodes based on their availability zones
700-
/// in the preferred datacenter.
701-
/// When a preferred rack is set, the policy will first return replicas in the local rack
702-
/// in the preferred datacenter, and then the other replicas in the datacenter.
681+
/// Allows the load balancing policy to prioritize nodes based on their location.
682+
/// When a preferred datacenter is set, the policy will treat nodes in that
683+
/// datacenter as "local" nodes, and nodes in other datacenters as "remote" nodes.
684+
/// This affects the order in which nodes are returned by the policy when
685+
/// selecting replicas for read or write operations. If no preferred datacenter
686+
/// is specified, the policy will treat all nodes as local nodes.
703687
///
704-
/// When a preferred datacenter is not set, setting preferred rack will not have any effect.
705-
pub fn prefer_rack(mut self, rack_name: String) -> Self {
706-
self.preferred_rack = Some(rack_name);
688+
/// When datacenter failover is disabled (`permit_dc_failover` is set to false),
689+
/// the default policy will only include local nodes in load balancing plans.
690+
/// Remote nodes will be excluded, even if they are alive and available
691+
/// to serve requests.
692+
pub fn prefer_datacenter(mut self, datacenter_name: String) -> Self {
693+
self.preferences = ReplicaLocationPreference::Datacenter(datacenter_name);
707694
self
708695
}
709696

710-
/// Sets the datacenter to be preferred by this policy.
697+
/// Sets the datacenter and rack to be preferred by this policy.
711698
///
712-
/// Allows the load balancing policy to prioritize nodes based on their location.
699+
/// Allows the load balancing policy to prioritize nodes based on their location
700+
/// as well as their availability zones in the preferred datacenter.
713701
/// When a preferred datacenter is set, the policy will treat nodes in that
714702
/// datacenter as "local" nodes, and nodes in other datacenters as "remote" nodes.
715703
/// This affects the order in which nodes are returned by the policy when
@@ -720,8 +708,15 @@ impl DefaultPolicyBuilder {
720708
/// the default policy will only include local nodes in load balancing plans.
721709
/// Remote nodes will be excluded, even if they are alive and available
722710
/// to serve requests.
723-
pub fn prefer_datacenter(mut self, datacenter_name: String) -> Self {
724-
self.preferred_datacenter = Some(datacenter_name);
711+
///
712+
/// When a preferred rack is set, the policy will first return replicas in the local rack
713+
/// in the preferred datacenter, and then the other replicas in the datacenter.
714+
pub fn prefer_datacenter_and_rack(
715+
mut self,
716+
datacenter_name: String,
717+
rack_name: String,
718+
) -> Self {
719+
self.preferences = ReplicaLocationPreference::DatacenterAndRack(datacenter_name, rack_name);
725720
self
726721
}
727722

@@ -740,7 +735,7 @@ impl DefaultPolicyBuilder {
740735
/// In the case of `DefaultPolicy`, token awareness is enabled by default,
741736
/// meaning that the policy will prefer to return alive local replicas
742737
/// if the token is available. This means that if the client is requesting data
743-
/// that falls within the token range of a particular node, the policy will try\
738+
/// that falls within the token range of a particular node, the policy will try
744739
/// to route the request to that node first, assuming it is alive and responsive.
745740
///
746741
/// Token awareness can significantly improve the performance and scalability

0 commit comments

Comments
 (0)