Lines
83.33 %
Functions
71.43 %
Branches
100 %
//! A tenant connection that keeps its pool alive.
use crate::user::userpool::registry::TenantPool;
use sqlx::pool::PoolConnection;
use sqlx::{PgConnection, Postgres};
use std::ops::{Deref, DerefMut};
use std::sync::Arc;
/// A checked-out connection, holding the tenant pool it came from.
///
/// The anchor is what makes the residency bound true. A permit lives inside
/// [`TenantPool`] and is returned when the last handle drops, so handing back a
/// bare `PoolConnection` released the permit while the connection was still
/// open — sqlx keeps the pool alive behind the connection, so the process could
/// then admit a ninth resident pool and exceed the budget it claims to enforce.
/// Dereferences to [`PgConnection`], so `&mut *conn` and `&mut conn` reach an
/// executor exactly as they did before.
pub struct TenantConnection {
conn: PoolConnection<Postgres>,
/// `None` for the global/admin pool, which is bounded by its own cap rather
/// than by residency permits.
_anchor: Option<Arc<TenantPool>>,
}
impl TenantConnection {
/// Only the tenant-routing half builds these, and that half is excluded
/// from server's own `cfg(test)` runs.
#[cfg(not(test))]
pub(crate) const fn tenant(conn: PoolConnection<Postgres>, anchor: Arc<TenantPool>) -> Self {
Self {
conn,
_anchor: Some(anchor),
/// Only the test and `test-utils` arms of `User::get_connection` route a
/// global connection through the tenant type; production always has a pool.
#[cfg(any(test, feature = "test-utils"))]
pub(crate) const fn global(conn: PoolConnection<Postgres>) -> Self {
_anchor: None,
impl Deref for TenantConnection {
type Target = PgConnection;
fn deref(&self) -> &Self::Target {
&self.conn
impl DerefMut for TenantConnection {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.conn