🐷
jaemk/cached を使ってRust(axum)で動くサーバーでキャッシュ出来るか試してみた
TL;DR
簡単なキャッシュ(関数のメモ化)は jaemk/cached で実現できる。
サンプルコード
use axum::Router;
use axum::routing::get;
use axum::extract;
use cached::{async_mutex, Cached, UnboundCache};
use cached::proc_macro::cached;
/*
cached! {
TWICE_CACHE: SizedCache<String, String> = SizedCache::with_size(5000);
fn cached_twice(id:String) -> String = {
println!("{} not cached", id);
return (id.parse::<i32>().unwrap() * 2).to_string();
}
}
*/
#[cached (name="TWICE_CACHE")]
async fn cached_twice(id:String) -> String {
println!("{} not cached", id);
return format!("{} * 2 = {}", id, id.parse::<i32>().unwrap() * 2);
}
pub fn routes() -> Router{
Router::new()
.route("/cache/:id", get(get_cache))
.route("/clear-cache/:id", get(clear_cache))
}
async fn get_cache(
extract::Path(id) : extract::Path<String>
) -> String {
cached_twice(id).await
}
async fn clear_cache(
extract::Path(id) : extract::Path<String>
) -> String {
{
let mut cache : async_mutex::MutexGuard<UnboundCache<String, String>>= TWICE_CACHE.lock().await;
cache.cache_remove(&id);
}
return format!("{} cache clear has done", id);
}
何をやっているか
- 簡単なリクエストを2倍して返すAPIサンプル
-
/cache/:id
で1回目にキャッシュ -
/cache/:id
で2回目以降はキャッシュされた値が返される -
/clear-cache/:id
でキャッシュクリア - 面倒だったので全部GETにしちゃったけど許して欲しい
使い方
cachedは関数の結果をキャッシュしてくれるマクロを提供してくれる。
Function-likeマクロ(Function-like macros)とattribute(Attribute macros)マクロの書き方が出来る。
ただasyncな関数に対してはどうやらattributeマクロの方式でしか対応してくれないようで
Function-likeマクロの書き方だとエラーになった。
axumとかasyncをつけたい場合はattributeマクロ一択になりそう。
キャッシュクリアをしたかったため、
name="TWICE_CACHE"
という形でキャッシュの構造体の名前を明示するようにしている。
TWICE_CACHE
はlockすることで操作できるっぽい。
この場合は async_mutex::MutexGuard<UnboundCache<String, String>>
が実体の型となっている。
まとめ
雑にサーバーサイドでキャッシュしたい時はjaemk/cached良いかも。
ただサーバー再起動したら消えるし、複数サーバーだとキャッシュは共有されないしなどあるので
ちゃんとやるならredisとかが無難かも。
参考
- Procedural Macros
- READMEによると関数のメモ化(memoization)が出来ると書いてある
Discussion