@@ -26,6 +26,7 @@ pub struct ConnectionPool {
26
26
banlist : BanList ,
27
27
healthcheck_timeout : u64 ,
28
28
ban_time : i64 ,
29
+ pool_size : u32 ,
29
30
}
30
31
31
32
impl ConnectionPool {
@@ -96,6 +97,7 @@ impl ConnectionPool {
96
97
banlist : Arc :: new ( Mutex :: new ( banlist) ) ,
97
98
healthcheck_timeout : config. general . healthcheck_timeout ,
98
99
ban_time : config. general . ban_time ,
100
+ pool_size : config. general . pool_size ,
99
101
}
100
102
}
101
103
@@ -115,12 +117,29 @@ impl ConnectionPool {
115
117
116
118
let mut allowed_attempts = match role {
117
119
// 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
+ }
120
139
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 ,
124
143
} ;
125
144
126
145
while allowed_attempts > 0 {
@@ -184,6 +203,9 @@ impl ConnectionPool {
184
203
">> Banning replica {} because of failed health check" ,
185
204
index
186
205
) ;
206
+ // Don't leave a bad connection in the pool.
207
+ server. mark_bad ( ) ;
208
+
187
209
self . ban ( & address, shard) ;
188
210
continue ;
189
211
}
@@ -194,6 +216,9 @@ impl ConnectionPool {
194
216
">> Banning replica {} because of health check timeout" ,
195
217
index
196
218
) ;
219
+ // Don't leave a bad connection in the pool.
220
+ server. mark_bad ( ) ;
221
+
197
222
self . ban ( & address, shard) ;
198
223
continue ;
199
224
}
0 commit comments