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

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.