diff --git a/Cargo.toml b/Cargo.toml index b4840f6..582b256 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,7 @@ required-features = ["async", "serialize", "macros"] [[example]] name = "async_http_server" -required-features = ["async", "macros", "unstable"] +required-features = ["async", "macros"] [[example]] name = "async_tcp_server" diff --git a/examples/async_http_server.rs b/examples/async_http_server.rs index 337eebb..43ae7a9 100644 --- a/examples/async_http_server.rs +++ b/examples/async_http_server.rs @@ -1,6 +1,7 @@ use std::future::Future; use std::net::SocketAddr; use std::pin::Pin; +use std::rc::Rc; use std::task::{Context, Poll}; use hyper::server::conn::AddrStream; @@ -8,8 +9,7 @@ use hyper::service::Service; use hyper::{Body, Request, Response, Server}; use mlua::{ - chunk, Error as LuaError, Function, Lua, OwnedFunction, String as LuaString, Table, UserData, - UserDataMethods, + chunk, Error as LuaError, Function, Lua, String as LuaString, Table, UserData, UserDataMethods, }; struct LuaRequest(SocketAddr, Request); @@ -21,10 +21,7 @@ impl UserData for LuaRequest { } } -#[derive(Clone)] -struct Handler(OwnedFunction); - -pub struct Svc(Handler, SocketAddr); +pub struct Svc(Rc, SocketAddr); impl Service> for Svc { type Response = Response; @@ -37,10 +34,11 @@ impl Service> for Svc { fn call(&mut self, req: Request) -> Self::Future { // If handler returns an error then generate 5xx response - let handler = self.0.clone(); + let lua = self.0.clone(); let lua_req = LuaRequest(self.1, req); Box::pin(async move { - match handler.0.to_ref().call_async::<_, Table>(lua_req).await { + let handler: Function = lua.named_registry_value("http_handler")?; + match handler.call_async::<_, Table>(lua_req).await { Ok(lua_resp) => { let status = lua_resp.get::<_, Option>("status")?.unwrap_or(200); let mut resp = Response::builder().status(status); @@ -74,10 +72,10 @@ impl Service> for Svc { #[tokio::main(flavor = "current_thread")] async fn main() { - let lua = Lua::new(); + let lua = Rc::new(Lua::new()); // Create Lua handler function - let handler_fn: Function = lua + let handler: Function = lua .load(chunk! { function(req) return { @@ -93,10 +91,12 @@ async fn main() { .eval() .expect("cannot create Lua handler"); + // Store it in the Registry + lua.set_named_registry_value("http_handler", handler) + .expect("cannot store Lua handler"); + let addr = ([127, 0, 0, 1], 3000).into(); - let server = Server::bind(&addr) - .executor(LocalExec) - .serve(MakeSvc(Handler(handler_fn.into_owned()))); + let server = Server::bind(&addr).executor(LocalExec).serve(MakeSvc(lua)); println!("Listening on http://{}", addr); @@ -105,7 +105,7 @@ async fn main() { local.run_until(server).await.expect("cannot run server") } -struct MakeSvc(Handler); +struct MakeSvc(Rc); impl Service<&AddrStream> for MakeSvc { type Response = Svc; @@ -117,9 +117,9 @@ impl Service<&AddrStream> for MakeSvc { } fn call(&mut self, stream: &AddrStream) -> Self::Future { - let handler = self.0.clone(); + let lua = self.0.clone(); let remote_addr = stream.remote_addr(); - Box::pin(async move { Ok(Svc(handler, remote_addr)) }) + Box::pin(async move { Ok(Svc(lua, remote_addr)) }) } }