如何缓存或记忆 actix-web 路由中的数据?

tur*_*tle 5 rust actix-web

我正在实现一个 API,其中有一个需要调用的昂贵函数。我想要么记住这个函数,要么使用键值缓存来查找以前的结果。我也会考虑一个Mutex或类似的结构,但我想避免像 Redis 或 Memcached 这样的外部结构。据我所知, aMutex的缓存性能很差。如何HashMap在 actix_web 异步路由中使用键值存储(例如 a 或 memoize 函数)?现在,我正在尝试一个简单的方法HashMap,但出现此错误:can't borrow data in an Arc as mutable

async fn index(
    kv: web::Data<HashMap<&str, i64>>,
) -> Result<HttpResponse> {
    dbg!(kv);   
    kv.insert("four", 4);
    Ok(HttpResponse::Ok().json(kv)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let tuples: Vec<(&str, i64)> = vec![("one", 1), ("two", 2), ("three", 3)];
    let mut m = tuples.into_iter().collect::<HashMap<&str, i64>>();
    let mut kv = web::Data::new(m);
    // move is necessary to give closure below ownership of counter1
    HttpServer::new(move || {
            App::new()
                .app_data(kv.clone())
                .route("/", web::get().to(index))
        })
        .bind("127.0.0.1:8080")?
        .run()
        .await
}
Run Code Online (Sandbox Code Playgroud)

Omi*_*mid 3

看来你可以使用缓存的箱子。

将逻辑移至另一个函数。类似下面的代码可以工作:

use actix_web::{web, App, HttpServer, HttpResponse};
use cached::proc_macro::cached;

async fn index() -> HttpResponse {
    dbg!("in index");
    let number = get_number(2);
    HttpResponse::Ok().body(number.to_string())
}

#[cached]
fn get_number(n: i32) -> i32 {
    dbg!("in get_number");
    n * 2
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(move || {
            App::new()
                .route("/", web::get().to(index))
        })
        .bind("127.0.0.1:8080")?
        .run()
        .await
}
Run Code Online (Sandbox Code Playgroud)