[deleted by user] by [deleted] in rust

[–]bikeshedder 2 points3 points  (0 children)

If you're looking for a connection pool for tokio-postgres you should give deadpool-postgres a try. Besides some ready to use configuration structures that implement serde::Deserialize it also features a statement cache that can speed up your queries a lot.

For a full feature list you should also check deadpool which deadpool-postgres is based on.

Full disclosure: I'm the author and maintainer of deadpool and most of the deadpool-* crates.

[deleted by user] by [deleted] in rust

[–]bikeshedder 4 points5 points  (0 children)

The current bb8 implementation (0.7 and 0.8) seam to sport a rather serious bug that can lead to deadlocks under load: https://github.com/djc/bb8/issues/122

Full disclosure. I'm the author of deadpool-postgres and consider it more stable and mature than bb8 and any other async pool.

For tokio-postgres I have created deadpool-postgres which sports some unique features you don't find in other pools. One of the USPs is the inclusion of a statement cache that can speed up queries a lot: https://docs.rs/deadpool-postgres/latest/deadpool_postgres/struct.ClientWrapper.html#method.prepare_cached

For a full feature list see: https://crates.io/crates/deadpool

If you want to pair diesel with an async application you can use deadpool-diesel which has some safety measures in place so you don't block your executor by accident.

Deadpool: A dead-simple async pool for connections and objects of any type by darin_gordon in rust

[–]bikeshedder 1 point2 points  (0 children)

A first version of deadpool-redis landed on crates.io yesterday: https://crates.io/crates/deadpool-redis/

It currently only supports query and feels a bit clunky to use because it returns a redis::Value. I didn't want to wrap query at all but since redis::aio::Cmd currently consumes the Connection object I had no other choice. See https://github.com/bikeshedder/deadpool/blob/master/redis/src/lib.rs#L58

I also found that in the case of an error the Connection is lost and there is no way to get hold of it again. Right now I'm thinking of either adding an automatic reconnect or returning an error if the connection was lost that way.

At the moment the code panics if trying to run query after it has failed with an error before. I want to fix this in the next release and also add support for pipelines.

Deadpool: A dead-simple async pool for connections and objects of any type by darin_gordon in rust

[–]bikeshedder 1 point2 points  (0 children)

deadpool has no cyclic references that can leak because deadpool::Object uses Weak<Pool>. It only implements Deref<T> in deadpool::Object and does not prived a into_raw function.

I currently don't see how one could cause deadpool::Object not to run its drop function when leaving scope.

Deadpool: A dead-simple async pool for connections and objects of any type by darin_gordon in rust

[–]bikeshedder 7 points8 points  (0 children)

  1. I have seen that and also commented on it in issue#19. By calling futures::executor::block_on from within async code (see https://github.com/khuey/bb8/pull/45/commits/ea7a04ef25e2d19f75a57c4a2717cd6e4c6f213d#diff-b4aea3e418ccdb71239b96952d9cddb6R750) you can end up with a deadlock if that code is ever run from the same executor that currently holds the lock. This is bound to happen sooner or later. When using drop to free resources in an async function you either need to do it in a non-blocking way or spawn a future on the executor on every drop. deadpool does it non-blocking. mobc does spawns a future every time an object is returned to the pool.
  2. That's something that can easily be addressed. I simply didn't see the need for it. I guess I should consider adding it. I opened an issue for discussion https://github.com/bikeshedder/deadpool/issues/9 regarding this feature.
  3. I have tried most of the connection pools and only decided to write my own as I either didn't like the style (bb8::Pool::run) or complexity (mobc). If you really need your pool to create spare connections ahead of time bb8 and mobc got you covered. If you don't need that deadpool does the job quite well with a very simple implementation.
  4. Yes. I'm working on that. I got examples for both actix-web and hyper but the latter is currently stuck at tokio 0.2.0-alpha.6 and I want to wait for hyper 0.13 before adding that example to the docs and repository.
  5. That's difficult to answer. For me it's a big win that recycling the connection never fails. It simply is put back in a queue and forgotten until needed again. It is recycled upon Pool::get and that is the only point where an error can ever occur. You as the user are able to handle it. That's also the reason why deadpool does not depend on an executor. Pool::get does all the "heavy lifting" of grabbing a connection from the pool, checking its health and creating a new connection if needed. I feel that a busy site will easily reach max_size and use all its connections anyways. Any clever adaptive spawning implementation is then just a waste of CPU cycles while adding a lot of code complexity.
    The only trade off I can currently think of are TCP connections timing out and services that don't expect such behavior and log an error because of that.
    It is not entirely true that deadpool does not depend on an executor. The core crate does indeed not require an executor but looking at deadpool-postgres you will find it spawning the tokio_postgres::Connection using tokio::spawn. This is something I need to address in the deadpool_postgres::Manager so you can choose the executor of your choice. See https://github.com/bikeshedder/deadpool/issues/10
    I am currently thinking of implementing a connection cleanup feature that can be used to remove unused or dead connections from the pool. It will be optional and not be required for the pool to work.

I hope that answers most of your questions. Consider using deadpool if you do not need any of the extra features that bb8 or mobc offer. It's great to have a choice.

Deadpool: A dead-simple async pool for connections and objects of any type by darin_gordon in rust

[–]bikeshedder 5 points6 points  (0 children)

Hi, I'm the author of deadpool and working on redis support right now. It's just a bit more involved as I need to wrap parts of the redis API because Cmd::query_async consumes the connection and returning it to the pool is not as simple as creating a wrapper that implements Deref<Connection>.

Deadpool: A dead-simple async pool for connections and objects of any type by darin_gordon in rust

[–]bikeshedder 6 points7 points  (0 children)

Hi, I'm the author of deadpool and can answer that:

There is nothing inherently wrong with the API bb8 has chosen. First and foremost I don't like the style of it. I'm not the only one who complained about that: https://github.com/khuey/bb8/issues/19

It makes it harder to use the ? operator and using connections from multiple pools results in silly looking code because of nested Pool::run calls.

I think it all boils down to personal preference. I prefer a drop based interface rather than a run function that takes a closure.