Skip to content

Commit ba89d50

Browse files
authored
Merge pull request #15 from JackThomson2/main
Remove Mutex lock on Threadpool and routes
2 parents e81fd02 + 307810c commit ba89d50

File tree

5 files changed

+65
-58
lines changed

5 files changed

+65
-58
lines changed

Cargo.lock

+13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ log = "0.4"
3333
async-std = "1.9.0"
3434
async-channel = "1.6.1"
3535
crossbeam = "0.8.1"
36+
dashmap = "4.0.2"
3637

3738
[package.metadata.maturin]
3839
name = "robyn"

src/router.rs

+41-42
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use dashmap::DashMap;
22
// pyo3 modules
33
use pyo3::prelude::*;
44

@@ -62,12 +62,12 @@ impl Route {
6262
// this should ideally be a hashmap of hashmaps but not really
6363

6464
pub struct Router {
65-
get_routes: HashMap<Route, Py<PyAny>>,
66-
post_routes: HashMap<Route, Py<PyAny>>,
67-
put_routes: HashMap<Route, Py<PyAny>>,
68-
update_routes: HashMap<Route, Py<PyAny>>,
69-
delete_routes: HashMap<Route, Py<PyAny>>,
70-
patch_routes: HashMap<Route, Py<PyAny>>,
65+
get_routes: DashMap<Route, Py<PyAny>>,
66+
post_routes: DashMap<Route, Py<PyAny>>,
67+
put_routes: DashMap<Route, Py<PyAny>>,
68+
update_routes: DashMap<Route, Py<PyAny>>,
69+
delete_routes: DashMap<Route, Py<PyAny>>,
70+
patch_routes: DashMap<Route, Py<PyAny>>,
7171
}
7272
// these should be of the type struct and not the type router
7373
// request_stream: &TcpStream,
@@ -78,47 +78,46 @@ pub struct Router {
7878
impl Router {
7979
pub fn new() -> Self {
8080
Self {
81-
get_routes: HashMap::new(),
82-
post_routes: HashMap::new(),
83-
put_routes: HashMap::new(),
84-
update_routes: HashMap::new(),
85-
delete_routes: HashMap::new(),
86-
patch_routes: HashMap::new(),
81+
get_routes: DashMap::new(),
82+
post_routes: DashMap::new(),
83+
put_routes: DashMap::new(),
84+
update_routes: DashMap::new(),
85+
delete_routes: DashMap::new(),
86+
patch_routes: DashMap::new(),
8787
}
8888
}
8989

90-
pub fn add_route(&mut self, route_type: &str, route: Route, handler: Py<PyAny>) {
91-
if route_type == "GET" {
92-
self.get_routes.insert(route, handler);
93-
} else if route_type == "POST" {
94-
self.post_routes.insert(route, handler);
95-
} else if route_type == "PUT" {
96-
self.put_routes.insert(route, handler);
97-
} else if route_type == "UPDATE" {
98-
self.update_routes.insert(route, handler);
99-
} else if route_type == "DELETE" {
100-
self.delete_routes.insert(route, handler);
101-
} else if route_type == "PATCH" {
102-
self.patch_routes.insert(route, handler);
90+
#[inline]
91+
fn get_relevant_map(&self, route: &str) -> Option<&DashMap<Route, Py<PyAny>>> {
92+
match route {
93+
"GET" => Some(&self.get_routes),
94+
"POST" => Some(&self.post_routes),
95+
"PUT" => Some(&self.put_routes),
96+
"UPDATE" => Some(&self.update_routes),
97+
"DELETE" => Some(&self.delete_routes),
98+
"PATCH" => Some(&self.patch_routes),
99+
_ => None,
103100
}
104101
}
105102

106-
pub fn get_route(&self, route: Route) -> Option<&Py<PyAny>> {
107-
let route_type = route.get_route_type();
108-
if route_type == "GET" {
109-
self.get_routes.get(&route)
110-
} else if route_type == "POST" {
111-
self.post_routes.get(&route)
112-
} else if route_type == "PUT" {
113-
self.put_routes.get(&route)
114-
} else if route_type == "UPDATE" {
115-
self.update_routes.get(&route)
116-
} else if route_type == "DELETE" {
117-
self.delete_routes.get(&route)
118-
} else if route_type == "PATCH" {
119-
self.patch_routes.get(&route)
120-
} else {
121-
None
103+
pub fn add_route(&self, route_type: &str, route: Route, handler: Py<PyAny>) {
104+
let table = match self.get_relevant_map(route_type) {
105+
Some(table) => table,
106+
None => return,
107+
};
108+
109+
table.insert(route, handler);
110+
}
111+
112+
pub fn get_route(&self, route: Route) -> Option<Py<PyAny>> {
113+
let table = match self.get_relevant_map(route.get_route_type().as_str()) {
114+
Some(table) => table,
115+
None => return None,
116+
};
117+
118+
match table.get(&route) {
119+
Some(res) => Some(res.clone()),
120+
None => None,
122121
}
123122
}
124123
}

src/server.rs

+8-12
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use pyo3::types::PyAny;
1313
pub struct Server {
1414
port: usize,
1515
number_of_threads: usize,
16-
router: Arc<Mutex<Router>>, //
17-
threadpool: Arc<Mutex<ThreadPool>>,
16+
router: Arc<Router>, //
17+
threadpool: Arc<ThreadPool>,
1818
}
1919

2020
// unsafe impl Send for Server {}
@@ -26,32 +26,29 @@ impl Server {
2626
Self {
2727
port: 5000,
2828
number_of_threads: 1,
29-
router: Arc::new(Mutex::new(Router::new())),
30-
threadpool: Arc::new(Mutex::new(ThreadPool::new(1))),
29+
router: Arc::new(Router::new()),
30+
threadpool: Arc::new(ThreadPool::new(1)),
3131
}
3232
}
3333

3434
pub fn start(&mut self, py: Python) {
3535
let url = format!("127.0.0.1:{}", &self.port);
36-
let get_router = self.router.clone();
36+
let router = self.router.clone();
3737
let pool = self.threadpool.clone();
3838

3939
// thread::spawn -> block on
4040
thread::spawn(move || {
4141
let listener = TcpListener::bind(url).unwrap();
42-
let pool = pool.lock().unwrap();
4342

4443
for stream in listener.incoming() {
4544
let mut stream = stream.unwrap();
4645
let mut buffer = [0; 1024];
4746
stream.read(&mut buffer).unwrap();
4847
let route = Route::new(RouteType::Buffer(Box::new(buffer)));
4948

50-
let f = get_router.lock().unwrap();
51-
let x = f.get_route(route);
52-
match x {
49+
match router.get_route(route) {
5350
Some(a) => {
54-
pool.push_async(&a.clone(), stream);
51+
pool.push_async(a, stream);
5552
}
5653
None => {
5754
print!("No match found");
@@ -72,7 +69,6 @@ impl Server {
7269
pub fn add_route(&mut self, route_type: &str, route: String, handler: Py<PyAny>) {
7370
println!("{} {} ", route_type, route);
7471
let route = Route::new(RouteType::Route((route, route_type.to_string())));
75-
let mut router = self.router.lock().unwrap();
76-
router.add_route(route_type, route, handler);
72+
self.router.add_route(route_type, route, handler);
7773
}
7874
}

src/threadpool.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,9 @@ impl ThreadPool {
9393
ThreadPool { workers, sender }
9494
}
9595

96-
pub fn push_async(&self, f: &Py<PyAny>, stream: TcpStream) {
96+
pub fn push_async(&self, f: Py<PyAny>, stream: TcpStream) {
9797
// println!("Sending a message");
98-
self.sender
99-
.send(Message::NewJob((f.clone(), stream)))
100-
.unwrap();
98+
self.sender.send(Message::NewJob((f, stream))).unwrap();
10199
}
102100
}
103101

0 commit comments

Comments
 (0)