From 7272879180fbc189bffb67eae84e248f13cc4feb Mon Sep 17 00:00:00 2001 From: alemidev Date: Wed, 13 Jul 2022 01:58:01 +0200 Subject: [PATCH] feat: state manager with message passing Co-authored-by: f-tlm --- src/server/state.rs | 61 +++++++++++++++++++++++++++++++++++++++++ src/server/workspace.rs | 18 ++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/server/state.rs create mode 100644 src/server/workspace.rs diff --git a/src/server/state.rs b/src/server/state.rs new file mode 100644 index 0000000..902dbf8 --- /dev/null +++ b/src/server/state.rs @@ -0,0 +1,61 @@ + +use std::{collections::HashMap, sync::Arc}; +use tokio::sync::{mpsc, watch}; + +use crate::workspace::Workspace; + +#[derive(Debug)] +pub enum AlterState { + ADD { + key: String, + w: Workspace + }, + REMOVE { key: String }, +} + +pub struct StateManager { + store: HashMap>, + rx: mpsc::Receiver, + tx: watch::Sender>> +} + +impl StateManager { + pub fn new(rx: mpsc::Receiver, tx: watch::Sender>>) -> StateManager { + StateManager { + store: HashMap::new(), + rx, + tx + } + } + + pub async fn run(mut self) { + loop { + if let Some(event) = self.rx.recv().await { + match event { + AlterState::ADD { key, w } => { + self.store.insert(key, Arc::new(w)); // TODO put in hashmap + }, + AlterState::REMOVE { key } => { + self.store.remove(&key); + }, + } + self.tx.send(self.store.clone()).unwrap(); + } else { + break + } + } + } +} + + +pub fn run_state_manager() -> (mpsc::Sender, watch::Receiver>>) { + let (tx, rx) = mpsc::channel(32); // TODO quantify backpressure + let (watch_tx, watch_rx) = watch::channel(HashMap::new()); + let state = StateManager::new(rx, watch_tx); + + let _task = tokio::spawn(async move { + state.run().await; + }); + + return (tx, watch_rx); +} diff --git a/src/server/workspace.rs b/src/server/workspace.rs new file mode 100644 index 0000000..8a92e5a --- /dev/null +++ b/src/server/workspace.rs @@ -0,0 +1,18 @@ +// Must be clonable, containing references to the actual state maybe? Or maybe give everyone an Arc, idk +#[derive(Debug)] +pub struct Workspace { + pub name: String, + pub content: String, +} + +impl Workspace { + pub fn new(name: String, content: String) -> Self { + Workspace { name , content } + } +} + +impl Default for Workspace { + fn default() -> Self { + Workspace { name: "fuck you".to_string() , content: "too".to_string() } + } +}