如何在actix-web路由中缓存或存储数据?

问题描述

我有一个正在实现的API,我有一个需要调用的昂贵函数。我想记住此功能或使用键值缓存来查找以前的结果。我还会考虑Mutex或类似的结构,但我想避免使用Redis或Memcached之类的外部对象。根据我的阅读,互斥量在缓存方面表现不佳。如何使用像HashMap这样的键值存储或在actix_web异步路由内存储函数?现在,我正在尝试一个简单的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
}

解决方法

好像您使用此板条箱:https://github.com/jaemk/cached

将逻辑移至另一个功能。类似于以下代码的作品:

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
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...