Skip to content

Commit

Permalink
remove Send and Sync bounds from Rust SDK router (#2198)
Browse files Browse the repository at this point in the history
These bounds were preventing users from calling async functions which use
`http::executor` since it uses `Rc<RefCell<_>>` internally, which is neither
`Send` nor `Sync`.

Signed-off-by: Joel Dice <[email protected]>
  • Loading branch information
dicej authored Dec 21, 2023
1 parent b435f83 commit d723301
Showing 1 changed file with 87 additions and 87 deletions.
174 changes: 87 additions & 87 deletions sdk/rust/src/http/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@ use std::{collections::HashMap, fmt::Display};
///
/// This trait is automatically implemented for `Fn` types, and so is rarely implemented
/// directly by Spin users.
#[async_trait]
pub trait Handler: Send + Sync {
#[async_trait(?Send)]
pub trait Handler {
/// Invoke the handler.
async fn handle(&self, req: Request, params: Params) -> Response;
}

#[async_trait]
#[async_trait(?Send)]
impl Handler for Box<dyn Handler> {
async fn handle(&self, req: Request, params: Params) -> Response {
self.as_ref().handle(req, params).await
}
}

#[async_trait]
#[async_trait(?Send)]
impl<F, Fut> Handler for F
where
F: Fn(Request, Params) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Response> + Send + 'static,
F: Fn(Request, Params) -> Fut + 'static,
Fut: Future<Output = Response> + 'static,
{
async fn handle(&self, req: Request, params: Params) -> Response {
let fut = (self)(req, params);
Expand Down Expand Up @@ -154,10 +154,10 @@ impl Router {
/// Register a handler at the path for all methods.
pub fn any<F, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Resp + 'static + Send + Sync,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Resp + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
let handler = move |req, params| {
let res = TryFromRequest::try_from_request(req).map(|r| handler(r, params));
Expand All @@ -175,11 +175,11 @@ impl Router {
/// Register an async handler at the path for all methods.
pub fn any_async<F, Fut, I, O>(&mut self, path: &str, handler: F)
where
F: Fn(I, Params) -> Fut + 'static + Send + Sync,
Fut: Future<Output = O> + Send + 'static,
I: TryFromRequest + 'static + Send,
I::Error: IntoResponse + Send + 'static,
O: IntoResponse + 'static + Send,
F: Fn(I, Params) -> Fut + 'static,
Fut: Future<Output = O> + 'static,
I: TryFromRequest + 'static,
I::Error: IntoResponse + 'static,
O: IntoResponse + 'static,
{
let handler = move |req, params| {
let res = TryFromRequest::try_from_request(req).map(|r| handler(r, params));
Expand All @@ -197,10 +197,10 @@ impl Router {
/// Register a handler at the path for the specified HTTP method.
pub fn add<F, Req, Resp>(&mut self, path: &str, method: Method, handler: F)
where
F: Fn(Req, Params) -> Resp + 'static + Send + Sync,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Resp + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
let handler = move |req, params| {
let res = TryFromRequest::try_from_request(req).map(|r| handler(r, params));
Expand All @@ -218,11 +218,11 @@ impl Router {
/// Register an async handler at the path for the specified HTTP method.
pub fn add_async<F, Fut, I, O>(&mut self, path: &str, method: Method, handler: F)
where
F: Fn(I, Params) -> Fut + 'static + Send + Sync,
Fut: Future<Output = O> + Send + 'static,
I: TryFromRequest + 'static + Send,
I::Error: IntoResponse + Send + 'static,
O: IntoResponse + 'static + Send,
F: Fn(I, Params) -> Fut + 'static,
Fut: Future<Output = O> + 'static,
I: TryFromRequest + 'static,
I::Error: IntoResponse + 'static,
O: IntoResponse + 'static,
{
let handler = move |req, params| {
let res = TryFromRequest::try_from_request(req).map(|r| handler(r, params));
Expand All @@ -244,160 +244,160 @@ impl Router {
/// Register a handler at the path for the HTTP GET method.
pub fn get<F, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Resp + 'static + Send + Sync,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Resp + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add(path, Method::Get, handler)
}

/// Register an async handler at the path for the HTTP GET method.
pub fn get_async<F, Fut, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Fut + 'static + Send + Sync,
Fut: Future<Output = Resp> + Send + 'static,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Fut + 'static,
Fut: Future<Output = Resp> + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add_async(path, Method::Get, handler)
}

/// Register a handler at the path for the HTTP HEAD method.
pub fn head<F, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Resp + 'static + Send + Sync,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Resp + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add(path, Method::Head, handler)
}

/// Register an async handler at the path for the HTTP HEAD method.
pub fn head_async<F, Fut, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Fut + 'static + Send + Sync,
Fut: Future<Output = Resp> + Send + 'static,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Fut + 'static,
Fut: Future<Output = Resp> + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add_async(path, Method::Head, handler)
}

/// Register a handler at the path for the HTTP POST method.
pub fn post<F, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Resp + 'static + Send + Sync,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Resp + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add(path, Method::Post, handler)
}

/// Register an async handler at the path for the HTTP POST method.
pub fn post_async<F, Fut, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Fut + 'static + Send + Sync,
Fut: Future<Output = Resp> + Send + 'static,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Fut + 'static,
Fut: Future<Output = Resp> + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add_async(path, Method::Post, handler)
}

/// Register a handler at the path for the HTTP DELETE method.
pub fn delete<F, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Resp + 'static + Send + Sync,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Resp + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add(path, Method::Delete, handler)
}

/// Register an async handler at the path for the HTTP DELETE method.
pub fn delete_async<F, Fut, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Fut + 'static + Send + Sync,
Fut: Future<Output = Resp> + Send + 'static,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Fut + 'static,
Fut: Future<Output = Resp> + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add_async(path, Method::Delete, handler)
}

/// Register a handler at the path for the HTTP PUT method.
pub fn put<F, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Resp + 'static + Send + Sync,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Resp + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add(path, Method::Put, handler)
}

/// Register an async handler at the path for the HTTP PUT method.
pub fn put_async<F, Fut, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Fut + 'static + Send + Sync,
Fut: Future<Output = Resp> + Send + 'static,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Fut + 'static,
Fut: Future<Output = Resp> + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add_async(path, Method::Put, handler)
}

/// Register a handler at the path for the HTTP PATCH method.
pub fn patch<F, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Resp + 'static + Send + Sync,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Resp + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add(path, Method::Patch, handler)
}

/// Register an async handler at the path for the HTTP PATCH method.
pub fn patch_async<F, Fut, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Fut + 'static + Send + Sync,
Fut: Future<Output = Resp> + Send + 'static,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Fut + 'static,
Fut: Future<Output = Resp> + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add_async(path, Method::Patch, handler)
}

/// Register a handler at the path for the HTTP OPTIONS method.
pub fn options<F, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Resp + 'static + Send + Sync,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Resp + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add(path, Method::Options, handler)
}

/// Register an async handler at the path for the HTTP OPTIONS method.
pub fn options_async<F, Fut, Req, Resp>(&mut self, path: &str, handler: F)
where
F: Fn(Req, Params) -> Fut + 'static + Send + Sync,
Fut: Future<Output = Resp> + Send + 'static,
Req: TryFromRequest + 'static + Send,
Req::Error: IntoResponse + Send + 'static,
Resp: IntoResponse + 'static + Send,
F: Fn(Req, Params) -> Fut + 'static,
Fut: Future<Output = Resp> + 'static,
Req: TryFromRequest + 'static,
Req::Error: IntoResponse + 'static,
Resp: IntoResponse + 'static,
{
self.add_async(path, Method::Options, handler)
}
Expand Down

0 comments on commit d723301

Please sign in to comment.