Skip to main content

Pool

Trait Pool 

Source
pub trait Pool: Send + Sync {
    type Key: Debug + Send + Sync;
    type Connection: Connection;
    type Error: Error + From<<Self::Connection as Connection>::Error> + Into<Status> + Send + Sync;

    // Required method
    fn get_connection<'life0, 'async_trait>(
        &'life0 self,
        key: Self::Key,
    ) -> Pin<Box<dyn Future<Output = Result<Self::Connection, Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
}
Expand description

Connection pool behavior that can be customized across async pool implementations.

The key difference between a Pool and most other connection pools is the way new connections are accessed: by building connection logic around a Key that can be derived from a tonic::Request, all connection isolation and preparation can be handled internally to the pool. Furthermore, pools don’t have to be traditional pools, but can hand out shared access to a single Connection.

§Example:
use postgrpc::pools::{Pool, Connection};
use std::collections::BTreeMap;
use tokio::sync::RwLock;
use uuid::Uuid;
use tonic::Status;

// a simple connection wrapper
// (implementing postgrpc::Connection is an exercise for the reader)
#[derive(Clone)]
struct MyConnection(Arc<tokio_postgres::Client>);

// a toy pool wrapping a collection of tokio_postgres::Clients
// accessible by unique IDs that are provided by the caller
struct MyPool {
    connections: RwLock<BTreeMap<Uuid, MyConnection>>,
    config: tokio_postgres::config::Config
}

#[postgrpc::async_trait]
impl Pool for MyPool {
    type Key: Uuid;
    type Connection: MyConnection;
    type Error: Status;

    async fn get_connection(&self, key: Self::Key) -> Result<Self::Connection, Self::Error> {
        // get a connection from the pool or store one for later
        let connections = self.connections.read().await;

        match connections.get(&key) {
            Some(connection) => Ok(Arc::clone(connection.0)),
            None => {
                // drop the previous lock on the connections
                drop(connections);

                // connect to the database using the configuration
                let (client, connection) = self
                    .config
                    .connect(tokio_postgres::NoTls)
                    .map_error(|error| Status::internal(error.to_string()))?;

                // spawn the raw connection off onto an executor
                tokio::spawn(async move {
                    if let Err(error) = connection.await {
                        eprintln!("connection error: {}", error);
                    }
                });

                // store a reference to the connection for later
                let connection = MyConnection(Arc::new(client));
                self.connections.write().await.insert(key, connection);

                // return another reference to the connection for use
                Ok(connection)
            }
        }
    }
}

Required Associated Types§

Source

type Key: Debug + Send + Sync

The key by which connections are selected from the Pool, allowing for custom connection-fetching logic in Pool implementations

Source

type Connection: Connection

The underlying connection type returned from the Pool

Source

type Error: Error + From<<Self::Connection as Connection>::Error> + Into<Status> + Send + Sync

Errors related to fetching Connections from the Pool

Required Methods§

Source

fn get_connection<'life0, 'async_trait>( &'life0 self, key: Self::Key, ) -> Pin<Box<dyn Future<Output = Result<Self::Connection, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Get a single connection from the pool using some key

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§

Source§

impl Pool for postgrpc::pools::deadpool::Pool

Available on crate feature deadpool only.
Source§

impl<P> Pool for postgrpc::pools::transaction::Pool<P>
where P: Pool, P::Key: Hash + Eq + Send + Sync + Clone, P::Connection: 'static, <P::Connection as Connection>::Error: Send + Sync + Into<Status> + 'static,

Available on crate feature transaction only.