rust 在Rocket或Tauri中异步加载状态

rvpgvaaj  于 2023-01-17  发布在  其他
关注(0)|答案(1)|浏览(253)

我有一个应用程序是用tauri(一个独立的应用程序)和rocket(网络版)编写的。
这个应用程序使用了一个保存在内存中的大文件(基本上是一个内存数据库),加载时间在1- 10秒之间,但我不希望应用程序在打开之前阻塞这段时间。
我的代码(火箭部分)现在看起来像这样:

#[rocket::get("/api/search?<searchTerm>&<take>&<skip>")]
pub fn search<'a>(
    searchTerm: &str,
    take: Option<u32>,
    skip: Option<u32>,
    db: &rocket::State<Database>
) -> Json<SearchResult>
{
    Json(db.search(searchTerm, take, skip))
}

#[rocket::launch]
fn rocket() {
    // ...
    let db = Database::load().expect("Failed loading database");
    rocket::build()
        .mount("/", rocket::routes![search])
        .manage(db);
}

如何异步运行Database::load(),而不阻塞rocket服务器/tauri应用程序的启动,并且仍然能够在search中获取它?

ubby3x7f

ubby3x7f1#

我最终使用了全局状态和RwLock,如下所示:

static DB: RwLock::<Option<Database>> = RwLock::<Option<Database>>::new(None);

#[rocket::get("/api/search?<searchTerm>&<take>&<skip>")]
pub fn search<'a>(
    searchTerm: &str,
    take: Option<u32>,
    skip: Option<u32>,
    db: &rocket::State<Database>
) -> Json<SearchResult>
{
    if let Some(db) = DB.read().expect("Cannot read the database because it failed to load.").as_ref() {
        Json(jdict_shared::shared_api::search(db, searchTerm, take, skip))
    }
    else {
        // TODO: return proper error code
        Json(jdict_shared::shared_api::SearchResult::default())
    }
}

#[rocket::launch]
fn rocket() {
    // ...
    std::thread::spawn(|| {
        *DB.write().unwrap() = Some(Database::load(cfg.jdict));
    });

    rocket::build().mount("/", rocket::routes![search]);
}

这是可行的,但在我看来是一个非常丑陋的解决方案。

相关问题