Skip to content

Instantly share code, notes, and snippets.

@trvswgnr
Last active August 5, 2023 05:47
Show Gist options
  • Save trvswgnr/2b689ba78ae3155c2cddaf02792f2531 to your computer and use it in GitHub Desktop.
Save trvswgnr/2b689ba78ae3155c2cddaf02792f2531 to your computer and use it in GitHub Desktop.
crab sync services
/*
[dependencies]
tokio = {version="1", features=["full"]}
*/
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use tokio::time::sleep;
#[derive(Clone)]
struct User {
id: String,
}
struct Todo {
id: String,
user_id: String,
}
struct SystemB {
users: Mutex<HashMap<String, User>>,
todos: Mutex<HashMap<String, Todo>>,
}
impl SystemB {
async fn get_user(&self, id: &str) -> Option<User> {
let users = self.users.lock().unwrap();
users.get(id).cloned()
}
async fn create_user(&self, id: &str) -> Result<(), &'static str> {
let mut users = self.users.lock().unwrap();
if users.contains_key(id) {
Err("User already exists")
} else {
users.insert(id.to_string(), User { id: id.to_string() });
Ok(())
}
}
async fn create_todo(&self, id: &str, user_id: &str) -> Result<(), &'static str> {
let mut todos = self.todos.lock().unwrap();
if todos.contains_key(id) {
Err("Todo already exists")
} else {
todos.insert(id.to_string(), Todo { id: id.to_string(), user_id: user_id.to_string() });
Ok(())
}
}
}
struct SystemC {
system_b: Arc<SystemB>,
}
impl SystemC {
async fn handle_event(&self, event: &str, id: &str) {
match event {
"user.created" => {
if let Err(e) = self.system_b.create_user(id).await {
eprintln!("Failed to create user: {}", e);
}
}
"todo.created" => {
if self.system_b.get_user(id).await.is_none() {
if let Err(e) = self.retry_create_user(id).await {
eprintln!("Failed to create user: {}", e);
}
}
if let Err(e) = self.retry_create_todo(id, id).await {
eprintln!("Failed to create todo: {}", e);
}
}
_ => {}
}
}
async fn retry_create_user(&self, id: &str) -> Result<(), &'static str> {
let mut retries = 0;
loop {
match self.system_b.create_user(id).await {
Ok(_) => return Ok(()),
Err(e) => {
if retries >= 3 {
return Err(e);
}
retries += 1;
sleep(Duration::from_secs(1)).await;
}
}
}
}
async fn retry_create_todo(&self, id: &str, user_id: &str) -> Result<(), &'static str> {
let mut retries = 0;
loop {
match self.system_b.create_todo(id, user_id).await {
Ok(_) => return Ok(()),
Err(e) => {
if retries >= 3 {
return Err(e);
}
retries += 1;
sleep(Duration::from_secs(1)).await;
}
}
}
}
}
fn main() {
println!("");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment