最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Rust在寫庫時(shí)實(shí)現(xiàn)緩存的操作方法

 更新時(shí)間:2024年01月06日 15:37:51   作者:Star-tears  
Moka是一個(gè)用于Rust的高性能緩存庫,它提供了多種類型的緩存數(shù)據(jù)結(jié)構(gòu),包括哈希表、LRU(最近最少使用)緩存和?支持TTL(生存時(shí)間)緩存,這篇文章給大家介紹Rust在寫庫時(shí)實(shí)現(xiàn)緩存的相關(guān)知識(shí),感興趣的朋友一起看看吧

Rust在寫庫時(shí)實(shí)現(xiàn)緩存

依賴

在寫庫時(shí),實(shí)現(xiàn)一個(gè)緩存請(qǐng)求,需要用到全局變量,所以我們可以添加cratelazy_static

Cargo.toml添加以下依賴

[dependencies]
chrono = "0.4.31"
lazy_static = "1.4.0"
reqwest = { version = "0.11.23", features = ["blocking", "json"] }
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0.108"

代碼實(shí)現(xiàn)

use std::{sync::Mutex, collections::HashMap};
use chrono::{DateTime, Utc};
use lazy_static::lazy_static;
use serde_json::Value;
lazy_static! {
    static ref REQUESTS_RESPONSE_CACHE: Mutex<HashMap<String, RequestsResponseCache>> =
        Mutex::new(HashMap::new());
}
pub struct RequestsResponseCache {
    pub response: Value,
    pub datetime: DateTime<Utc>,
}
pub fn get_requests_response_cache(url: &str) -> Result<Value, reqwest::Error> {
    let mut cache = REQUESTS_RESPONSE_CACHE.lock().unwrap();
    if let Some(cache_entry) = cache.get(url) {
        let elapsed = Utc::now() - cache_entry.datetime;
        if elapsed.num_seconds() > 3600 {
            let response: Value = reqwest::blocking::get(url)?.json()?;
            let res = response.clone();
            let cache_entry = RequestsResponseCache {
                response,
                datetime: Utc::now(),
            };
            cache.insert(url.to_string(), cache_entry);
            return Ok(res);
        }
    }
    let response: Value = reqwest::blocking::get(url)?.json()?;
    let res = response.clone();
    let cache_entry = RequestsResponseCache {
        response,
        datetime: Utc::now(),
    };
    cache.insert(url.to_string(), cache_entry);
    Ok(res)
}

使用了 lazy_static 宏創(chuàng)建了一個(gè)靜態(tài)的全局變量 REQUESTS_RESPONSE_CACHE,這個(gè)全局變量是一個(gè) Mutex 包裹的 HashMap,用來存儲(chǔ)請(qǐng)求的響應(yīng)緩存。這個(gè)緩存是線程安全的,因?yàn)楸?Mutex 包裹了起來,這樣就可以在多個(gè)線程中安全地訪問和修改這個(gè)緩存。

接著定義了一個(gè) RequestsResponseCache 結(jié)構(gòu)體,用來表示緩存中的一個(gè)條目,其中包含了響應(yīng)數(shù)據(jù) response 和緩存的時(shí)間戳 datetime

然后定義了一個(gè) get_requests_response_cache 函數(shù),用來從緩存中獲取請(qǐng)求的響應(yīng)。它首先嘗試從緩存中獲取指定 url 的響應(yīng)數(shù)據(jù),如果緩存中有對(duì)應(yīng)的條目,并且距離上次緩存的時(shí)間超過了 3600 秒(1 小時(shí)),則重新發(fā)起請(qǐng)求并更新緩存,然后返回響應(yīng)數(shù)據(jù)。如果緩存中沒有對(duì)應(yīng)的條目,或者緩存的時(shí)間未超過 3600 秒,則直接發(fā)起請(qǐng)求并更新緩存,然后返回響應(yīng)數(shù)據(jù)。

這樣就提供了一個(gè)簡(jiǎn)單的請(qǐng)求響應(yīng)的緩存功能,能夠在需要時(shí)緩存請(qǐng)求的響應(yīng)數(shù)據(jù),并在一定時(shí)間內(nèi)有效,從而減少對(duì)遠(yuǎn)程服務(wù)的重復(fù)請(qǐng)求,提高程序性能。

補(bǔ)充:

rust緩存庫moka簡(jiǎn)介

關(guān)于moka

“Moka” 是一個(gè)用于 Rust 的高性能緩存庫,它提供了多種類型的緩存數(shù)據(jù)結(jié)構(gòu),包括哈希表、LRU(最近最少使用)緩存和 支持TTL(生存時(shí)間)緩存。
以下是一些 “moka” 庫的特點(diǎn)和功能:

  • 多種緩存類型: “moka” 提供了多種緩存類型,包括哈希表緩存、LRU 緩存和 TTL 緩存。你可以根據(jù)具體的需求選擇適合的緩存類型。
  • 線程安全: “moka” 庫是線程安全的,可以在多線程環(huán)境中使用,不需要額外的同步措施。
  • 高性能: “moka” 的設(shè)計(jì)目標(biāo)之一是提供高性能的緩存實(shí)現(xiàn)。它經(jīng)過優(yōu)化,能夠在高并發(fā)場(chǎng)景下快速處理緩存操作。
  • 可配置性: “moka” 允許你根據(jù)需要對(duì)緩存進(jìn)行配置,如容量限制、緩存項(xiàng)的最大生存時(shí)間等。

moka的github地址:moka。

moka的使用示例

1.事件通知:
支持在緩存項(xiàng)發(fā)生過期淘汰、用戶主動(dòng)淘汰、緩存池大小受限強(qiáng)制淘汰時(shí),觸發(fā)回調(diào)函數(shù)執(zhí)行一些后續(xù)任務(wù)。

use moka::{notification::RemovalCause, sync::Cache};
use std::time::{Duration,Instant};
fn main() {
    // 創(chuàng)建一個(gè)緩存項(xiàng)事件監(jiān)聽閉包
    let now = Instant::now();
    let listener = move |k, v: String, cause| {
        // 監(jiān)聽緩存項(xiàng)的觸發(fā)事件,RemovalCause包含四種場(chǎng)景:Expired(緩存項(xiàng)過期)、Explicit(用戶主動(dòng)移除緩存)、Replaced(緩存項(xiàng)發(fā)生更新或替換)、Size(緩存數(shù)量達(dá)到上限驅(qū)逐)。
        println!(
            "== An entry has been evicted. time:{} k: {:?}, v: {:?},cause:{:?}",
            now.elapsed().as_secs(),
            k,
            v,
            cause
        );
        // 針對(duì)不同事項(xiàng),進(jìn)行處理。
        // match cause {
        //     RemovalCause::Expired => {}
        //     RemovalCause::Explicit => {}
        //     RemovalCause::Replaced => {}
        //     RemovalCause::Size => {}
        // }
    };
    //緩存生存時(shí)間:10s
    let ttl_time = Duration::from_secs(10);
    // 創(chuàng)建一個(gè)具有過期時(shí)間和淘汰機(jī)制的緩存
    let cache: Cache<String, String> = Cache::builder()
        .time_to_idle(ttl_time)
        .eviction_listener(listener)
        .build();
    // insert 緩存項(xiàng)
    cache.insert("key1".to_string(), "value1".to_string());
    cache.insert("key2".to_string(), "value2".to_string());
    cache.insert("key3".to_string(), "value3".to_string());
    // 5s后使用key1
    std::thread::sleep(Duration::from_secs(5));
    if let Some(value) = cache.get(&"key1".to_string()) {
        println!("5s: Value of key1: {}", value);
    }
    cache.remove("key3");
    println!("5s: remove key3");
    // 等待 6 秒,讓緩存項(xiàng)key2過期
    std::thread::sleep(Duration::from_secs(6));
    // 嘗試獲取緩存項(xiàng) "key1" 的值
    if let Some(value) = cache.get("key1") {
        println!("11s: Value of key1: {}", value);
    } else {
        println!("Key1 has expired.");
    }
    // 嘗試獲取緩存項(xiàng) "key2" 的值
    if let Some(value) = cache.get("key2") {
        println!("11s: Value of key2: {}", value);
    } else {
        println!("Key2 has expired.");
    }
    // 嘗試獲取緩存項(xiàng) "key3" 的值
    if let Some(value) = cache.get("key3") {
        println!("11s: Value of key3: {}", value);
    } else {
        println!("Key3 has removed.");
    }
    // 空置9s后
    std::thread::sleep(Duration::from_secs(11));
    // 再次嘗試獲取緩存項(xiàng) "key1" 的值
    if let Some(value) = cache.get("key1") {
        println!("22s: Value of key1: {}", value);
    } else {
        println!("Key1 has expired.");
    }
}

運(yùn)行結(jié)果:

5s: Value of key1: value1
== An entry has been evicted. time:5 k: "key3", v: "value3",cause:Explicit
5s: remove key3
== An entry has been evicted. time:10 k: "key2", v: "value2",cause:Expired
11s: Value of key1: value1
Key2 has expired.
Key3 has removed.
== An entry has been evicted. time:21 k: "key1", v: "value1",cause:Expired
Key1 has expired.

2.支持同步并發(fā):

use moka::sync::Cache;
use std::thread;
fn value(n: usize) -> String {
    format!("value {}", n)
}
fn main() {
    const NUM_THREADS: usize = 3;
    const NUM_KEYS_PER_THREAD: usize = 2;
    // Create a cache that can store up to 6 entries.
    let cache = Cache::new(6);
    // Spawn threads and read and update the cache simultaneously.
    let threads: Vec<_> = (0..NUM_THREADS)
        .map(|i| {
            // To share the same cache across the threads, clone it.
            // This is a cheap operation.
            let my_cache = cache.clone();
            let start = i * NUM_KEYS_PER_THREAD;
            let end = (i + 1) * NUM_KEYS_PER_THREAD;
            thread::spawn(move || {
                // Insert 2 entries. (NUM_KEYS_PER_THREAD = 2)
                for key in start..end {
                    my_cache.insert(key, value(key));
                    println!("{}",my_cache.get(&key).unwrap());
                }
                // Invalidate every 2 element of the inserted entries.
                for key in (start..end).step_by(2) {
                    my_cache.invalidate(&key);
                }
            })
        })
        .collect();
    // Wait for all threads to complete.
    threads.into_iter().for_each(|t| t.join().expect("Failed"));
    // Verify the result.
    for key in 0..(NUM_THREADS * NUM_KEYS_PER_THREAD) {
        if key % 2 == 0 {
            assert_eq!(cache.get(&key), None);
        } else {
            assert_eq!(cache.get(&key), Some(value(key)));
        }
    }
}

結(jié)果:

value 2
value 3
value 0
value 4
value 1
value 5

并發(fā)讀寫cahce中的數(shù)據(jù)不會(huì)產(chǎn)生異常。

3.下面是moka庫example中給出的異步示例:

use moka::future::Cache;
#[tokio::main]
async fn main() {
    const NUM_TASKS: usize = 16;
    const NUM_KEYS_PER_TASK: usize = 64;
    fn value(n: usize) -> String {
        format!("value {}", n)
    }
    // Create a cache that can store up to 10,000 entries.
    let cache = Cache::new(10_000);
    // Spawn async tasks and write to and read from the cache.
    let tasks: Vec<_> = (0..NUM_TASKS)
        .map(|i| {
            // To share the same cache across the async tasks, clone it.
            // This is a cheap operation.
            let my_cache = cache.clone();
            let start = i * NUM_KEYS_PER_TASK;
            let end = (i + 1) * NUM_KEYS_PER_TASK;
            tokio::spawn(async move {
                // Insert 64 entries. (NUM_KEYS_PER_TASK = 64)
                for key in start..end {
                    // insert() is an async method, so await it.
                    my_cache.insert(key, value(key)).await;
                    // get() returns Option<String>, a clone of the stored value.
                    assert_eq!(my_cache.get(&key), Some(value(key)));
                }
                // Invalidate every 4 element of the inserted entries.
                for key in (start..end).step_by(4) {
                    // invalidate() is an async method, so await it.
                    my_cache.invalidate(&key).await;
                }
            })
        })
        .collect();
    // Wait for all tasks to complete.
    futures_util::future::join_all(tasks).await;
    // Verify the result.
    for key in 0..(NUM_TASKS * NUM_KEYS_PER_TASK) {
        if key % 4 == 0 {
            assert_eq!(cache.get(&key), None);
        } else {
            assert_eq!(cache.get(&key), Some(value(key)));
        }
    }
}

