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
}