简体   繁体   English

在 Rocket 或 Tauri 中异步加载 state

[英]Load state asynchronously in Rocket or Tauri

I have an app written in tauri (for a standalone app) and rocket (for the web version).我有一个用 tauri(用于独立应用程序)和 rocket(用于 web 版本)编写的应用程序。

The app uses a large(-ish) file that's kept in memory (basically an in-memory database) and takes somewhere between 1-10s to load, but I don't want the app to block for that duration before opening.该应用程序使用保存在 memory(基本上是内存数据库)中的大型(-ish)文件,加载时间介于 1 到 10 秒之间,但我不希望该应用程序在打开之前阻塞该持续时间。

My code (the rocket part) currently looks something like this:我的代码(火箭部分)目前看起来像这样:

#[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);
}

How can I run Database::load() asynchronously, without blocking the startup of the rocket server/tauri app and still be able to get it in search ?我怎样才能异步运行 Database::load() ,而不阻止 rocket server/tauri 应用程序的启动,并且仍然能够在search中得到它?

I ended up using global state and a RwLock like this:我最终使用了全局 state 和这样的 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]);
}

This works, but is a really ugly solution in my opinion.这可行,但在我看来这是一个非常丑陋的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM