Skip to main content

PoolProvider

Trait PoolProvider 

Source
pub trait PoolProvider:
    Clone
    + Send
    + Sync
    + 'static {
    // Required methods
    fn read(&self) -> &Pool<Postgres>;
    fn write(&self) -> &Pool<Postgres>;
}
Expand description

Trait for providing database pools with read/write routing.

Implementations can provide separate read and write pools for load distribution, or use a single pool for both operations.

§Thread Safety

Implementations must be Clone, Send, and Sync to work with async Rust and be shared across tasks.

§When to Use Each Method

§.read() - For Read Operations

Use for queries that:

  • Don’t modify data (SELECT without FOR UPDATE)
  • Can tolerate slight staleness (eventual consistency)
  • Benefit from load distribution

Examples: user listings, analytics, dashboards, search

§.write() - For Write Operations

Use for operations that:

  • Modify data (INSERT, UPDATE, DELETE)
  • Require transactions
  • Need locking reads (SELECT FOR UPDATE)
  • Require read-after-write consistency

Examples: creating records, updates, deletes, transactions

§Example Implementation

use sqlx::PgPool;
use sqlx_pool_router::PoolProvider;

#[derive(Clone)]
struct MyPools {
    primary: PgPool,
    replica: Option<PgPool>,
}

impl PoolProvider for MyPools {
    fn read(&self) -> &PgPool {
        self.replica.as_ref().unwrap_or(&self.primary)
    }

    fn write(&self) -> &PgPool {
        &self.primary
    }
}

Required Methods§

Source

fn read(&self) -> &Pool<Postgres>

Get a pool for read operations.

May return a read replica for load distribution, or fall back to the primary pool if no replica is configured.

Source

fn write(&self) -> &Pool<Postgres>

Get a pool for write operations.

Should always return the primary pool to ensure ACID guarantees and read-after-write consistency.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl PoolProvider for Pool<Postgres>

Implement PoolProvider for PgPool for backward compatibility.

This allows existing code using PgPool directly to work with generic code that accepts impl PoolProvider without any changes.

§Example

use sqlx::PgPool;
use sqlx_pool_router::PoolProvider;

async fn query_user<P: PoolProvider>(pools: &P, id: i64) -> Result<String, sqlx::Error> {
    sqlx::query_scalar("SELECT name FROM users WHERE id = $1")
        .bind(id)
        .fetch_one(pools.read())
        .await
}

let pool = PgPool::connect("postgresql://localhost/db").await?;

// Works with PgPool directly
let name = query_user(&pool, 1).await?;
Source§

fn read(&self) -> &Pool<Postgres>

Source§

fn write(&self) -> &Pool<Postgres>

Implementors§