Skip to content

Commit ce8b64b

Browse files
Make the scheduler aware of the new readyset status
Readyset is adding a new status for maintanance mode, this will change the fields of SHOW READYSET STATUS command. This commit makes the scheduler aware of the new status.
1 parent 672dc99 commit ce8b64b

File tree

2 files changed

+117
-47
lines changed

2 files changed

+117
-47
lines changed

src/hosts.rs

Lines changed: 92 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::time::Duration;
66
#[allow(dead_code)]
77
/// Defines the possible status of a host
88
#[derive(PartialEq, Clone, Copy)]
9-
pub enum HostStatus {
9+
pub enum ProxyStatus {
1010
/// backend server is fully operational
1111
Online,
1212
/// backend sever is temporarily taken out of use because of either too many connection errors in a time that was too short, or the replication lag exceeded the allowed threshold
@@ -17,25 +17,67 @@ pub enum HostStatus {
1717
OfflineHard,
1818
}
1919

20-
impl fmt::Display for HostStatus {
20+
impl fmt::Display for ProxyStatus {
2121
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2222
match self {
23-
HostStatus::Online => write!(f, "ONLINE"),
24-
HostStatus::Shunned => write!(f, "SHUNNED"),
25-
HostStatus::OfflineSoft => write!(f, "OFFLINE_SOFT"),
26-
HostStatus::OfflineHard => write!(f, "OFFLINE_HARD"),
23+
ProxyStatus::Online => write!(f, "ONLINE"),
24+
ProxyStatus::Shunned => write!(f, "SHUNNED"),
25+
ProxyStatus::OfflineSoft => write!(f, "OFFLINE_SOFT"),
26+
ProxyStatus::OfflineHard => write!(f, "OFFLINE_HARD"),
2727
}
2828
}
2929
}
3030

31-
impl From<String> for HostStatus {
31+
impl From<String> for ProxyStatus {
3232
fn from(s: String) -> Self {
3333
match s.to_uppercase().as_str() {
34-
"ONLINE" => HostStatus::Online,
35-
"SHUNNED" => HostStatus::Shunned,
36-
"OFFLINE_SOFT" => HostStatus::OfflineSoft,
37-
"OFFLINE_HARD" => HostStatus::OfflineHard,
38-
_ => HostStatus::Online,
34+
"ONLINE" => ProxyStatus::Online,
35+
"SHUNNED" => ProxyStatus::Shunned,
36+
"OFFLINE_SOFT" => ProxyStatus::OfflineSoft,
37+
"OFFLINE_HARD" => ProxyStatus::OfflineHard,
38+
_ => ProxyStatus::Online,
39+
}
40+
}
41+
}
42+
43+
impl From<ReadysetStatus> for ProxyStatus {
44+
fn from(status: ReadysetStatus) -> Self {
45+
match status {
46+
ReadysetStatus::Online => ProxyStatus::Online,
47+
ReadysetStatus::SnapshotInProgress => ProxyStatus::Shunned,
48+
ReadysetStatus::Maintenance => ProxyStatus::OfflineSoft,
49+
ReadysetStatus::Unknown => ProxyStatus::Shunned,
50+
}
51+
}
52+
}
53+
54+
#[derive(PartialEq, Clone, Copy)]
55+
56+
pub enum ReadysetStatus {
57+
Online,
58+
SnapshotInProgress,
59+
Maintenance,
60+
Unknown,
61+
}
62+
63+
impl fmt::Display for ReadysetStatus {
64+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65+
match self {
66+
ReadysetStatus::Online => write!(f, "Online"),
67+
ReadysetStatus::SnapshotInProgress => write!(f, "Snapshot in progress"),
68+
ReadysetStatus::Maintenance => write!(f, "Maintenance mode"),
69+
ReadysetStatus::Unknown => write!(f, "Unknown"),
70+
}
71+
}
72+
}
73+
74+
impl From<String> for ReadysetStatus {
75+
fn from(s: String) -> Self {
76+
match s.to_lowercase().as_str() {
77+
"online" => ReadysetStatus::Online,
78+
"snapshot in progress" => ReadysetStatus::SnapshotInProgress,
79+
"maintenance mode" => ReadysetStatus::Maintenance,
80+
_ => ReadysetStatus::Unknown,
3981
}
4082
}
4183
}
@@ -44,7 +86,8 @@ impl From<String> for HostStatus {
4486
pub struct Host {
4587
hostname: String,
4688
port: u16,
47-
status: HostStatus,
89+
proxysql_status: ProxyStatus,
90+
readyset_status: ReadysetStatus,
4891
conn: Option<Conn>,
4992
}
5093

@@ -62,7 +105,7 @@ impl Host {
62105
/// # Returns
63106
///
64107
/// A new `Host` instance.
65-
pub fn new(hostname: String, port: u16, status: String, config: &Config) -> Host {
108+
pub fn new(hostname: String, port: u16, proxysql_status: String, config: &Config) -> Host {
66109
let conn = match Conn::new(
67110
OptsBuilder::new()
68111
.ip_or_hostname(Some(hostname.clone()))
@@ -80,7 +123,8 @@ impl Host {
80123
return Host {
81124
hostname,
82125
port,
83-
status: HostStatus::from(status),
126+
proxysql_status: ProxyStatus::from(proxysql_status),
127+
readyset_status: ReadysetStatus::Unknown,
84128
conn: None,
85129
};
86130
}
@@ -89,7 +133,8 @@ impl Host {
89133
Host {
90134
hostname,
91135
port,
92-
status: HostStatus::from(status),
136+
proxysql_status: ProxyStatus::from(proxysql_status),
137+
readyset_status: ReadysetStatus::Unknown,
93138
conn: Some(conn),
94139
}
95140
}
@@ -112,31 +157,40 @@ impl Host {
112157
self.port
113158
}
114159

115-
/// Gets the status of the host.
160+
/// Gets the proxysql status of the host.
116161
///
117162
/// # Returns
118163
///
119164
/// The status of the host.
120-
pub fn get_status(&self) -> HostStatus {
121-
self.status
165+
pub fn get_proxysql_status(&self) -> ProxyStatus {
166+
self.proxysql_status
122167
}
123168

124-
/// Changes the status of the host.
169+
/// Changes the proxysql status of the host.
125170
///
126171
/// # Arguments
127172
///
128173
/// * `status` - The new status of the host.
129-
pub fn change_status(&mut self, status: HostStatus) {
130-
self.status = status;
174+
pub fn change_proxysqlstatus(&mut self, status: ProxyStatus) {
175+
self.proxysql_status = status;
131176
}
132177

133-
/// Checks if the host is online.
178+
/// Checks if the host is online in proxysql.
134179
///
135180
/// # Returns
136181
///
137182
/// true if the host is online, false otherwise.
138-
pub fn is_online(&self) -> bool {
139-
self.status == HostStatus::Online
183+
pub fn is_proxysql_online(&self) -> bool {
184+
self.proxysql_status == ProxyStatus::Online
185+
}
186+
187+
/// Gets the readyset status of the host.
188+
///
189+
/// # Returns
190+
///
191+
/// The status of the host.
192+
pub fn get_readyset_status(&self) -> ReadysetStatus {
193+
self.readyset_status
140194
}
141195

142196
/// Checks if the Readyset host is ready to serve traffic.
@@ -145,19 +199,28 @@ impl Host {
145199
/// # Returns
146200
///
147201
/// true if the host is ready, false otherwise.
148-
pub fn check_readyset_is_ready(&mut self) -> Result<bool, mysql::Error> {
202+
pub fn check_readyset_is_ready(&mut self) -> Result<ProxyStatus, mysql::Error> {
149203
match &mut self.conn {
150204
Some(conn) => {
151205
let result = conn.query("SHOW READYSET STATUS");
152206
match result {
153207
Ok(rows) => {
154208
let rows: Vec<(String, String)> = rows;
155209
for (field, value) in rows {
156-
if field == "Snapshot Status" {
157-
return Ok(value == "Completed");
210+
if field == "Snapshot Status" && value == "Completed" {
211+
self.readyset_status = ReadysetStatus::Online;
212+
return Ok(ProxyStatus::Online);
213+
} else if field == "Snapshot Status" && value == "In Progress" {
214+
self.readyset_status = ReadysetStatus::SnapshotInProgress;
215+
return Ok(ProxyStatus::Shunned);
216+
} else if field == "Status" {
217+
let status = ReadysetStatus::from(value);
218+
self.readyset_status = status;
219+
return Ok(status.into());
158220
}
159221
}
160-
Ok(false)
222+
self.readyset_status = ReadysetStatus::Unknown;
223+
Ok(ProxyStatus::Shunned)
161224
}
162225
Err(err) => Err(mysql::Error::IoError(std::io::Error::new(
163226
std::io::ErrorKind::Other,

src/proxysql.rs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use mysql::{prelude::Queryable, Conn, OptsBuilder};
33

44
use crate::{
55
config,
6-
hosts::{Host, HostStatus},
6+
hosts::{Host, ProxyStatus},
77
messages,
88
queries::Query,
99
};
@@ -40,7 +40,7 @@ impl ProxySQL {
4040
.expect("Failed to create ProxySQL connection");
4141

4242
let query = format!(
43-
"SELECT hostname, port, status, comment FROM mysql_servers WHERE hostgroup_id = {} AND status IN ('ONLINE', 'SHUNNED')",
43+
"SELECT hostname, port, status, comment FROM mysql_servers WHERE hostgroup_id = {} AND status IN ('ONLINE', 'SHUNNED', 'OFFLINE_SOFT')",
4444
config.readyset_hostgroup
4545
);
4646
let results: Vec<(String, u16, String, String)> = conn.query(query).unwrap();
@@ -176,23 +176,29 @@ impl ProxySQL {
176176

177177
for host in self.hosts.iter_mut() {
178178
match host.check_readyset_is_ready() {
179-
Ok(ready) => {
180-
if ready {
181-
status_changes.push((host, HostStatus::Online));
182-
} else {
183-
messages::print_note("Readyset is still running Snapshot.");
184-
status_changes.push((host, HostStatus::Shunned));
179+
Ok(ready) => match ready {
180+
ProxyStatus::Online => {
181+
status_changes.push((host, ProxyStatus::Online));
185182
}
186-
}
183+
ProxyStatus::Shunned => {
184+
status_changes.push((host, ProxyStatus::Shunned));
185+
}
186+
ProxyStatus::OfflineSoft => {
187+
status_changes.push((host, ProxyStatus::OfflineSoft));
188+
}
189+
ProxyStatus::OfflineHard => {
190+
status_changes.push((host, ProxyStatus::OfflineHard));
191+
}
192+
},
187193
Err(e) => {
188194
messages::print_error(format!("Cannot check Readyset status: {}.", e).as_str());
189-
status_changes.push((host, HostStatus::Shunned));
195+
status_changes.push((host, ProxyStatus::Shunned));
190196
}
191197
};
192198
}
193199

194200
for (host, status) in status_changes {
195-
if host.get_status() != status {
201+
if host.get_proxysql_status() != status {
196202
let where_clause = format!(
197203
"WHERE hostgroup_id = {} AND hostname = '{}' AND port = {}",
198204
self.readyset_hostgroup,
@@ -201,23 +207,24 @@ impl ProxySQL {
201207
);
202208
messages::print_note(
203209
format!(
204-
"Server HG: {}, Host: {}, Port: {} is currently {}. Changing to {}",
210+
"Server HG: {}, Host: {}, Port: {} is currently {} on proxysql and {} on readyset. Changing to {}",
205211
self.readyset_hostgroup,
206212
host.get_hostname(),
207213
host.get_port(),
208-
host.get_status(),
214+
host.get_proxysql_status(),
215+
host.get_readyset_status().to_string().to_uppercase(),
209216
status
210217
)
211218
.as_str(),
212219
);
213-
host.change_status(status);
220+
host.change_proxysqlstatus(status);
214221
if self.dry_run {
215222
messages::print_info("Dry run, skipping changes to ProxySQL");
216223
continue;
217224
}
218225
let _ = self.conn.query_drop(format!(
219226
"UPDATE mysql_servers SET status = '{}' {}",
220-
host.get_status(),
227+
host.get_proxysql_status(),
221228
where_clause
222229
));
223230
let _ = self.conn.query_drop("LOAD MYSQL SERVERS TO RUNTIME");
@@ -235,7 +242,7 @@ impl ProxySQL {
235242
pub fn number_of_online_hosts(&self) -> u16 {
236243
self.hosts
237244
.iter()
238-
.filter(|host| host.is_online())
245+
.filter(|host| host.is_proxysql_online())
239246
.collect::<Vec<&Host>>()
240247
.len() as u16
241248
}
@@ -247,7 +254,7 @@ impl ProxySQL {
247254
///
248255
/// An Option containing a reference to the first online host.
249256
pub fn get_first_online_host(&mut self) -> Option<&mut Host> {
250-
self.hosts.iter_mut().find(|host| host.is_online())
257+
self.hosts.iter_mut().find(|host| host.is_proxysql_online())
251258
}
252259

253260
/// This function is used to get all the online hosts.
@@ -259,7 +266,7 @@ impl ProxySQL {
259266
pub fn get_online_hosts(&mut self) -> Vec<&mut Host> {
260267
self.hosts
261268
.iter_mut()
262-
.filter(|host| host.is_online())
269+
.filter(|host| host.is_proxysql_online())
263270
.collect()
264271
}
265272
}

0 commit comments

Comments
 (0)