Last active
April 30, 2026 00:49
-
-
Save stephenlb/8a41f0393d6970f73497d14f49503adf to your computer and use it in GitHub Desktop.
Multi-threaded Async MPSC Cache in Tokyo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use std::collections::HashMap; | |
| use tokio::sync::{mpsc, oneshot}; | |
| // THE BEST PART OF YOUR DAY | |
| enum Request { | |
| Set(String, String), // Key and Value | |
| Get(String, oneshot::Sender<Option<String>>), | |
| Delete(String), | |
| } | |
| #[derive(Clone)] | |
| struct Cache { | |
| req: mpsc::Sender<Request>, | |
| } | |
| impl Cache { | |
| fn new() -> Self { | |
| let (req, receiver) = mpsc::channel(256); | |
| tokio::spawn(cache_service(receiver)); | |
| Self { req } | |
| } | |
| async fn set(&self, key: &str, value: &str) { | |
| self.req.send(Request::Set( | |
| key.to_string(), | |
| value.to_string(), | |
| )).await.ok(); | |
| } | |
| async fn get(&self, key: &str) -> Option<String> { | |
| let (reply, receive) = oneshot::channel(); | |
| self.req.send(Request::Get(key.to_string(), reply)).await.ok()?; | |
| receive.await.ok().flatten() | |
| } | |
| async fn delete(&self, key: &str) { | |
| self.req.send(Request::Delete(key.to_string())).await.ok(); | |
| } | |
| } | |
| async fn cache_service(mut receiver: mpsc::Receiver<Request>) { | |
| // All data sotred here | |
| let mut map: HashMap<String, String> = HashMap::new(); | |
| while let Some(req) = receiver.recv().await { | |
| match req { | |
| Request::Set(key, value) => { | |
| map.insert(key, value); | |
| }, | |
| Request::Get(key, reply_oneshot) => { | |
| reply_oneshot.send(map.get(&key).cloned()).ok(); | |
| }, | |
| Request::Delete(key) => { | |
| map.remove(&key); | |
| }, | |
| } | |
| } | |
| } | |
| #[tokio::main] | |
| async fn main() { | |
| println!("Hello, cache!"); | |
| let cache = Cache::new(); | |
| cache.set("Zergio42", "Sivan, Looons, Kyle, Bonzupii, Jefferson, zombied, mrdangwal").await; | |
| if let Some(value) = cache.get("Zergio42").await { | |
| println!("Zergio42: {value}"); | |
| } | |
| cache.set("DeleteMe", "DeleteMe").await; | |
| if let Some(value) = cache.get("DeleteMe").await { | |
| println!("The DeleteMe: {value}"); | |
| } | |
| cache.delete("DeleteMe").await; | |
| if let Some(value) = cache.get("DeleteMe").await { | |
| println!("NEVER WILL SEE THIS MESSSAGE: {value}"); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment