Skip to content

Query hangs when max_size is greater than the current amount of idle connections #113

@SeanOMik

Description

@SeanOMik

I made a Manager for scylla and it worked great when I had the max_size set to the same amount as min_idle. Here's my implementation:

use bb8::ManageConnection;

use scylla::{Session, SessionBuilder, SessionConfig};
use scylla::transport::errors::{NewSessionError, QueryError};

use async_trait::async_trait;

use thiserror::Error; // TODO: Remove use for this

pub struct ScyllaManager {
    client_config: SessionConfig,
}

impl ScyllaManager {
    pub fn new (client_config: SessionConfig) -> ScyllaManager {
        ScyllaManager {
            client_config,
        }
    }
}

#[derive(Error, Debug)]
pub enum ScyllaR2D2Error{
    #[error("An error occurred while trying to create a new session")]
    NewSessionError(NewSessionError),
    #[error("An error occurred while trying to send a query")]
    QueryError(QueryError)
}

impl From<NewSessionError> for ScyllaR2D2Error {
    fn from(error: NewSessionError) -> Self {
        ScyllaR2D2Error::NewSessionError(error)
    }
}

impl From<QueryError> for ScyllaR2D2Error {
    fn from(error: QueryError) -> Self {
        ScyllaR2D2Error::QueryError(error)
    }
}

#[async_trait]
impl ManageConnection for ScyllaManager {
    type Connection = Session;
    type Error = ScyllaR2D2Error;

    async fn connect(&self) -> Result<Self::Connection, Self::Error> {
        let mut bld = SessionBuilder::new();
        bld.config = self.client_config.clone();

        Ok(futures::executor::block_on(bld.build())?)
    }

    async fn is_valid(&self, db: &mut bb8::PooledConnection<'_, Self>) -> Result<(), Self::Error> {
        match db.query("SELECT cql_version FROM system.local;", &[]).await {
            Ok(_) => {
                println!("Queried fine");
            },
            Err(e) => {
                println!("Query error: {}", e);

                return Err(ScyllaR2D2Error::QueryError(e));
            }
        }
        Ok(())
    }

    fn has_broken(&self, db: &mut Self::Connection) -> bool {
        // TODO
        false
    }
}

This is the pool configuration that causes issues (sorry for bad formatting)

    let cassandra_manager = bb8_scylla::ScyllaManager::new(cassandra_config);
    let db_pool = bb8::Pool::builder()
        .max_size(100)
        .min_idle(Some(15))
        .idle_timeout(Some(Duration::from_secs(900))) // 900 seconds = 15 minutes
        .connection_timeout(Duration::from_secs(10)) 
        .build(cassandra_manager)
        .await
        .unwrap();

The max_size and min_idle don't need to be that high, it can be set to something as low as 3 and 2 respectively and the issue still happens.

If you need any more information I'll be happy to provide. Thanks in advance!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions