1
1
//! Application-wide components in a struct accessible from each request
2
2
3
3
use crate :: config;
4
- use crate :: db:: { connection_url, ConnectionConfig , DieselPool , DieselPooledConn , PoolError } ;
4
+ use crate :: db:: { connection_url, ConnectionConfig } ;
5
5
use std:: ops:: Deref ;
6
6
use std:: sync:: atomic:: AtomicUsize ;
7
7
use std:: sync:: Arc ;
@@ -14,25 +14,17 @@ use axum::extract::{FromRef, FromRequestParts, State};
14
14
use crates_io_github:: GitHubClient ;
15
15
use deadpool_diesel:: postgres:: { Manager as DeadpoolManager , Pool as DeadpoolPool } ;
16
16
use deadpool_diesel:: Runtime ;
17
- use diesel:: r2d2;
18
17
use oauth2:: basic:: BasicClient ;
19
- use scheduled_thread_pool:: ScheduledThreadPool ;
20
18
21
19
type DeadpoolResult = Result < deadpool_diesel:: postgres:: Connection , deadpool_diesel:: PoolError > ;
22
20
23
21
/// The `App` struct holds the main components of the application like
24
22
/// the database connection pool and configurations
25
23
pub struct App {
26
- /// The primary database connection pool
27
- pub primary_database : DieselPool ,
28
-
29
24
/// Async database connection pool based on `deadpool` connected
30
25
/// to the primary database
31
26
pub deadpool_primary : DeadpoolPool ,
32
27
33
- /// The read-only replica database connection pool
34
- pub read_only_replica_database : Option < DieselPool > ,
35
-
36
28
/// Async database connection pool based on `deadpool` connected
37
29
/// to the read-only replica database
38
30
pub deadpool_replica : Option < DeadpoolPool > ,
@@ -88,32 +80,6 @@ impl App {
88
80
) ,
89
81
) ;
90
82
91
- let thread_pool = Arc :: new ( ScheduledThreadPool :: new ( config. db . helper_threads ) ) ;
92
-
93
- let primary_database = {
94
- let primary_db_connection_config = ConnectionConfig {
95
- statement_timeout : config. db . statement_timeout ,
96
- read_only : config. db . primary . read_only_mode ,
97
- } ;
98
-
99
- let primary_db_config = r2d2:: Pool :: builder ( )
100
- . max_size ( config. db . primary . pool_size )
101
- . min_idle ( config. db . primary . min_idle )
102
- . connection_timeout ( config. db . connection_timeout )
103
- . connection_customizer ( Box :: new ( primary_db_connection_config) )
104
- . thread_pool ( thread_pool. clone ( ) ) ;
105
-
106
- DieselPool :: new (
107
- & config. db . primary . url ,
108
- & config. db ,
109
- primary_db_config,
110
- instance_metrics
111
- . database_time_to_obtain_connection
112
- . with_label_values ( & [ "primary" ] ) ,
113
- )
114
- . unwrap ( )
115
- } ;
116
-
117
83
let primary_database_async = {
118
84
use secrecy:: ExposeSecret ;
119
85
@@ -134,34 +100,6 @@ impl App {
134
100
. unwrap ( )
135
101
} ;
136
102
137
- let replica_database = if let Some ( pool_config) = config. db . replica . as_ref ( ) {
138
- let replica_db_connection_config = ConnectionConfig {
139
- statement_timeout : config. db . statement_timeout ,
140
- read_only : pool_config. read_only_mode ,
141
- } ;
142
-
143
- let replica_db_config = r2d2:: Pool :: builder ( )
144
- . max_size ( pool_config. pool_size )
145
- . min_idle ( pool_config. min_idle )
146
- . connection_timeout ( config. db . connection_timeout )
147
- . connection_customizer ( Box :: new ( replica_db_connection_config) )
148
- . thread_pool ( thread_pool) ;
149
-
150
- Some (
151
- DieselPool :: new (
152
- & pool_config. url ,
153
- & config. db ,
154
- replica_db_config,
155
- instance_metrics
156
- . database_time_to_obtain_connection
157
- . with_label_values ( & [ "follower" ] ) ,
158
- )
159
- . unwrap ( ) ,
160
- )
161
- } else {
162
- None
163
- } ;
164
-
165
103
let replica_database_async = if let Some ( pool_config) = config. db . replica . as_ref ( ) {
166
104
use secrecy:: ExposeSecret ;
167
105
@@ -187,9 +125,7 @@ impl App {
187
125
} ;
188
126
189
127
App {
190
- primary_database,
191
128
deadpool_primary : primary_database_async,
192
- read_only_replica_database : replica_database,
193
129
deadpool_replica : replica_database_async,
194
130
github,
195
131
github_oauth,
@@ -208,48 +144,12 @@ impl App {
208
144
& self . config . session_key
209
145
}
210
146
211
- /// Obtain a read/write database connection from the primary pool
212
- #[ instrument( skip_all) ]
213
- pub fn db_write ( & self ) -> Result < DieselPooledConn , PoolError > {
214
- self . primary_database . get ( )
215
- }
216
-
217
147
/// Obtain a read/write database connection from the async primary pool
218
148
#[ instrument( skip_all) ]
219
149
pub async fn db_write_async ( & self ) -> DeadpoolResult {
220
150
self . deadpool_primary . get ( ) . await
221
151
}
222
152
223
- /// Obtain a readonly database connection from the replica pool
224
- ///
225
- /// If the replica pool is disabled or unavailable, the primary pool is used instead.
226
- #[ instrument( skip_all) ]
227
- pub fn db_read ( & self ) -> Result < DieselPooledConn , PoolError > {
228
- let Some ( read_only_pool) = self . read_only_replica_database . as_ref ( ) else {
229
- // Replica is disabled, but primary might be available
230
- return self . primary_database . get ( ) ;
231
- } ;
232
-
233
- match read_only_pool. get ( ) {
234
- // Replica is available
235
- Ok ( connection) => Ok ( connection) ,
236
-
237
- // Replica is not available, but primary might be available
238
- Err ( PoolError :: UnhealthyPool ) => {
239
- let _ = self
240
- . instance_metrics
241
- . database_fallback_used
242
- . get_metric_with_label_values ( & [ "follower" ] )
243
- . map ( |metric| metric. inc ( ) ) ;
244
-
245
- self . primary_database . get ( )
246
- }
247
-
248
- // Replica failed
249
- Err ( error) => Err ( error) ,
250
- }
251
- }
252
-
253
153
/// Obtain a readonly database connection from the replica pool
254
154
///
255
155
/// If the replica pool is disabled or unavailable, the primary pool is used instead.
@@ -281,35 +181,6 @@ impl App {
281
181
}
282
182
}
283
183
284
- /// Obtain a readonly database connection from the primary pool
285
- ///
286
- /// If the primary pool is unavailable, the replica pool is used instead, if not disabled.
287
- #[ instrument( skip_all) ]
288
- pub fn db_read_prefer_primary ( & self ) -> Result < DieselPooledConn , PoolError > {
289
- let Some ( read_only_pool) = self . read_only_replica_database . as_ref ( ) else {
290
- return self . primary_database . get ( ) ;
291
- } ;
292
-
293
- match self . primary_database . get ( ) {
294
- // Primary is available
295
- Ok ( connection) => Ok ( connection) ,
296
-
297
- // Primary is not available, but replica might be available
298
- Err ( PoolError :: UnhealthyPool ) => {
299
- let _ = self
300
- . instance_metrics
301
- . database_fallback_used
302
- . get_metric_with_label_values ( & [ "primary" ] )
303
- . map ( |metric| metric. inc ( ) ) ;
304
-
305
- read_only_pool. get ( )
306
- }
307
-
308
- // Primary failed
309
- Err ( error) => Err ( error) ,
310
- }
311
- }
312
-
313
184
/// Obtain a readonly database connection from the primary pool
314
185
///
315
186
/// If the primary pool is unavailable, the replica pool is used instead, if not disabled.
0 commit comments