11use std:: convert:: Infallible ;
22use std:: future:: Future ;
33use std:: net:: SocketAddr ;
4- use std:: rc :: Rc ;
4+ use std:: pin :: Pin ;
55
6- use futures:: future:: LocalBoxFuture ;
76use http_body_util:: combinators:: BoxBody ;
87use http_body_util:: { BodyExt as _, Empty , Full } ;
98use hyper:: body:: { Bytes , Incoming } ;
9+ use hyper:: server:: conn:: http1;
1010use hyper:: { Request , Response } ;
1111use hyper_util:: rt:: TokioIo ;
12- use hyper_util:: server:: conn:: auto:: Builder as ServerConnBuilder ;
1312use tokio:: net:: TcpListener ;
14- use tokio:: task:: LocalSet ;
1513
16- use mlua:: {
17- chunk, Error as LuaError , Function , Lua , RegistryKey , String as LuaString , Table , UserData ,
18- UserDataMethods ,
19- } ;
14+ use mlua:: { chunk, Error as LuaError , Function , Lua , String as LuaString , Table , UserData , UserDataMethods } ;
2015
2116/// Wrapper around incoming request that implements UserData
2217struct LuaRequest ( SocketAddr , Request < Incoming > ) ;
@@ -32,33 +27,26 @@ impl UserData for LuaRequest {
3227/// Service that handles incoming requests
3328#[ derive( Clone ) ]
3429pub struct Svc {
35- lua : Rc < Lua > ,
36- handler : Rc < RegistryKey > ,
30+ handler : Function ,
3731 peer_addr : SocketAddr ,
3832}
3933
4034impl Svc {
41- pub fn new ( lua : Rc < Lua > , handler : Rc < RegistryKey > , peer_addr : SocketAddr ) -> Self {
42- Self {
43- lua,
44- handler,
45- peer_addr,
46- }
35+ pub fn new ( handler : Function , peer_addr : SocketAddr ) -> Self {
36+ Self { handler, peer_addr }
4737 }
4838}
4939
5040impl hyper:: service:: Service < Request < Incoming > > for Svc {
5141 type Response = Response < BoxBody < Bytes , Infallible > > ;
5242 type Error = LuaError ;
53- type Future = LocalBoxFuture < ' static , Result < Self :: Response , Self :: Error > > ;
43+ type Future = Pin < Box < dyn Future < Output = Result < Self :: Response , Self :: Error > > + Send > > ;
5444
5545 fn call ( & self , req : Request < Incoming > ) -> Self :: Future {
5646 // If handler returns an error then generate 5xx response
57- let lua = self . lua . clone ( ) ;
58- let handler_key = self . handler . clone ( ) ;
47+ let handler = self . handler . clone ( ) ;
5948 let lua_req = LuaRequest ( self . peer_addr , req) ;
6049 Box :: pin ( async move {
61- let handler: Function = lua. registry_value ( & handler_key) ?;
6250 match handler. call_async :: < _ , Table > ( lua_req) . await {
6351 Ok ( lua_resp) => {
6452 let status = lua_resp. get :: < _ , Option < u16 > > ( "status" ) ?. unwrap_or ( 200 ) ;
@@ -94,10 +82,10 @@ impl hyper::service::Service<Request<Incoming>> for Svc {
9482
9583#[ tokio:: main( flavor = "current_thread" ) ]
9684async fn main ( ) {
97- let lua = Rc :: new ( Lua :: new ( ) ) ;
85+ let lua = Lua :: new ( ) ;
9886
9987 // Create Lua handler function
100- let handler: RegistryKey = lua
88+ let handler = lua
10189 . load ( chunk ! {
10290 function( req)
10391 return {
@@ -111,15 +99,13 @@ async fn main() {
11199 }
112100 end
113101 } )
114- . eval ( )
102+ . eval :: < Function > ( )
115103 . expect ( "Failed to create Lua handler" ) ;
116- let handler = Rc :: new ( handler) ;
117104
118105 let listen_addr = "127.0.0.1:3000" ;
119106 let listener = TcpListener :: bind ( listen_addr) . await . unwrap ( ) ;
120107 println ! ( "Listening on http://{listen_addr}" ) ;
121108
122- let local = LocalSet :: new ( ) ;
123109 loop {
124110 let ( stream, peer_addr) = match listener. accept ( ) . await {
125111 Ok ( x) => x,
@@ -129,29 +115,14 @@ async fn main() {
129115 }
130116 } ;
131117
132- let svc = Svc :: new ( lua. clone ( ) , handler. clone ( ) , peer_addr) ;
133- local
134- . run_until ( async move {
135- let result = ServerConnBuilder :: new ( LocalExec )
136- . http1 ( )
137- . serve_connection ( TokioIo :: new ( stream) , svc)
138- . await ;
139- if let Err ( err) = result {
140- eprintln ! ( "Error serving connection: {err:?}" ) ;
141- }
142- } )
143- . await ;
144- }
145- }
146-
147- #[ derive( Clone , Copy , Debug ) ]
148- struct LocalExec ;
149-
150- impl < F > hyper:: rt:: Executor < F > for LocalExec
151- where
152- F : Future + ' static , // not requiring `Send`
153- {
154- fn execute ( & self , fut : F ) {
155- tokio:: task:: spawn_local ( fut) ;
118+ let svc = Svc :: new ( handler. clone ( ) , peer_addr) ;
119+ tokio:: task:: spawn ( async move {
120+ if let Err ( err) = http1:: Builder :: new ( )
121+ . serve_connection ( TokioIo :: new ( stream) , svc)
122+ . await
123+ {
124+ eprintln ! ( "Error serving connection: {:?}" , err) ;
125+ }
126+ } ) ;
156127 }
157128}
0 commit comments