Skip to content

Instantly share code, notes, and snippets.

@cfcosta
Created November 16, 2023 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cfcosta/d03f3c6da4d5d71a4e7122703ebde6d4 to your computer and use it in GitHub Desktop.
Save cfcosta/d03f3c6da4d5d71a4e7122703ebde6d4 to your computer and use it in GitHub Desktop.
use forced_collaboration::{
corpus::key_value_store::{Operation, Response},
proptest::*,
test_key_value_store, transport, Host, Simulation,
};
use async_trait::async_trait;
use dashmap::DashMap;
use eyre::Result;
use turmoil::net::TcpStream;
#[derive(Debug, Clone, Default)]
pub struct Server {
pub inner: DashMap<String, String>,
}
#[async_trait]
impl Host for Server {
async fn on_connection(&self, stream: TcpStream) -> Result<TcpStream> {
let (mut reader, mut writer) = transport::<Operation, Response>(stream);
while let Ok(event) = reader.read().await {
let response = match event {
Operation::Set(key, value) => {
let response = match self.inner.get(&key).as_ref() {
Some(old) => Response::replaced(&key, (*old).clone()),
None => Response::ack(),
};
self.inner.insert(key, value);
response
}
Operation::Get(key) => match self.inner.get(&key) {
Some(v) => Response::value(v.clone()),
None => Response::empty(key),
},
Operation::Delete(key) => match self.inner.remove(&key) {
Some(_) => Response::ack(),
None => Response::empty(key),
},
};
writer.write(response).await?;
}
Ok(reader.reunite(writer)?)
}
}
test_key_value_store!(Server);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment