Skip to content

adbc: ADBC connect() blocks the async runtime on r2d2::Pool::get() #672

Description

@ewgenius

ADBCPool::connect is an async fn but calls r2d2::Pool::get() directly on the async executor. get() is synchronous and may block indefinitely when the pool is exhausted or while opening a new connection.

async fn connect(
&self,
) -> Result<Box<dyn DbConnection<r2d2::PooledConnection<AdbcConnectionManager<D>>, RecordBatch>>>
{
let pool = Arc::clone(&self.pool);
let conn: r2d2::PooledConnection<AdbcConnectionManager<D>> =
pool.get().context(ConnectionPoolSnafu)?;
Ok(Box::new(AdbcDbConnection::new(conn)))
}

When many callers await connect() concurrently (e.g. during parallel table/schema initialization in a host runtime), waiters block Tokio worker threads instead of yielding. That can stall unrelated async work on the same runtime, including health checks and other I/O.

Expected: blocking pool acquisition should run off the async executor (e.g. tokio::task::spawn_blocking) so connect().await yields while waiting for a connection.

Actual: pool.get() runs inline in the async task, blocking the executor thread until a connection is available.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions