djc/bb8

A full-featured connection pool, designed for asynchronous connections (using

Opening a new database connection every time one is needed is both inefficient

bb8

tokio). Originally based on r2d2.

and can lead to resource exhaustion under high traffic conditions. A connection pool maintains a set of open connections to a database, handing them out for repeated use.

bb8 is agnostic to the connection type it is managing. Implementors of the ManageConnection trait provide the database-specific logic to create and check the health of connections.

A (possibly not exhaustive) list of adapters for different backends:

Backend Adapter Crate
tokio-postgres bb8-postgres (in-tree)
redis bb8-redis (in-tree)
rsmq rsmq_async
bolt-client bb8-bolt
diesel bb8-diesel
tiberius bb8-tiberius
nebula-client bb8-nebula
memcache-async bb8-memcached
lapin bb8-lapin

Example

Using an imaginary "foodb" database.

fn main() {
    let manager = bb8_foodb::FooConnectionManager::new("localhost:1234");
    let pool = bb8::Pool::builder()
        .max_size(15)
        .build(manager)
        .unwrap();

    for _ in 0..20 {
        let pool = pool.clone();
        tokio::spawn(move || {
            let conn = pool.get().await.unwrap();
            // use the connection
            // it will be returned to the pool when it falls out of scope.
        })
    }
}

License

Licensed under the MIT license (LICENSE).

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be licensed as above, without any additional terms or conditions.

Issues

Collection of the latest Issues

SeanOMik

SeanOMik

Comment Icon2

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:

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

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!

mu-arch

mu-arch

Comment Icon2

I have the following code:

I want to prepare a number of queries using this for every connection. However, I'm struggling to think of a way to actually get the reference to the prepared statements for a specific connection. Is there a way to bind some data to the connection object, or at least a way to get some unique identifier for a connection that I could use to lookup their prepared statements in a hash table?

marcbowes

marcbowes

Comment Icon10

If a user incorrectly specifies their connection setting (e.g. typos the IP address), then bb8's get method will hit errors and retry until the timeout. Is there a way of marking certain errors as "just give up"?

jakajancar

jakajancar

Comment Icon5

Would be nice if bb8-postgres supported calling DISCARD ALL after the connection is returned to the pool, so it's guaranteed to be "pristine" on the next checkout.

Unless I'm missing something, there isn't even a "post check-in" hook in bb8 right now, only test_on_check_out. I suppose that could be used, but the best is to do it early, release the resources (e.g. UNLISTEN) and reduce the latency on checkout (assuming test_on_checkout is false).

sync

sync

Comment Icon6

First of all thank you for the recent update to bb8 :-)

I can never turn a conn in into a pubsub connection calling into_pubsub for some reason. Have you had a chance to have a look pubsub with redis ?

From redis

ufoscout

ufoscout

Comment Icon2

Hi,

this issue is conceptually linked to https://github.com/sfackler/r2d2-postgres/issues/19

The problem is related to the fact that the PostgresConnectionManager<T> struct has a generic parameter <T>. If <T> is known at compile-time, then there are no problems; on the contrary, if it is only known at runtime then it has to be redeclared and propagated in every place where the connection and/or the Pool is used.

As already shown in https://github.com/sfackler/r2d2-postgres/issues/19 , it is possible to slightly alter the PostgresConnectionManager struct implementation to remove the generic T and making the pool more ergonomic to use.

If you think it is not feasible, would you at least mind to provide both the alternatives of the PostgresConnectionManager, one with and one without the generic param?

stoksc

stoksc

Comment Icon5

Maybe I'm wrong here, but the way I see to prepare statements currently, you would call prepare, get back the statement and use it. I don't see, eyeing the code, that tokio-postgres will do any smart persistence of the prepared statements and not reprepare them until needed (like npgsql for c# for example).

I feel like adding this functionality into bb8 wouldn't be too hard. Potentially the user could specify statements in something like bb8_postgres::PostgresConnectionManager::new_with_prepared, bb8_postgres::PostgresConnectionManager::connect could prepare the statements and populate them into a custom type Connection (that's just a wrapper around the tokio_postgres::Client) in the ManageConnection impl that allows the user to access them.

Any thoughts?

elpiel

elpiel

Comment Icon9

Hello, I'm trying to make a transaction, but I am hitting a wall and can't figure it out.

Is it possible for an example with transaction and 2 inserts for example?

Versions

Find the latest versions by id

v0.7.0 - Dec 27, 2020

This release updates tokio to 1.0. Additionally, it contains one additional feature:

  • Allow customization of connections after connecting (#89, thanks to @agersant)

I simultaneously published bb8-postgres 0.7.0 and bb8-redis 0.8.0. This branch is most likely to get bug fixes and additional features. The 0.5.x branch (tokio 0.2) and 0.6.x branch (tokio 0.3) will probably get less maintenance, depending on the uptake of tokio 1.

v0.6.2 - Dec 27, 2020

This is a bug fix release for the 0.6.x line (based on tokio 0.3). It fixes an issue where pools configured with a maximum size could get stuck in case futures were cancelled before completion. Thanks to @lassipulkkinen for reporting the issue (in #67) and creating a minimal reproduction which led me to the fix in #91.

v0.5.2 - Dec 27, 2020

This is a bug fix release for the 0.5.x line (based on tokio 0.2). It fixes an issue where pools configured with a maximum size could get stuck in case futures were cancelled before completion. Thanks to @lassipulkkinen for reporting the issue (in #67) and creating a minimal reproduction which led me to the fix in #91.

v0.6.0 - Nov 16, 2020

Hot on the heels of yesterday's 0.5.0 release, I've just released 0.6.0. These are the only functional changes:

  • Update to tokio 0.3
  • Enable tokio's parking_lot feature, since bb8 depends on parking_lot anyway

For now, there is no bb8-redis 0.6 release, since there is no tokio 0.3-compatible version of the redis crate yet.

As a reminder, depending on the uptake of tokio 0.3.0 in the ecosystem, I will maintain both of these releases for a while; most features and bug fixes, for the foreseeable future, will be made against both branches.

v0.5.0 - Nov 15, 2020

After 7 months, there is finally a new release of bb8, the fully-featured connection pool for (tokio-based) async connections. This release took a while due to issues with hanging connections (described in #67), where some recent fixes appear to have solved the reported issues. While this release depends on tokio 0.2, I will release a 0.6 set of releases soon which relies on tokio 0.3 instead (update: released). Maintenance of the 0.5 branch will continue for a while, depending on the uptake of tokio 0.3 in the ecosystem.

Breaking changes:

  • ConnectionManager::is_valid() now takes a &mut PooledConnection<'_, M::Connection>
  • The run() method was removed in favor of the more ergonomic get() method

Other changes:

  • Switch to blocking parking_lot::Mutex instead of tokio's async Mutex (fixes #74)
  • Add basic documentation (#62, thanks to @pksunkara)
  • Reduced dependencies
  • bb8-redis: disable default features in redis dependency (#77, thanks to @x04)
  • The State type became non-exhaustive
  • The internal structure has been substantially reworked to make it easier to reason about

v0.4.0 - Jan 17, 2020

bb8 is an r2d2-like connection pooling solution for the async/await world. This is the first release from a new maintainer: since @khuey doesn't have much time, @djc has become the primary maintainer.

  • Migrate to tokio 0.2, std::future::Future and async/await
  • Upgrade to tokio-postgres 0.5 and redis 0.15
  • Add a guard-based get() API (thanks to @elpiel)
  • Retry connection establishment on failure (thanks to @bbigras for contributing a test case)

Any feedback is welcome, please file any issues you may have including comments on (lack of) documentation, example code that would help you work with this projects, and of course any bugs.

Information - Updated Feb 25, 2022

Stars: 402
Forks: 70
Issues: 11

Repositories & Extras

influxdb provides an asynchronous Rust interface to an InfluxDB database

influxdb provides an asynchronous Rust interface to an Integer 32, sponsored by Stephan Buys of

influxdb provides an asynchronous Rust interface to an InfluxDB database

Bollard: an asynchronous rust client library for the docker API

Bollard leverages the latest Tokio improvements for an asynchronous API containing

Bollard: an asynchronous rust client library for the docker API

A library providing asynchronous, multiplexed tailing for (namely log) files

Also available is the underlying file event-stream (driven by MIT license (LICENSE-MIT or

A library providing asynchronous, multiplexed tailing for (namely log) files

Hitbox is an asynchronous caching framework supporting multiple backends and suitable

for distributed and for single-machine applications

Hitbox is an asynchronous caching framework supporting multiple backends and suitable

Aleph is an asynchronous and Byzantine fault tolerant consensus protocol aimed

This repository contains a Rust implementation of AlephBFT that offers a convenient

Aleph is an asynchronous and Byzantine fault tolerant consensus protocol aimed

Tokio-based asynchronous filesystems library using 9P2000

L protocol, an extended variant of 9P from Plan 9

Tokio-based asynchronous filesystems library using 9P2000

Asynchronous-Rust Remote Control for SCI Hipot testers

As the name would imply, this is a library for controlling

Asynchronous-Rust Remote Control for SCI Hipot testers

Astra is a synchronous HTTP server built on top of hyper

Astra is a synchronous HTTP server built on top of http2_keep_alive_while_idle, are not supported

Astra is a synchronous HTTP server built on top of hyper

Asynchronous File Fetcher

This library provides an async service that can fetch multiple files concurrently, with multiple concurrent connections per file

Asynchronous File Fetcher

A simple asynchronous server/client crate built

on tokio for easy two-way streaming

A simple asynchronous server/client crate built
Facebook Instagram Twitter GitHub Dribbble
Privacy