Skip to content

Commit d671b98

Browse files
committed
fix(pool): tweaks and fixes
1 parent 80831e8 commit d671b98

File tree

5 files changed

+40
-31
lines changed

5 files changed

+40
-31
lines changed

sqlx-core/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pin-project-lite = "0.2.14"
8585

8686
[dev-dependencies]
8787
sqlx = { workspace = true, features = ["postgres", "sqlite", "mysql", "migrate", "macros", "time", "uuid"] }
88-
tokio = { version = "1", features = ["rt"] }
88+
tokio = { version = "1", features = ["rt", "sync"] }
8989

9090
[lints]
9191
workspace = true

sqlx-core/src/pool/connect.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::pool::PoolConnection;
66
use crate::rt::JoinHandle;
77
use crate::Error;
88
use ease_off::EaseOff;
9-
use event_listener::Event;
9+
use event_listener::{listener, Event};
1010
use std::fmt::{Display, Formatter};
1111
use std::future::Future;
1212
use std::ptr;
@@ -50,7 +50,7 @@ use std::io;
5050
/// let database_url = database_url.clone();
5151
/// async move {
5252
/// println!(
53-
/// "opening connection {}, attempt {}; elapsed time: {}",
53+
/// "opening connection {}, attempt {}; elapsed time: {:?}",
5454
/// meta.pool_size,
5555
/// meta.num_attempts + 1,
5656
/// meta.start.elapsed()
@@ -96,10 +96,10 @@ use std::io;
9696
///
9797
/// let pool = PgPoolOptions::new()
9898
/// .connect_with_connector(move |meta: PoolConnectMetadata| {
99-
/// let connect_opts_ = connect_opts.clone();
99+
/// let connect_opts = connect_opts_.clone();
100100
/// async move {
101101
/// println!(
102-
/// "opening connection {}, attempt {}; elapsed time: {}",
102+
/// "opening connection {}, attempt {}; elapsed time: {:?}",
103103
/// meta.pool_size,
104104
/// meta.num_attempts + 1,
105105
/// meta.start.elapsed()
@@ -318,7 +318,8 @@ impl ConnectionCounter {
318318

319319
pub async fn drain(&self) {
320320
while self.count.load(Ordering::Acquire) > 0 {
321-
self.connect_available.listen().await;
321+
listener!(self.connect_available => permit_released);
322+
permit_released.await;
322323
}
323324
}
324325

@@ -386,13 +387,14 @@ impl ConnectionCounter {
386387
return acquired;
387388
}
388389

389-
self.connect_available.listen().await;
390-
391390
if attempt == 2 {
392391
tracing::warn!(
393392
"unable to acquire a connect permit after sleeping; this may indicate a bug"
394393
);
395394
}
395+
396+
listener!(self.connect_available => connect_available);
397+
connect_available.await;
396398
}
397399

398400
panic!("BUG: was never able to acquire a connection despite waking many times")

sqlx-core/src/pool/idle.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use futures_util::FutureExt;
88
use std::sync::atomic::{AtomicUsize, Ordering};
99
use std::sync::Arc;
1010

11+
use event_listener::listener;
12+
1113
pub struct IdleQueue<DB: Database> {
1214
queue: ArrayQueue<Idle<DB>>,
1315
// Keep a separate count because `ArrayQueue::len()` loops until the head and tail pointers
@@ -36,7 +38,8 @@ impl<DB: Database> IdleQueue<DB> {
3638

3739
for attempt in 1usize.. {
3840
if should_wait {
39-
self.release_event.listen().await;
41+
listener!(self.release_event => release_event);
42+
release_event.await;
4043
}
4144

4245
if let Some(conn) = self.try_acquire(pool) {

sqlx-core/src/pool/inner.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::rt::JoinHandle;
1717
use crate::{private_tracing_dynamic_event, rt};
1818
use either::Either;
1919
use futures_util::future::{self, OptionFuture};
20-
use futures_util::{select, FutureExt};
20+
use futures_util::{FutureExt};
2121
use std::time::{Duration, Instant};
2222
use tracing::Level;
2323

@@ -77,14 +77,19 @@ impl<DB: Database> PoolInner<DB> {
7777

7878
// Keep clearing the idle queue as connections are released until the count reaches zero.
7979
async move {
80-
let mut drained = pin!(self.counter.drain()).fuse();
80+
let mut drained = pin!(self.counter.drain());
8181

8282
loop {
83-
select! {
84-
idle = self.idle.acquire(self) => {
83+
let mut acquire_idle = pin!(self.idle.acquire(self));
84+
85+
// Not using `futures::select!{}` here because it requires a proc-macro dep,
86+
// and frankly it's a little broken.
87+
match future::select(drained.as_mut(), acquire_idle.as_mut()).await {
88+
// *not* `either::Either`; they rolled their own
89+
future::Either::Left(_) => break,
90+
future::Either::Right((idle, _)) => {
8591
idle.close().await;
86-
},
87-
() = drained.as_mut() => break,
92+
}
8893
}
8994
}
9095
}

sqlx-core/src/raw_sql.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ pub struct RawSql<'q>(&'q str);
114114
///
115115
/// See [MySQL manual, section 13.3.3: Statements That Cause an Implicit Commit](https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html) for details.
116116
/// See also: [MariaDB manual: SQL statements That Cause an Implicit Commit](https://mariadb.com/kb/en/sql-statements-that-cause-an-implicit-commit/).
117-
pub fn raw_sql(sql: &str) -> RawSql<'_> {
117+
pub fn raw_sql<'q>(sql: &'q str) -> RawSql<'q> {
118118
RawSql(sql)
119119
}
120120

@@ -138,27 +138,26 @@ impl<'q, DB: Database> Execute<'q, DB> for RawSql<'q> {
138138

139139
impl<'q> RawSql<'q> {
140140
/// Execute the SQL string and return the total number of rows affected.
141-
#[inline]
142-
pub async fn execute<'e, E>(
141+
pub async fn execute<'e, 'c: 'e, E>(
143142
self,
144143
executor: E,
145144
) -> crate::Result<<E::Database as Database>::QueryResult>
146145
where
147146
'q: 'e,
148-
E: Executor<'e>,
147+
E: Executor<'c>,
149148
{
150149
executor.execute(self).await
151150
}
152151

153152
/// Execute the SQL string. Returns a stream which gives the number of rows affected for each statement in the string.
154153
#[inline]
155-
pub fn execute_many<'e, E>(
154+
pub fn execute_many<'e, 'c: 'e, E>(
156155
self,
157156
executor: E,
158157
) -> BoxStream<'e, crate::Result<<E::Database as Database>::QueryResult>>
159158
where
160159
'q: 'e,
161-
E: Executor<'e>,
160+
E: Executor<'c>,
162161
{
163162
executor.execute_many(self)
164163
}
@@ -167,13 +166,13 @@ impl<'q> RawSql<'q> {
167166
///
168167
/// If the string contains multiple statements, their results will be concatenated together.
169168
#[inline]
170-
pub fn fetch<'e, E>(
169+
pub fn fetch<'e, 'c: 'e, E>(
171170
self,
172171
executor: E,
173172
) -> BoxStream<'e, Result<<E::Database as Database>::Row, Error>>
174173
where
175174
'q: 'e,
176-
E: Executor<'e>,
175+
E: Executor<'c>,
177176
{
178177
executor.fetch(self)
179178
}
@@ -183,7 +182,7 @@ impl<'q> RawSql<'q> {
183182
/// For each query in the stream, any generated rows are returned first,
184183
/// then the `QueryResult` with the number of rows affected.
185184
#[inline]
186-
pub fn fetch_many<'e, E>(
185+
pub fn fetch_many<'e, 'c: 'e, E>(
187186
self,
188187
executor: E,
189188
) -> BoxStream<
@@ -195,7 +194,7 @@ impl<'q> RawSql<'q> {
195194
>
196195
where
197196
'q: 'e,
198-
E: Executor<'e>,
197+
E: Executor<'c>,
199198
{
200199
executor.fetch_many(self)
201200
}
@@ -208,13 +207,13 @@ impl<'q> RawSql<'q> {
208207
/// To avoid exhausting available memory, ensure the result set has a known upper bound,
209208
/// e.g. using `LIMIT`.
210209
#[inline]
211-
pub async fn fetch_all<'e, E>(
210+
pub async fn fetch_all<'e, 'c: 'e, E>(
212211
self,
213212
executor: E,
214213
) -> crate::Result<Vec<<E::Database as Database>::Row>>
215214
where
216215
'q: 'e,
217-
E: Executor<'e>,
216+
E: Executor<'c>,
218217
{
219218
executor.fetch_all(self).await
220219
}
@@ -232,13 +231,13 @@ impl<'q> RawSql<'q> {
232231
///
233232
/// Otherwise, you might want to add `LIMIT 1` to your query.
234233
#[inline]
235-
pub async fn fetch_one<'e, E>(
234+
pub async fn fetch_one<'e, 'c: 'e, E>(
236235
self,
237236
executor: E,
238237
) -> crate::Result<<E::Database as Database>::Row>
239238
where
240239
'q: 'e,
241-
E: Executor<'e>,
240+
E: Executor<'c>,
242241
{
243242
executor.fetch_one(self).await
244243
}
@@ -256,13 +255,13 @@ impl<'q> RawSql<'q> {
256255
///
257256
/// Otherwise, you might want to add `LIMIT 1` to your query.
258257
#[inline]
259-
pub async fn fetch_optional<'e, E>(
258+
pub async fn fetch_optional<'e, 'c: 'e, E>(
260259
self,
261260
executor: E,
262261
) -> crate::Result<<E::Database as Database>::Row>
263262
where
264263
'q: 'e,
265-
E: Executor<'e>,
264+
E: Executor<'c>,
266265
{
267266
executor.fetch_one(self).await
268267
}

0 commit comments

Comments
 (0)