httpq/src/main.rs

105 lines
2.8 KiB
Rust

use rocket::{State, http::Status};
use std::{sync::RwLock, collections::{VecDeque, HashMap}};
#[derive(Debug)]
struct DumbQueue {
queue_map : RwLock<HashMap<String, usize>>,
queues : RwLock<Vec<RwLock<VecDeque<String>>>>,
}
impl DumbQueue {
fn new() -> Self {
DumbQueue {
queue_map: RwLock::new(HashMap::new()),
queues: RwLock::new(vec!()),
}
}
}
#[macro_use] extern crate rocket;
#[get("/")]
fn index(dumb_queue: &State<DumbQueue>) -> String {
let map_reader = &dumb_queue.queue_map.read().unwrap();
let queue_reader = &dumb_queue.queues.read().unwrap();
let queue_count = queue_reader.len();
let mut stats : HashMap<String, usize> = HashMap::new();
for (key,val) in map_reader.iter() {
let reader = queue_reader[*val].read().unwrap();
stats.insert(key.to_string(), reader.len());
drop(reader);
}
format!("Total queues: {}\nCounts: {:?}", queue_count, stats)
}
#[get("/<name>")]
fn get_by_name(name: &str, dumb_queue: &State<DumbQueue>) -> Result<String, Status> {
let queue_map = &dumb_queue.queue_map;
let queues = &dumb_queue.queues;
let map_reader = queue_map.read().unwrap();
match map_reader.get(name) {
Some(i) => {
let index = *i;
drop(map_reader);
match queues.read().unwrap()[index]
.write().unwrap().pop_front() {
Some(res) => Ok(res),
None => return Err(Status::NoContent)
}
}
None => return Err(Status::NotFound)
}
}
#[post("/<name>", data = "<input>")]
fn put_by_name(name: &str, input: &str, dumb_queue: &State<DumbQueue>) {
let queue_map = &dumb_queue.queue_map;
let queues = &dumb_queue.queues;
let mut inserted = false;
let mut inserted_index = usize::MAX;
let map_read = queue_map.read().unwrap();
match map_read.get(&name.to_string()) {
None => {
let new_queue = RwLock::new(VecDeque::with_capacity(1024));
let mut write = new_queue.write().unwrap();
write.push_back(input.to_string());
drop(write);
let mut write = queues.write().unwrap();
write.push(new_queue);
inserted_index = write.len() -1 as usize;
drop(write);
inserted = true;
},
Some(i) => {
let read = queues.read().unwrap();
read[*i].write().unwrap().push_back(input.to_string());
}
}
drop(map_read);
if inserted {
let mut write = queue_map.write().unwrap();
write.insert(name.to_string(), inserted_index);
drop(write);
}
}
#[launch]
fn rocket() -> _ {
rocket::build()
.manage( DumbQueue::new())
.mount("/", routes![index, put_by_name, get_by_name])
}