Bb8_redis: Is there a way to return the connection?

Hello.

I want to reuse the connection, so I'm trying to make it a method or function.

this is the official example.

async fn main() {
    let manager = RedisConnectionManager::new("redis://localhost").unwrap();
    let pool = bb8::Pool::builder().build(manager).await.unwrap();

    let mut handles = vec![];

    for _i in 0..10 {
        let pool = pool.clone();

        handles.push(tokio::spawn(async move {
            let mut conn = pool.get().await.unwrap();

            let reply: String = cmd("PING").query_async(&mut *conn).await.unwrap();

            assert_eq!("PONG", reply);
        }));
    }

    join_all(handles).await;
}

I'm trying to reuse the "conn" in this.
I've tried multiple ways, but I get an error (mainly about trait bounds) and can't proceed.
does anyone know how to do it?

What is the error?

I deleted the previous code, so I wrote it again.
So I'm getting a different error.

#[derive(Copy,Clone)]
struct RedisConn;

impl RedisConn{
    async fn conn(&self) -> Result<PooledConnection<'static, RedisConnectionManager>, RunError<RedisError>>{
        let url = Environment::redis_url();
        let manager = RedisConnectionManager::new(url)?;
        let pool = bb8::Pool::builder().max_size(REDIS_MAX_SIZE).build(manager).await?;
        let clone = pool.clone();          
        let mut conn = &clone.get().await?;             

        Ok(*conn)
    }
}

error

cannot move out of `*conn` which is behind a shared reference
move occurs because `*conn` has type `PooledConnection<'_, connection::RedisConnectionManager>`, which does not implement the `Copy` trait

I'm sure you've already made a few mistakes.
maybe "conn" returns the type of ”Result<PooledConnection/...”.
i don't know how to get it return.

Don't create a reference in the first place:

        let mut conn = clone.get().await?;             

        Ok(conn)
1 Like

Perhaps I succeeded.
I needed to store the connection somewhere, probably due to ownership issues, so I decided to store it in a struct.

use anyhow::{Result, Ok};

struct MyRedis{
    mypool: Pool<RedisConnectionManager>,
}

impl MyRedis{
    async fn new() -> Result<MyRedis>{
        let url = Environment::redis_url()?;
        let manager = RedisConnectionManager::new(url)?;
        let pool = bb8::Pool::builder().max_size(REDIS_MAX_SIZE).build(manager).await?;
        let clone = pool.clone();          
    
        Ok(MyRedis{
            mypool: clone
        })
    }
    pub async fn set(key: String, val: String) -> Result<()>{
        let pool = MyRedis::new().await?.mypool; 
        let mut conn = pool.get().await?;
        let set : () = redis::cmd("SETEX").arg(key).arg(REDIS_DATE_OF_EXPIRY).arg(val).query_async(&mut *conn).await?;
        Ok(set)
    }
}

I have verified that this works.
Whether the pool is really created or not, and error handling will be postponed for the time being.