toml

actix-web = "4"
redis = { version = "0.21.4", features = ["r2d2"] }
r2d2 = "0.8.9"
r2d2_redis = "0.14.0"
uuid = { version = "0.8", features = ["v4"] }

with_r2d2.rs

use redis::Commands;
use std::time::Duration;

pub type R2D2Pool = r2d2::Pool<redis::Client>;
type R2d2PooledCon = r2d2::PooledConnection<redis::Client>;

const PREFIX: &str = "with_r2d2";
const TTL: usize = 60 * 5;
const MAX_POOL_SIZE: u32 = 30;
const CONNECTION_TIMEOUT: Duration = Duration::from_secs(10);

/// 默认创建
pub fn _simple_create_pool(host_addr: &str) -> Result<R2D2Pool, MyError> {
    let client = redis::Client::open(host_addr).map_err(|e| MyError::new_string(e.to_string()))?;

    r2d2::Pool::builder()
        .build(client)
        .map_err(|e| MyError::new_string(e.to_string()))
}

pub fn create_pool(host_addr: &str) -> Result<R2D2Pool, MyError> {
    let client = redis::Client::open(host_addr).map_err(|e| MyError::new_string(e.to_string()))?;
    r2d2::Pool::builder()
        .max_size(MAX_POOL_SIZE)
        .connection_timeout(CONNECTION_TIMEOUT)
        .build(client)
        .map_err(|e| MyError::new_string(e.to_string()))
}

fn get_key(base: &str) -> String {
    format!("{}:{}", PREFIX, base)
}

fn create_connection(pool: &R2D2Pool) -> Result<R2d2PooledCon, MyError> {
    pool.get().map_err(|e| MyError::new_string(e.to_string()))
}

pub fn set(pool: &R2D2Pool, key: &str, value: &str) -> Result<(), MyError> {
    let mut con = create_connection(pool)?;
    let redis_key = get_key(key);
    con.set_ex(redis_key, value, TTL)
        .map_err(|e| MyError::new_string(e.to_string()))
}

pub fn get(pool: &R2D2Pool, key: &str) -> Result<String, MyError> {
    let mut con = create_connection(pool)?;
    let redis_key = get_key(key);
    con.get(redis_key)
        .map_err(|e| MyError::new_string(e.to_string()))
}

#[derive(Debug)]
pub struct MyError {
    pub msg: String,
}
impl MyError {
    pub fn new_str(s: &str) -> MyError {
        MyError { msg: s.to_string() }
    }
    pub fn new_string(s: String) -> MyError {
        MyError { msg: s }
    }
}

main.rs

use actix_web::{get, web, App, HttpResponse, HttpServer, Responder};
use uuid::Uuid;
mod with_r2d2;

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}
#[get("/r2d2")]
async fn set_with_r2d2(pool: web::Data<with_r2d2::R2D2Pool>) -> impl Responder {
    let id = Uuid::new_v4();
    let key = format!("{}", id);
    let value = "hi";
    let result = with_r2d2::set(&pool, &key, value);
    match result {
        Ok(_) => HttpResponse::Ok().body(key),
        Err(e) => HttpResponse::InternalServerError().body(e.msg),
    }
}
#[get("/r2d2/{id}")]
async fn get_with_r2d2(
    pool: web::Data<with_r2d2::R2D2Pool>,
    info: web::Path<(String,)>,
) -> impl Responder {
    let result = with_r2d2::get(&pool, &info.0);
    match result {
        Ok(r) => HttpResponse::Ok().body(r),
        Err(e) => HttpResponse::NotFound().body(e.msg),
    }
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let host = "redis://192.168.252.128/";
    let r2d2_pool = with_r2d2::create_pool(host).unwrap();
    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(r2d2_pool.clone()))
            .service(hello)
            .service(set_with_r2d2)
            .service(get_with_r2d2)
    })
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

朝阳
1 声望0 粉丝