Skip to content

Commit

Permalink
fix: various improvements in the index method
Browse files Browse the repository at this point in the history
  • Loading branch information
AntoineRR committed Nov 21, 2022
1 parent 1bb9940 commit 1a58f19
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 153 deletions.
50 changes: 18 additions & 32 deletions src/executors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
/// i.e. the functions that have the responsibility of parsing and executing functions.
use crate::io_helpers::read_file;

use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Arc;

use actix_web::{http::Method, web, HttpRequest};
Expand All @@ -25,8 +23,8 @@ pub async fn execute_middleware_function<'a>(
payload: &mut web::Payload,
headers: &HashMap<String, String>,
req: &HttpRequest,
route_params: HashMap<String, String>,
queries: Rc<RefCell<HashMap<String, String>>>,
route_params: &HashMap<String, String>,
queries: &HashMap<String, String>,
number_of_params: u8,
) -> Result<HashMap<String, HashMap<String, String>>> {
// TODO:
Expand Down Expand Up @@ -55,20 +53,14 @@ pub async fn execute_middleware_function<'a>(
// request object accessible while creating routes
let mut request = HashMap::new();

let mut queries_clone: HashMap<String, String> = HashMap::new();

for (key, value) in (*queries).borrow().clone() {
queries_clone.insert(key, value);
}

match function {
PyFunction::CoRoutine(handler) => {
let output = Python::with_gil(|py| {
let handler = handler.as_ref(py);
request.insert("params", route_params.into_py(py));
request.insert("queries", queries_clone.into_py(py));
request.insert("params", route_params.to_object(py));
request.insert("queries", queries.to_object(py));
// is this a bottleneck again?
request.insert("headers", headers.clone().into_py(py));
request.insert("headers", headers.to_object(py));
// request.insert("body", data.into_py(py));

// this makes the request object to be accessible across every route
Expand Down Expand Up @@ -100,10 +92,10 @@ pub async fn execute_middleware_function<'a>(
// let's wrap the output in a future?
let output: Result<HashMap<String, HashMap<String, String>>> = Python::with_gil(|py| {
let handler = handler.as_ref(py);
request.insert("params", route_params.into_py(py));
request.insert("queries", queries_clone.into_py(py));
request.insert("params", route_params.to_object(py));
request.insert("queries", queries.to_object(py));
// is this a bottleneck again?
request.insert("headers", headers.clone().into_py(py));
request.insert("headers", headers.to_object(py));
request.insert("body", data.into_py(py));

let output: PyResult<&PyAny> = match number_of_params {
Expand Down Expand Up @@ -185,10 +177,10 @@ pub async fn execute_function(
pub async fn execute_http_function(
function: PyFunction,
payload: &mut web::Payload,
headers: HashMap<String, String>,
headers: &HashMap<String, String>,
req: &HttpRequest,
route_params: HashMap<String, String>,
queries: Rc<RefCell<HashMap<String, String>>>,
route_params: &HashMap<String, String>,
queries: &HashMap<String, String>,
number_of_params: u8,
// need to change this to return a response struct
// create a custom struct for this
Expand Down Expand Up @@ -216,19 +208,13 @@ pub async fn execute_http_function(
// request object accessible while creating routes
let mut request = HashMap::new();

let mut queries_clone: HashMap<String, String> = HashMap::new();

for (key, value) in (*queries).borrow().clone() {
queries_clone.insert(key, value);
}

match function {
PyFunction::CoRoutine(handler) => {
let output = Python::with_gil(|py| {
let handler = handler.as_ref(py);
request.insert("params", route_params.into_py(py));
request.insert("queries", queries_clone.into_py(py));
request.insert("headers", headers.into_py(py));
request.insert("params", route_params.to_object(py));
request.insert("queries", queries.to_object(py));
request.insert("headers", headers.to_object(py));
let data = data.into_py(py);
request.insert("body", data);

Expand Down Expand Up @@ -265,8 +251,8 @@ pub async fn execute_http_function(
PyFunction::SyncFunction(handler) => {
Python::with_gil(|py| {
let handler = handler.as_ref(py);
request.insert("params", route_params.into_py(py));
request.insert("headers", headers.into_py(py));
request.insert("params", route_params.to_object(py));
request.insert("headers", headers.to_object(py));
let data = data.into_py(py);
request.insert("body", data);

Expand All @@ -288,12 +274,12 @@ pub async fn execute_http_function(
pub async fn execute_event_handler(
event_handler: Option<Arc<PyFunction>>,
task_locals: &TaskLocals,
) -> Result<(), Box<dyn std::error::Error>> {
) -> Result<()> {
if let Some(handler) = event_handler {
match &(*handler) {
PyFunction::SyncFunction(function) => {
debug!("Startup event handler");
Python::with_gil(|py| -> Result<(), Box<dyn std::error::Error>> {
Python::with_gil(|py| -> Result<()> {
function.call0(py)?;
Ok(())
})?;
Expand Down
6 changes: 3 additions & 3 deletions src/io_helpers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use std::collections::HashMap;

use std::fs::File;
use std::io::Read;

use actix_web::HttpResponseBuilder;
use anyhow::Result;

// this should be something else
// probably inside the submodule of the http router
#[inline]
pub fn apply_headers(response: &mut HttpResponseBuilder, headers: HashMap<String, String>) {
pub fn apply_headers(response: &mut HttpResponseBuilder, headers: &HashMap<String, String>) {
for (key, val) in (headers).iter() {
response.insert_header((key.clone(), val.clone()));
}
Expand All @@ -21,7 +21,7 @@ pub fn apply_headers(response: &mut HttpResponseBuilder, headers: HashMap<String
/// * `file_path` - The file path that we want the function to read
///
// ideally this should be async
pub fn read_file(file_path: &str) -> Result<String, Box<dyn std::error::Error>> {
pub fn read_file(file_path: &str) -> Result<String> {
let mut file = File::open(file_path)?;
let mut buf = vec![];
file.read_to_end(&mut buf)?;
Expand Down
37 changes: 15 additions & 22 deletions src/request_handler/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
use crate::executors::{execute_http_function, execute_middleware_function};

use log::debug;
use std::rc::Rc;
use std::collections::HashMap;
use std::str::FromStr;
use std::{cell::RefCell, collections::HashMap};

use actix_web::{web, HttpRequest, HttpResponse, HttpResponseBuilder};
// pyO3 module
use crate::types::PyFunction;

#[inline]
pub fn apply_headers(response: &mut HttpResponseBuilder, headers: HashMap<String, String>) {
for (key, val) in (headers).iter() {
pub fn apply_headers(response: &mut HttpResponseBuilder, headers: &HashMap<String, String>) {
for (key, val) in headers.iter() {
response.insert_header((key.clone(), val.clone()));
}
}
Expand All @@ -30,16 +29,16 @@ pub fn apply_headers(response: &mut HttpResponseBuilder, headers: HashMap<String
pub async fn handle_http_request(
function: PyFunction,
number_of_params: u8,
headers: HashMap<String, String>,
headers: &HashMap<String, String>,
payload: &mut web::Payload,
req: &HttpRequest,
route_params: HashMap<String, String>,
queries: Rc<RefCell<HashMap<String, String>>>,
route_params: &HashMap<String, String>,
queries: &HashMap<String, String>,
) -> HttpResponse {
let contents = match execute_http_function(
function,
payload,
headers.clone(),
headers,
req,
route_params,
queries,
Expand All @@ -51,7 +50,7 @@ pub async fn handle_http_request(
Err(err) => {
debug!("Error: {:?}", err);
let mut response = HttpResponse::InternalServerError();
apply_headers(&mut response, headers.clone());
apply_headers(&mut response, headers);
return response.finish();
}
};
Expand All @@ -60,11 +59,8 @@ pub async fn handle_http_request(
let status_code =
actix_http::StatusCode::from_str(contents.get("status_code").unwrap()).unwrap();

let response_headers: HashMap<String, String> = match contents.get("headers") {
Some(headers) => {
let h: HashMap<String, String> = serde_json::from_str(headers).unwrap();
h
}
let response_headers = match contents.get("headers") {
Some(headers) => serde_json::from_str(headers).unwrap(),
None => HashMap::new(),
};

Expand All @@ -74,7 +70,7 @@ pub async fn handle_http_request(
);

let mut response = HttpResponse::build(status_code);
apply_headers(&mut response, response_headers);
apply_headers(&mut response, &response_headers);
let final_response = if !body.is_empty() {
response.body(body)
} else {
Expand All @@ -95,10 +91,10 @@ pub async fn handle_http_middleware_request(
headers: &HashMap<String, String>,
payload: &mut web::Payload,
req: &HttpRequest,
route_params: HashMap<String, String>,
queries: Rc<RefCell<HashMap<String, String>>>,
route_params: &HashMap<String, String>,
queries: &HashMap<String, String>,
) -> HashMap<String, HashMap<String, String>> {
let contents = match execute_middleware_function(
let contents = execute_middleware_function(
function,
payload,
headers,
Expand All @@ -108,10 +104,7 @@ pub async fn handle_http_middleware_request(
number_of_params,
)
.await
{
Ok(res) => res,
Err(_err) => HashMap::new(),
};
.unwrap_or_default();

debug!("These are the middleware response {:?}", contents);
contents
Expand Down
34 changes: 13 additions & 21 deletions src/routers/const_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::sync::RwLock;
use crate::executors::execute_function;
use anyhow::Context;
use log::debug;
use matchit::Router as MatchItRouter;
use pyo3::prelude::*;
use pyo3::types::PyAny;

Expand All @@ -15,7 +16,7 @@ use anyhow::{Error, Result};

use super::Router;

type RouteMap = RwLock<matchit::Router<String>>;
type RouteMap = RwLock<MatchItRouter<String>>;

/// Contains the thread safe hashmaps of different routes
pub struct ConstRouter {
Expand Down Expand Up @@ -58,8 +59,8 @@ impl Router<String, Method> for ConstRouter {
Ok(())
}

fn get_route(&self, route_method: Method, route: &str) -> Option<String> {
let table = self.routes.get(&route_method)?;
fn get_route(&self, route_method: &Method, route: &str) -> Option<String> {
let table = self.routes.get(route_method)?;
let route_map = table.read().ok()?;

match route_map.at(route) {
Expand All @@ -72,24 +73,15 @@ impl Router<String, Method> for ConstRouter {
impl ConstRouter {
pub fn new() -> Self {
let mut routes = HashMap::new();
routes.insert(Method::GET, Arc::new(RwLock::new(matchit::Router::new())));
routes.insert(Method::POST, Arc::new(RwLock::new(matchit::Router::new())));
routes.insert(Method::PUT, Arc::new(RwLock::new(matchit::Router::new())));
routes.insert(
Method::DELETE,
Arc::new(RwLock::new(matchit::Router::new())),
);
routes.insert(Method::PATCH, Arc::new(RwLock::new(matchit::Router::new())));
routes.insert(Method::HEAD, Arc::new(RwLock::new(matchit::Router::new())));
routes.insert(
Method::OPTIONS,
Arc::new(RwLock::new(matchit::Router::new())),
);
routes.insert(
Method::CONNECT,
Arc::new(RwLock::new(matchit::Router::new())),
);
routes.insert(Method::TRACE, Arc::new(RwLock::new(matchit::Router::new())));
routes.insert(Method::GET, Arc::new(RwLock::new(MatchItRouter::new())));
routes.insert(Method::POST, Arc::new(RwLock::new(MatchItRouter::new())));
routes.insert(Method::PUT, Arc::new(RwLock::new(MatchItRouter::new())));
routes.insert(Method::DELETE, Arc::new(RwLock::new(MatchItRouter::new())));
routes.insert(Method::PATCH, Arc::new(RwLock::new(MatchItRouter::new())));
routes.insert(Method::HEAD, Arc::new(RwLock::new(MatchItRouter::new())));
routes.insert(Method::OPTIONS, Arc::new(RwLock::new(MatchItRouter::new())));
routes.insert(Method::CONNECT, Arc::new(RwLock::new(MatchItRouter::new())));
routes.insert(Method::TRACE, Arc::new(RwLock::new(MatchItRouter::new())));
Self { routes }
}

Expand Down
4 changes: 2 additions & 2 deletions src/routers/http_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ impl Router<((PyFunction, u8), HashMap<String, String>), Method> for HttpRouter

fn get_route(
&self,
route_method: Method,
route_method: &Method,
route: &str,
) -> Option<((PyFunction, u8), HashMap<String, String>)> {
let table = self.routes.get(&route_method)?;
let table = self.routes.get(route_method)?;

let table_lock = table.read().ok()?;
let res = table_lock.at(route).ok()?;
Expand Down
40 changes: 20 additions & 20 deletions src/routers/middleware_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,22 @@ use std::collections::HashMap;
use std::sync::RwLock;
// pyo3 modules
use crate::types::PyFunction;
use anyhow::{Context, Error, Result};
use matchit::Router as MatchItRouter;
use pyo3::prelude::*;
use pyo3::types::PyAny;

use anyhow::{Context, Error, Result};

use crate::routers::types::MiddlewareRoute;

use super::Router;

type RouteMap = RwLock<matchit::Router<(PyFunction, u8)>>;
type RouteMap = RwLock<MatchItRouter<(PyFunction, u8)>>;

/// Contains the thread safe hashmaps of different routes
pub struct MiddlewareRouter {
routes: HashMap<MiddlewareRoute, RouteMap>,
}

impl MiddlewareRouter {
pub fn new() -> Self {
let mut routes = HashMap::new();
routes.insert(
MiddlewareRoute::BeforeRequest,
RwLock::new(matchit::Router::new()),
);
routes.insert(
MiddlewareRoute::AfterRequest,
RwLock::new(matchit::Router::new()),
);
Self { routes }
}
}

impl Router<((PyFunction, u8), HashMap<String, String>), MiddlewareRoute> for MiddlewareRouter {
fn add_route(
&self,
Expand Down Expand Up @@ -63,10 +48,10 @@ impl Router<((PyFunction, u8), HashMap<String, String>), MiddlewareRoute> for Mi

fn get_route(
&self,
route_method: MiddlewareRoute,
route_method: &MiddlewareRoute,
route: &str,
) -> Option<((PyFunction, u8), HashMap<String, String>)> {
let table = self.routes.get(&route_method)?;
let table = self.routes.get(route_method)?;

let table_lock = table.read().ok()?;
let res = table_lock.at(route).ok()?;
Expand All @@ -78,3 +63,18 @@ impl Router<((PyFunction, u8), HashMap<String, String>), MiddlewareRoute> for Mi
Some((res.value.to_owned(), route_params))
}
}

impl MiddlewareRouter {
pub fn new() -> Self {
let mut routes = HashMap::new();
routes.insert(
MiddlewareRoute::BeforeRequest,
RwLock::new(MatchItRouter::new()),
);
routes.insert(
MiddlewareRoute::AfterRequest,
RwLock::new(MatchItRouter::new()),
);
Self { routes }
}
}
Loading

0 comments on commit 1a58f19

Please sign in to comment.