This commit is contained in:
Maciej Krzyżanowski 2024-10-08 11:41:29 +02:00
parent 454ad256d1
commit 50f8604290

149
src/bin/beta.rs Normal file
View File

@ -0,0 +1,149 @@
use tokio::sync::{mpsc::{Receiver, Sender}, oneshot};
struct DatabaseStore {
counter: u64,
}
struct DatabaseClient {
queries: Sender<DatabaseQuery>,
}
struct DatabaseManager {
store: DatabaseStore,
queries: Receiver<DatabaseQuery>,
}
struct Database {
client: DatabaseClient,
}
enum DatabaseQuery {
Increment{
resp: oneshot::Sender<DatabaseResponse>,
},
Decrement{
resp: oneshot::Sender<DatabaseResponse>,
},
Get{
resp: oneshot::Sender<DatabaseResponse>,
},
}
enum DatabaseResponse {
Ok,
Value(u64),
}
#[tokio::main]
async fn main() {
let db = Database::new(DatabaseStore::new());
if let Ok(counter) = db.client.get().await {
println!("{}", counter);
}
if let Ok(_) = db.client.increment().await {
println!("incremented");
}
if let Ok(counter) = db.client.get().await {
println!("{}", counter);
}
if let Ok(_) = db.client.decrement().await {
println!("decremented");
}
if let Ok(counter) = db.client.get().await {
println!("{}", counter);
}
}
impl Database {
fn new(store_init: DatabaseStore) -> Database {
let (tx, rx) = tokio::sync::mpsc::channel(32);
let mut manager = DatabaseManager{ store: store_init, queries: rx };
tokio::spawn(async move {
manager.run().await;
});
Database{
client: DatabaseClient{
queries: tx,
},
}
}
}
impl DatabaseManager {
async fn run(&mut self) {
loop {
if let Some(query) = self.queries.recv().await {
self.handle_query(query);
} else {
break;
}
}
}
fn handle_query(&mut self, query: DatabaseQuery) {
match query {
DatabaseQuery::Increment{ resp } => {
self.store.counter += 1;
let _ = resp.send(DatabaseResponse::Ok);
}
DatabaseQuery::Decrement { resp } => {
self.store.counter -= 1;
let _ = resp.send(DatabaseResponse::Ok);
}
DatabaseQuery::Get { resp } => {
let _ = resp.send(DatabaseResponse::Value(self.store.counter));
}
}
}
}
impl DatabaseStore {
fn new() -> DatabaseStore {
DatabaseStore{
counter: 0,
}
}
}
impl DatabaseClient {
async fn increment(&self) -> Result<(), ()> {
let (tx, rx) = tokio::sync::oneshot::channel();
let _ = self.queries.send(DatabaseQuery::Increment { resp: tx }).await;
match rx.await {
Ok(_) => Ok(()),
Err(_) => Err(())
}
}
async fn decrement(&self) -> Result<(), ()> {
let (tx, rx) = tokio::sync::oneshot::channel();
let _ = self.queries.send(DatabaseQuery::Decrement { resp: tx }).await;
match rx.await {
Ok(_) => Ok(()),
Err(_) => Err(())
}
}
async fn get(&self) -> Result<u64, ()> {
let (tx, rx) = tokio::sync::oneshot::channel();
let _ = self.queries.send(DatabaseQuery::Get { resp: tx }).await;
match rx.await {
Ok(db_resp) => {
match db_resp {
DatabaseResponse::Value(value) => Ok(value),
_ => Err(())
}
}
Err(_) => Err(())
}
}
}