bb8_redis/lib.rs
1//! Redis support for the `bb8` connection pool.
2//!
3//! # Example
4//!
5//! ```
6//! use futures_util::future::join_all;
7//! use bb8_redis::{
8//! bb8,
9//! redis::{cmd, AsyncCommands},
10//! RedisConnectionManager
11//! };
12//!
13//! #[tokio::main]
14//! async fn main() {
15//! let manager = RedisConnectionManager::new("redis://localhost").unwrap();
16//! let pool = bb8::Pool::builder().build(manager).await.unwrap();
17//!
18//! let mut handles = vec![];
19//!
20//! for _i in 0..10 {
21//! let pool = pool.clone();
22//!
23//! handles.push(tokio::spawn(async move {
24//! let mut conn = pool.get().await.unwrap();
25//!
26//! let reply: String = cmd("PING").query_async(&mut *conn).await.unwrap();
27//!
28//! assert_eq!("PONG", reply);
29//! }));
30//! }
31//!
32//! join_all(handles).await;
33//! }
34//! ```
35#![allow(clippy::needless_doctest_main)]
36#![deny(missing_docs, missing_debug_implementations)]
37
38pub use bb8;
39pub use redis;
40
41use redis::{aio::MultiplexedConnection, ErrorKind};
42use redis::{Client, IntoConnectionInfo, RedisError};
43
44/// A `bb8::ManageConnection` for `redis::Client::get_async_connection`.
45#[derive(Clone, Debug)]
46pub struct RedisConnectionManager {
47 client: Client,
48}
49
50impl RedisConnectionManager {
51 /// Create a new `RedisConnectionManager`.
52 /// See `redis::Client::open` for a description of the parameter types.
53 pub fn new<T: IntoConnectionInfo>(info: T) -> Result<Self, RedisError> {
54 Ok(Self {
55 client: Client::open(info.into_connection_info()?)?,
56 })
57 }
58}
59
60impl bb8::ManageConnection for RedisConnectionManager {
61 type Connection = MultiplexedConnection;
62 type Error = RedisError;
63
64 async fn connect(&self) -> Result<Self::Connection, Self::Error> {
65 self.client.get_multiplexed_async_connection().await
66 }
67
68 async fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error> {
69 let pong: String = redis::cmd("PING").query_async(conn).await?;
70 match pong.as_str() {
71 "PONG" => Ok(()),
72 _ => Err((ErrorKind::ResponseError, "ping request").into()),
73 }
74 }
75
76 fn has_broken(&self, _: &mut Self::Connection) -> bool {
77 false
78 }
79}