MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Alternative zur Verwendung von 'await' mit lazy_static! Makro im Rost?

Ich habe mich für diesen Ansatz entschieden, basierend auf einem Vorschlag in Rostforen.

static MONGO: OnceCell<Client> = OnceCell::new();
static MONGO_INITIALIZED: OnceCell<tokio::sync::Mutex<bool>> = OnceCell::new();

pub async fn get_mongo() -> Option<&'static Client> {
    // this is racy, but that's OK: it's just a fast case
    let client_option = MONGO.get();
    if let Some(_) = client_option {
        return client_option;
    }
    // it hasn't been initialized yet, so let's grab the lock & try to
    // initialize it
    let initializing_mutex = MONGO_INITIALIZED.get_or_init(|| tokio::sync::Mutex::new(false));

    // this will wait if another task is currently initializing the client
    let mut initialized = initializing_mutex.lock().await;
    // if initialized is true, then someone else initialized it while we waited,
    // and we can just skip this part.
    if !*initialized {
        // no one else has initialized it yet, so

        if let Ok(token) = env::var("MONGO_AUTH") {
            if let Ok(client_options) = ClientOptions::parse(&token).await {
                if let Ok(client) = Client::with_options(client_options) {
                    if let Ok(_) = MONGO.set(client) {
                        *initialized = true;
                    }
                }
            }
        }
    }
    drop(initialized);
    MONGO.get()
}