Skip to content

Commit 8209633

Browse files
committed
pool fixes
1 parent daf120a commit 8209633

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ async fn main() {
7373
"> Healthcheck timeout: {}ms",
7474
config.general.healthcheck_timeout
7575
);
76+
println!("> Connection timeout: {}ms", config.general.connect_timeout);
7677

7778
let pool = ConnectionPool::from_config(config.clone(), client_server_map.clone()).await;
7879
let transaction_mode = config.general.pool_mode == "transaction";

src/pool.rs

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub struct ConnectionPool {
2626
banlist: BanList,
2727
healthcheck_timeout: u64,
2828
ban_time: i64,
29+
pool_size: u32,
2930
}
3031

3132
impl ConnectionPool {
@@ -96,6 +97,7 @@ impl ConnectionPool {
9697
banlist: Arc::new(Mutex::new(banlist)),
9798
healthcheck_timeout: config.general.healthcheck_timeout,
9899
ban_time: config.general.ban_time,
100+
pool_size: config.general.pool_size,
99101
}
100102
}
101103

@@ -115,12 +117,29 @@ impl ConnectionPool {
115117

116118
let mut allowed_attempts = match role {
117119
// Primary-specific queries get one attempt, if the primary is down,
118-
// nothing we can do.
119-
Some(Role::Primary) => 1,
120+
// nothing we should do about it I think. It's dangerous to retry
121+
// write queries.
122+
Some(Role::Primary) => {
123+
// Make sure we have a primary in the pool configured.
124+
let primary_present = self.addresses[shard]
125+
.iter()
126+
.filter(|&db| db.role == Role::Primary)
127+
.count();
128+
129+
// TODO: return this error to the client, so people don't have to look in
130+
// the logs to figure out what happened.
131+
if primary_present == 0 {
132+
println!(">> Error: Primary requested but none are configured.");
133+
return Err(Error::AllServersDown);
134+
}
135+
136+
// Primary gets one attempt.
137+
1
138+
}
120139

121-
// Replicas get to try as many times as there are replicas.
122-
Some(Role::Replica) => self.databases[shard].len(),
123-
None => self.databases[shard].len(),
140+
// Replicas get to try as many times as there are replicas
141+
// and connections in the pool.
142+
_ => self.databases[shard].len() * self.pool_size as usize,
124143
};
125144

126145
while allowed_attempts > 0 {
@@ -184,6 +203,9 @@ impl ConnectionPool {
184203
">> Banning replica {} because of failed health check",
185204
index
186205
);
206+
// Don't leave a bad connection in the pool.
207+
server.mark_bad();
208+
187209
self.ban(&address, shard);
188210
continue;
189211
}
@@ -194,6 +216,9 @@ impl ConnectionPool {
194216
">> Banning replica {} because of health check timeout",
195217
index
196218
);
219+
// Don't leave a bad connection in the pool.
220+
server.mark_bad();
221+
197222
self.ban(&address, shard);
198223
continue;
199224
}

0 commit comments

Comments
 (0)