sorccu / r2d2-redis

MIT License
100 stars 42 forks source link

Trying pooling work with `web::Data<Pool<RedisConnectionManager>>` with Actix-Web #39

Closed curiousdev closed 4 years ago

curiousdev commented 4 years ago

I'm trying to get the connection pool to work and really close. I'd like to get this added to the examples once implemented. I'm trying to pool the connection inside of the Actix-Web framework.

main.rs

#[macro_use] 
extern crate actix_web;
extern crate log;
extern crate env_logger;
extern crate chrono;
extern crate r2d2_redis;

use log::info;
use actix_web::{App, HttpServer};
use actix_web::middleware::Logger;
use std::{env};
use r2d2_redis::{r2d2, RedisConnectionManager};

mod statuscontroller;
mod healthcontroller;
mod sessioncontroller;

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    env::set_var("RUST_LOG", "verify_session_service=info,actix_web=warn");
    env_logger::init();

    info!("Starting actix-web server");

    let manager = RedisConnectionManager::new("redis://localhost").unwrap();

    let pool = r2d2::Pool::builder().build(manager).unwrap();

    HttpServer::new(move || {

        App::new()
            .data(pool.clone())
            .wrap(Logger::new("%r %s %T"))
            .service(healthcontroller::health)
    })
    .bind("0.0.0.0:5000")?
    .run()
    .await
}

healthcontroller

#[get("/v1/health")]
async fn health(pool : 
   web::Data<Pool<RedisConnectionManager>>) -> impl Responder {

    let utc = Utc::now().to_rfc3339_opts(SecondsFormat::Micros, true);

    let mut conn = pool.get().unwrap();  

    let reply = redis::cmd("PING").query::<String>(conn.deref_mut()).unwrap();

    if reply == "PONG"
    {
        let health_response = HealthResponse { 
            status: String::from("HEALTHY"), 
            utcDateTime: utc 
        };

        return HttpResponse::Ok().json(health_response);
    }
    else
    {
        let health_response = HealthResponse { 
            status: String::from("NOTHEALTHY"), 
            utcDateTime: utc 
        };

        return HttpResponse::ServiceUnavailable().json(health_response);
    }    
}

Here's the compiler error

error[E0599]: no method named `deref_mut` found for type `r2d2_redis::r2d2::PooledConnection<r2d2_redis::RedisConnectionManager>` in the current scope
  --> src/healthcontroller.rs:23:57
   |
23 |     let reply = redis::cmd("PING").query::<String>(conn.deref_mut()).unwrap();
   |                                                         ^^^^^^^^^ method not found in `r2d2_redis::r2d2::PooledConnection<r2d2_redis::RedisConnectionManager>`
   |
   = help: items from traits can only be used if the trait is in scope
   = note: the following trait is implemented but not in scope; perhaps add a `use` for it:
           `use std::ops::DerefMut;`
curiousdev commented 4 years ago

Fixed needed to use this instead let reply : String = redis::cmd("PING").query(&mut *conn).unwrap();