到此這篇關(guān)于Rust在寫庫時(shí)實(shí)現(xiàn)緩存的文章就介紹到這了,更多相關(guān)Rust緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • rust實(shí)現(xiàn)post小程序(完整代碼)

    rust實(shí)現(xiàn)post小程序(完整代碼)

    這篇文章主要介紹了rust實(shí)現(xiàn)一個(gè)post小程序,本文通過示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • Rust 多線程編程的實(shí)現(xiàn)

    Rust 多線程編程的實(shí)現(xiàn)

    在rust中,多線程編程不算困難,但是也需要留心和別的編程語言中不同的地方,本文主要介紹了Rust 多線程編程的實(shí)現(xiàn),感興趣的可以了解一下
    2023-12-12
  • Rust中類型轉(zhuǎn)換在錯(cuò)誤處理中的應(yīng)用小結(jié)

    Rust中類型轉(zhuǎn)換在錯(cuò)誤處理中的應(yīng)用小結(jié)

    隨著項(xiàng)目的進(jìn)展,關(guān)于Rust的故事又翻開了新的一頁,今天來到了服務(wù)器端的開發(fā)場(chǎng)景,發(fā)現(xiàn)錯(cuò)誤處理中的錯(cuò)誤類型轉(zhuǎn)換有必要分享一下,對(duì)Rust錯(cuò)誤處理相關(guān)知識(shí)感興趣的朋友一起看看吧
    2023-09-09
  • RUST語言函數(shù)的定義與調(diào)用方法

    RUST語言函數(shù)的定義與調(diào)用方法

    定義一個(gè)RUST函數(shù)使用fn關(guān)鍵字,下面通過本文給大家介紹RUST語言函數(shù)的定義與調(diào)用方法,感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • Rust語言之結(jié)構(gòu)體和枚舉的用途與高級(jí)功能詳解

    Rust語言之結(jié)構(gòu)體和枚舉的用途與高級(jí)功能詳解

    Rust 是一門注重安全性和性能的現(xiàn)代編程語言,其中結(jié)構(gòu)體和枚舉是其強(qiáng)大的數(shù)據(jù)類型之一,了解結(jié)構(gòu)體和枚舉的概念及其高級(jí)功能,將使你能夠更加靈活和高效地處理數(shù)據(jù),本文將深入探討 Rust 中的結(jié)構(gòu)體和枚舉,并介紹它們的用途和高級(jí)功能
    2023-10-10
  • Rust中向量的學(xué)習(xí)筆記

    Rust中向量的學(xué)習(xí)筆記

    在Rust語言中,向量是一種動(dòng)態(tài)數(shù)組類型,可以存儲(chǔ)相同類型的元素,并且可以在運(yùn)行時(shí)改變大小,本文就來介紹一下Rust中向量,感興趣的可以了解一下
    2024-03-03
  • 為什么要使用 Rust 語言、Rust 語言有什么優(yōu)勢(shì)

    為什么要使用 Rust 語言、Rust 語言有什么優(yōu)勢(shì)

    雖然 Rust 是一種通用的多范式語言,但它的目標(biāo)是 C 和 C++占主導(dǎo)地位的系統(tǒng)編程領(lǐng)域,很多朋友會(huì)問rust語言難學(xué)嗎?rust語言可以做什么,今天帶著這些疑問通過本文詳細(xì)介紹下,感興趣的朋友一起看看吧
    2022-10-10
  • Rust常用特型之Drop特型

    Rust常用特型之Drop特型

    本文主要介紹了Rust常用特型之Drop特型,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • Rust之模式與模式匹配的實(shí)現(xiàn)

    Rust之模式與模式匹配的實(shí)現(xiàn)

    Rust中的模式匹配功能強(qiáng)大且靈活,它極大地提高了代碼的表達(dá)力和可讀性,本文主要介紹了Rust之模式與模式匹配,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • rust標(biāo)準(zhǔn)庫std::env環(huán)境相關(guān)的常量

    rust標(biāo)準(zhǔn)庫std::env環(huán)境相關(guān)的常量

    在本章節(jié)中, 我們探討了Rust處理命令行參數(shù)的常見的兩種方式和處理環(huán)境變量的兩種常見方式, 拋開Rust的語法, 實(shí)際上在命令行參數(shù)的處理方式上, 與其它語言大同小異, 可能影響我們習(xí)慣的也就只剩下語法,本文介紹rust標(biāo)準(zhǔn)庫std::env的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2024-03-03

最新評(píng)論

东平县| 浪卡子县| 新化县| 凤山县| 通榆县| 临沭县| 淮安市| 绿春县| 乐清市| 黄山市| 旌德县| 滨州市| 云和县| 和林格尔县| 陆良县| 临沭县| 建始县| 腾冲县| 中超| 昌邑市| 彭阳县| 杭州市| 青浦区| 吴桥县| 唐河县| 惠东县| 陇川县| 乌鲁木齐县| 汝阳县| 定兴县| 沙湾县| 兰考县| 沙田区| 新田县| 霍山县| 南部县| 永兴县| 晴隆县| 威海市| 天等县| 三都|