Skip to content

Commit

Permalink
Code cleanup using PyFunction type
Browse files Browse the repository at this point in the history
  • Loading branch information
sansyrox committed Jun 23, 2021
1 parent 7e1b4a6 commit 9470d78
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 46 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
#python cache
*__pycache__
*tags

# DS_Store
*.DS_Store
18 changes: 10 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ crate-type = ["cdylib", "rlib"]
version = "0.13.2"
features = ["extension-module"]

[patch.crates-io]
pyo3 = {git = "https://github.com/PyO3/pyo3/",branch = "main", features = ["extension-module"]}

[dependencies.pyo3-asyncio]
version = "0.13.3"
features =["tokio-runtime"]
Expand Down
42 changes: 14 additions & 28 deletions src/process.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,32 @@
use tokio::io::AsyncWriteExt;
use tokio::net::TcpStream;
// pyO3 module
use crate::types::PyFunction;
use pyo3::prelude::*;
use pyo3::types::{PyAny, PyDict};

enum PyFunction {
CoRoutine(Py<PyAny>),
SyncFunction(Py<PyAny>),
}

pub async fn handle_message(process_object: Py<PyAny>, mut stream: TcpStream) {
let function: PyFunction = Python::with_gil(|py| {
let process_object_wrapper: &PyAny = process_object.as_ref(py);
let py_dict = process_object_wrapper.downcast::<PyDict>().unwrap();
let is_async: bool = py_dict.get_item("is_async").unwrap().extract().unwrap();
let handler: &PyAny = py_dict.get_item("handler").unwrap();
if is_async {
let coro = handler.call0().unwrap();
PyFunction::CoRoutine(coro.into())
} else {
PyFunction::SyncFunction(handler.into())
}
});
// Handle message fetches the response function
// function is the response function fetched from the router
// tokio task is spawned depending on the type of function fetched (Sync/Async)

pub async fn handle_message(function: PyFunction, mut stream: TcpStream) {
let contents = match function {
PyFunction::CoRoutine(coro) => {
let x = Python::with_gil(|py| {
let x = coro.as_ref(py);
pyo3_asyncio::into_future(x).unwrap()
PyFunction::CoRoutine(handler) => {
let output = Python::with_gil(|py| {
let coro = handler.as_ref(py).call0().unwrap();
pyo3_asyncio::into_future(coro).unwrap()
});
let output = x.await.unwrap();
let output = output.await.unwrap();
Python::with_gil(|py| -> PyResult<String> {
let contents: &str = output.extract(py).unwrap();
Ok(contents.to_string())
})
.unwrap()
}
PyFunction::SyncFunction(x) => tokio::task::spawn_blocking(move || {
PyFunction::SyncFunction(handler) => tokio::task::spawn_blocking(move || {
Python::with_gil(|py| {
let y = x.as_ref(py);
let s: &str = (&y).call0().unwrap().extract().unwrap();
String::from(s)
let handler = handler.as_ref(py);
let output: &str = (&handler).call0().unwrap().extract().unwrap();
output.to_string()
})
})
.await
Expand Down
33 changes: 23 additions & 10 deletions src/router.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use dashmap::DashMap;
// pyo3 modules
use crate::types::PyFunction;
use pyo3::prelude::*;
use pyo3::types::{PyAny, PyDict};

pub enum RouteType {
Route((String, String)),
Expand Down Expand Up @@ -61,12 +63,12 @@ impl Route {
// this should ideally be a hashmap of hashmaps but not really

pub struct Router {
get_routes: DashMap<Route, Py<PyAny>>,
post_routes: DashMap<Route, Py<PyAny>>,
put_routes: DashMap<Route, Py<PyAny>>,
update_routes: DashMap<Route, Py<PyAny>>,
delete_routes: DashMap<Route, Py<PyAny>>,
patch_routes: DashMap<Route, Py<PyAny>>,
get_routes: DashMap<Route, PyFunction>,
post_routes: DashMap<Route, PyFunction>,
put_routes: DashMap<Route, PyFunction>,
update_routes: DashMap<Route, PyFunction>,
delete_routes: DashMap<Route, PyFunction>,
patch_routes: DashMap<Route, PyFunction>,
}
// these should be of the type struct and not the type router
// request_stream: &TcpStream,
Expand All @@ -87,7 +89,7 @@ impl Router {
}

#[inline]
fn get_relevant_map(&self, route: &str) -> Option<&DashMap<Route, Py<PyAny>>> {
fn get_relevant_map(&self, route: &str) -> Option<&DashMap<Route, PyFunction>> {
match route {
"GET" => Some(&self.get_routes),
"POST" => Some(&self.post_routes),
Expand All @@ -104,11 +106,22 @@ impl Router {
Some(table) => table,
None => return,
};

table.insert(route, handler);
Python::with_gil(|py| {
let process_object_wrapper: &PyAny = handler.as_ref(py);
let py_dict = process_object_wrapper.downcast::<PyDict>().unwrap();
let is_async: bool = py_dict.get_item("is_async").unwrap().extract().unwrap();
let handler: &PyAny = py_dict.get_item("handler").unwrap();
let route_function = if is_async {
// let coro = handler.call0().unwrap();
PyFunction::CoRoutine(handler.into())
} else {
PyFunction::SyncFunction(handler.into())
};
table.insert(route, route_function);
});
}

pub fn get_route(&self, route: Route) -> Option<Py<PyAny>> {
pub fn get_route(&self, route: Route) -> Option<PyFunction> {
let table = self.get_relevant_map(route.get_route_type().as_str())?;
Some(table.get(&route)?.clone())
}
Expand Down
6 changes: 6 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
use pyo3::prelude::*;

#[derive(Debug, Clone)]
pub enum PyFunction {
CoRoutine(Py<PyAny>),
SyncFunction(Py<PyAny>),
}

0 comments on commit 9470d78

Please sign in to comment.