Skip to content

Add before_acquire passthrough and idle-ping shorthand to ConnectOptions#3143

Merged
tyt2y3 merged 1 commit into
masterfrom
before-acquire-idle-ping
Jul 23, 2026
Merged

Add before_acquire passthrough and idle-ping shorthand to ConnectOptions#3143
tyt2y3 merged 1 commit into
masterfrom
before-acquire-idle-ping

Conversation

@tyt2y3

@tyt2y3 tyt2y3 commented Jul 23, 2026

Copy link
Copy Markdown
Member

What

Adds first-class access to SQLx's before_acquire pool hook, plus a shorthand for the common "only ping stale connections" pattern. Previously before_acquire was reachable only through the raw map_sqlx_<db>_pool_opts escape hatch, where you had to hand-write the idle-ping logic and couldn't compose with anything SeaORM set.

API (all additive)

  • ConnectOptions::test_before_acquire_if_idle_for(Duration) — DB-agnostic shorthand. Pings a pooled connection before handing it out only once it has been idle for at least the given duration, instead of on every acquire (test_before_acquire). Calling it sets test_before_acquire(false).
  • map_sqlx_postgres_before_acquire / map_sqlx_mysql_before_acquire / map_sqlx_sqlite_before_acquire — per-backend passthrough of SQLx's before_acquire callback (per-DB because it operates on the raw &mut DB::Connection).
  • get_test_before_acquire / get_test_before_acquire_if_idle_for getters.

How it composes

SQLx's before_acquire slot replaces rather than composes and offers no getter to read it back, so when both the shorthand and a user callback are set they cannot be combined by the caller. A generic ConnectOptions::apply_before_acquire<DB> helper composes them into one closure — idle-ping first, then the user callback — and is called once per driver with that backend's concrete callback. When neither option is set it returns the pool options untouched, so pools built by existing users are byte-for-byte unchanged.

The shorthand alone reduces exactly to:

opts.test_before_acquire(false).before_acquire(|conn, meta| Box::pin(async move {
    if meta.idle_for >= threshold { conn.ping().await?; }
    Ok(true)
}))

Non-breaking

No existing signature, default, or behavior is changed, renamed, or removed. The per-driver insertion is a no-op unless the new options are opted into.

Limitations

Applies only to pools built via Database::connect. The from_sqlx_<db>_pool constructors adopt a pre-built pool and bypass ConnectOptions entirely; configure before_acquire on your own PoolOptions there.

Tests

  • Three deterministic construction/composition unit tests in sqlx_common.rs (gated to sqlx-postgres).
  • Two doctests on the new methods.
  • Verified compiling under sqlx-postgres, sqlx-mysql, sqlx-sqlite, sqlx-all, and --no-default-features; clippy and rustfmt clean on the changed files.

Expose SQLx's `before_acquire` pool hook, which SeaORM previously only
reachable through the raw `map_sqlx_<db>_pool_opts` escape hatch.

- `test_before_acquire_if_idle_for(Duration)`: DB-agnostic shorthand that
  pings a pooled connection before handing it out only once it has been idle
  for at least the given duration, instead of on every acquire. Sets
  `test_before_acquire(false)`.
- `map_sqlx_{postgres,mysql,sqlite}_before_acquire`: per-backend passthrough of
  SQLx's `before_acquire` callback.
- `get_test_before_acquire` / `get_test_before_acquire_if_idle_for` getters.

Because SQLx's single `before_acquire` slot replaces rather than composes and
has no getter, a generic `apply_before_acquire` helper composes the idle-ping
shorthand with any user-provided callback into one closure (idle-ping first,
then the user callback). The helper returns the pool options untouched when
neither option is set, so existing behavior is unchanged.

Purely additive: no existing signature, default, or behavior is changed.
@tyt2y3
tyt2y3 merged commit d612926 into master Jul 23, 2026
39 checks passed
@tyt2y3
tyt2y3 deleted the before-acquire-idle-ping branch July 23, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant