Как использовать PickleDB с контекстом Rocket / Juniper? - PullRequest
1 голос
/ 09 февраля 2020

Я пытаюсь написать Rocket / Juniper / Сервер RQL на основе Rust с использованием PickleDB - хранилище ключей / значений в памяти.

База данных pickle создается / загружается в начале и передается ракете для управления:

fn rocket() -> Rocket {
    let pickle_path = var_os(String::from("PICKLE_PATH")).unwrap_or(OsString::from("pickle.db"));
    let pickle_db_dump_policy = PickleDbDumpPolicy::PeriodicDump(Duration::from_secs(120));
    let pickle_serialization_method = SerializationMethod::Bin;

    let pickle_db: PickleDb = match Path::new(&pickle_path).exists() {
        false => PickleDb::new(pickle_path, pickle_db_dump_policy, pickle_serialization_method),
        true => PickleDb::load(pickle_path, pickle_db_dump_policy, pickle_serialization_method).unwrap(),
    };

    rocket::ignite()
        .manage(Schema::new(Query, Mutation))
        .manage(pickle_db)
        .mount(
            "/",
            routes![graphiql, get_graphql_handler, post_graphql_handler],
        )
}

И я хочу получить экземпляр PickleDb из Rocket Состояние в моем Охрана:

pub struct Context {
    pickle_db: PickleDb,
}

impl juniper::Context for Context {}

impl<'a, 'r> FromRequest<'a, 'r> for Context {
    type Error = ();

    fn from_request(_request: &'a Request<'r>) -> request::Outcome<Context, ()> {
        let pickle_db = _request.guard::<State<PickleDb>>()?.inner();
        Outcome::Success(Context { pickle_db })
    }
}

Это не работает, потому что государство только дает мне ссылку:

26 |         Outcome::Success(Context { pickle_db })
   |                                    ^^^^^^^^^ expected struct `pickledb::pickledb::PickleDb`, found `&pickledb::pickledb::PickleDb`

Когда я изменяю свою структуру контекста, чтобы содержать ссылку, я получаю проблемы жизни, которые я ' я еще не знаком с:

15 |     pickle_db: &PickleDb,
   |                ^ expected named lifetime parameter

Я пытался использовать 'stati c, который делает ржавчину довольно несчастной, и я пытался использовать время жизни запроса (?)' из FromRequest, но это не действительно работает либо ...

Как мне заставить это работать? Поскольку я совсем новичок в ржавчине, это правильный путь?

1 Ответ

0 голосов
/ 13 февраля 2020

Наконец-то у меня есть решение, хотя необходимость в небезопасном указывает, что оно неоптимально:)

#![allow(unsafe_code)]
use pickledb::{PickleDb, PickleDbDumpPolicy, SerializationMethod};
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::env;
use std::path::Path;
use std::time::Duration;

pub static mut PICKLE_DB: Option<PickleDb> = None;

pub fn cache_init() {
    let pickle_path = env::var(String::from("PICKLE_PATH")).unwrap_or(String::from("pickle.db"));
    let pickle_db_dump_policy = PickleDbDumpPolicy::PeriodicDump(Duration::from_secs(120));
    let pickle_serialization_method = SerializationMethod::Json;
    let pickle_db = match Path::new(&pickle_path).exists() {
        false => PickleDb::new(
            pickle_path,
            pickle_db_dump_policy,
            pickle_serialization_method,
        ),
        true => PickleDb::load(
            pickle_path,
            pickle_db_dump_policy,
            pickle_serialization_method,
        )
        .unwrap(),
    };
    unsafe {
        PICKLE_DB = Some(pickle_db);
    }
}

pub fn cache_get<V>(key: &str) -> Option<V>
where
    V: DeserializeOwned + std::fmt::Debug,
{
    unsafe {
        let pickle_db = PICKLE_DB
            .as_ref()
            .expect("cache uninitialized - call cache_init()");
        pickle_db.get::<V>(key)
    }
}

pub fn cache_set<V>(key: &str, value: &V) -> Result<(), pickledb::error::Error>
where
    V: Serialize,
{
    unsafe {
        let pickle_db = PICKLE_DB
            .as_mut()
            .expect("cache uninitialized - call cache_init()");
        pickle_db.set::<V>(key, value)?;
        Ok(())
    }
}

Это можно просто импортировать и использовать как положено, но я думаю, что столкнусь с проблемами когда нагрузка становится высокой ...

...