@@ -34,23 +34,19 @@ impl ConnectionManager {
34
34
pub ( crate ) fn get_pool ( & self , settings : & DatabaseSettings ) -> Option < PgPool > {
35
35
let key = ConnectionKey :: from ( settings) ;
36
36
37
- // Cleanup idle connections first
38
- self . cleanup_idle_pools ( & key) ;
39
-
40
37
if !settings. enable_connection {
41
38
tracing:: info!( "Database connection disabled." ) ;
42
39
return None ;
43
40
}
44
41
45
- // Try read lock first for cache hit
46
- if let Ok ( pools) = self . pools . read ( ) {
47
- if let Some ( cached_pool) = pools. get ( & key) {
48
- // Can't update last_accessed with read lock, but that's okay for occasional misses
49
- return Some ( cached_pool . pool . clone ( ) ) ;
42
+ {
43
+ if let Ok ( pools) = self . pools . read ( ) {
44
+ if let Some ( cached_pool) = pools. get ( & key) {
45
+ return Some ( cached_pool . pool . clone ( ) ) ;
46
+ }
50
47
}
51
48
}
52
49
53
- // Cache miss or need to update timestamp - use write lock
54
50
let mut pools = self . pools . write ( ) . unwrap ( ) ;
55
51
56
52
// Double-check after acquiring write lock
@@ -59,6 +55,21 @@ impl ConnectionManager {
59
55
return Some ( cached_pool. pool . clone ( ) ) ;
60
56
}
61
57
58
+ // Clean up idle connections before creating new ones to avoid unbounded growth
59
+ let now = Instant :: now ( ) ;
60
+ pools. retain ( |k, cached_pool| {
61
+ let idle_duration = now. duration_since ( cached_pool. last_accessed ) ;
62
+ if idle_duration > cached_pool. idle_timeout && k != & key {
63
+ tracing:: debug!(
64
+ "Removing idle database connection (idle for {:?})" ,
65
+ idle_duration
66
+ ) ;
67
+ false
68
+ } else {
69
+ true
70
+ }
71
+ } ) ;
72
+
62
73
// Create a new pool
63
74
let config = PgConnectOptions :: new ( )
64
75
. host ( & settings. host )
@@ -85,25 +96,4 @@ impl ConnectionManager {
85
96
86
97
Some ( pool)
87
98
}
88
-
89
- /// Remove pools that haven't been accessed for longer than the idle timeout
90
- fn cleanup_idle_pools ( & self , ignore_key : & ConnectionKey ) {
91
- let now = Instant :: now ( ) ;
92
-
93
- let mut pools = self . pools . write ( ) . unwrap ( ) ;
94
-
95
- // Use retain to keep only non-idle connections
96
- pools. retain ( |key, cached_pool| {
97
- let idle_duration = now. duration_since ( cached_pool. last_accessed ) ;
98
- if idle_duration > cached_pool. idle_timeout && key != ignore_key {
99
- tracing:: debug!(
100
- "Removing idle database connection (idle for {:?})" ,
101
- idle_duration
102
- ) ;
103
- false
104
- } else {
105
- true
106
- }
107
- } ) ;
108
- }
109
99
}
0 commit comments