1
1
use std:: convert:: Infallible ;
2
2
use std:: future:: Future ;
3
3
use std:: net:: SocketAddr ;
4
- use std:: rc :: Rc ;
4
+ use std:: pin :: Pin ;
5
5
6
- use futures:: future:: LocalBoxFuture ;
7
6
use http_body_util:: combinators:: BoxBody ;
8
7
use http_body_util:: { BodyExt as _, Empty , Full } ;
9
8
use hyper:: body:: { Bytes , Incoming } ;
9
+ use hyper:: server:: conn:: http1;
10
10
use hyper:: { Request , Response } ;
11
11
use hyper_util:: rt:: TokioIo ;
12
- use hyper_util:: server:: conn:: auto:: Builder as ServerConnBuilder ;
13
12
use tokio:: net:: TcpListener ;
14
- use tokio:: task:: LocalSet ;
15
13
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 } ;
20
15
21
16
/// Wrapper around incoming request that implements UserData
22
17
struct LuaRequest ( SocketAddr , Request < Incoming > ) ;
@@ -32,33 +27,26 @@ impl UserData for LuaRequest {
32
27
/// Service that handles incoming requests
33
28
#[ derive( Clone ) ]
34
29
pub struct Svc {
35
- lua : Rc < Lua > ,
36
- handler : Rc < RegistryKey > ,
30
+ handler : Function ,
37
31
peer_addr : SocketAddr ,
38
32
}
39
33
40
34
impl 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 }
47
37
}
48
38
}
49
39
50
40
impl hyper:: service:: Service < Request < Incoming > > for Svc {
51
41
type Response = Response < BoxBody < Bytes , Infallible > > ;
52
42
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 > > ;
54
44
55
45
fn call ( & self , req : Request < Incoming > ) -> Self :: Future {
56
46
// 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 ( ) ;
59
48
let lua_req = LuaRequest ( self . peer_addr , req) ;
60
49
Box :: pin ( async move {
61
- let handler: Function = lua. registry_value ( & handler_key) ?;
62
50
match handler. call_async :: < _ , Table > ( lua_req) . await {
63
51
Ok ( lua_resp) => {
64
52
let status = lua_resp. get :: < _ , Option < u16 > > ( "status" ) ?. unwrap_or ( 200 ) ;
@@ -94,10 +82,10 @@ impl hyper::service::Service<Request<Incoming>> for Svc {
94
82
95
83
#[ tokio:: main( flavor = "current_thread" ) ]
96
84
async fn main ( ) {
97
- let lua = Rc :: new ( Lua :: new ( ) ) ;
85
+ let lua = Lua :: new ( ) ;
98
86
99
87
// Create Lua handler function
100
- let handler: RegistryKey = lua
88
+ let handler = lua
101
89
. load ( chunk ! {
102
90
function( req)
103
91
return {
@@ -111,15 +99,13 @@ async fn main() {
111
99
}
112
100
end
113
101
} )
114
- . eval ( )
102
+ . eval :: < Function > ( )
115
103
. expect ( "Failed to create Lua handler" ) ;
116
- let handler = Rc :: new ( handler) ;
117
104
118
105
let listen_addr = "127.0.0.1:3000" ;
119
106
let listener = TcpListener :: bind ( listen_addr) . await . unwrap ( ) ;
120
107
println ! ( "Listening on http://{listen_addr}" ) ;
121
108
122
- let local = LocalSet :: new ( ) ;
123
109
loop {
124
110
let ( stream, peer_addr) = match listener. accept ( ) . await {
125
111
Ok ( x) => x,
@@ -129,29 +115,14 @@ async fn main() {
129
115
}
130
116
} ;
131
117
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
+ } ) ;
156
127
}
157
128
}
0 commit comments