@@ -1386,6 +1386,7 @@ impl Bootstrapper<WithCache> {
13861386 let auth_backend = self . project . auth_backend ( & self . context ) ;
13871387 let context = self . context . with_auth ( auth_backend) ;
13881388
1389+ // dioxus_devtools::
13891390 Ok ( Bootstrapper {
13901391 project : self . project ,
13911392 context,
@@ -2140,7 +2141,7 @@ pub async fn run_at_with_shutdown(
21402141 } ;
21412142 std:: panic:: set_hook ( Box :: new ( new_hook) ) ;
21422143 }
2143- axum:: serve ( listener, handler. into_make_service ( ) )
2144+ axum:: serve ( ResetListener :: new ( listener) , handler. into_make_service ( ) )
21442145 . with_graceful_shutdown ( shutdown_signal)
21452146 . await
21462147 . map_err ( StartServerError ) ?;
@@ -2155,6 +2156,121 @@ pub async fn run_at_with_shutdown(
21552156 Ok ( ( ) )
21562157}
21572158
2159+ pub ( crate ) static RELOAD_NOTIFY : std:: sync:: OnceLock < Arc < tokio:: sync:: Notify > > =
2160+ std:: sync:: OnceLock :: new ( ) ;
2161+
2162+ #[ derive( Debug ) ]
2163+ struct ResetListener {
2164+ inner : tokio:: net:: TcpListener ,
2165+ }
2166+
2167+ impl ResetListener {
2168+ fn new ( inner : tokio:: net:: TcpListener ) -> Self {
2169+ Self { inner }
2170+ }
2171+ }
2172+
2173+ impl axum:: serve:: Listener for ResetListener {
2174+ type Io = ResetStream ;
2175+ type Addr = std:: net:: SocketAddr ;
2176+
2177+ async fn accept ( & mut self ) -> ( Self :: Io , Self :: Addr ) {
2178+ loop {
2179+ match self . inner . accept ( ) . await {
2180+ Ok ( ( stream, addr) ) => {
2181+ let notify = RELOAD_NOTIFY . get_or_init ( || Arc :: new ( tokio:: sync:: Notify :: new ( ) ) ) ;
2182+ let notify = notify. clone ( ) ;
2183+ return (
2184+ ResetStream {
2185+ inner : stream,
2186+ reset_fut : Box :: pin ( async move { notify. notified ( ) . await } ) ,
2187+ } ,
2188+ addr,
2189+ ) ;
2190+ }
2191+ Err ( _err) => {
2192+ tokio:: time:: sleep ( std:: time:: Duration :: from_millis ( 50 ) ) . await ;
2193+ }
2194+ }
2195+ }
2196+ }
2197+
2198+ fn local_addr ( & self ) -> std:: io:: Result < Self :: Addr > {
2199+ self . inner . local_addr ( )
2200+ }
2201+ }
2202+
2203+ struct ResetStream {
2204+ inner : tokio:: net:: TcpStream ,
2205+ reset_fut : std:: pin:: Pin < Box < dyn Future < Output = ( ) > + Send > > ,
2206+ }
2207+
2208+ impl Debug for ResetStream {
2209+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
2210+ f. debug_struct ( "ResetStream" )
2211+ . field ( "inner" , & self . inner )
2212+ . finish ( )
2213+ }
2214+ }
2215+
2216+ impl tokio:: io:: AsyncRead for ResetStream {
2217+ fn poll_read (
2218+ mut self : std:: pin:: Pin < & mut Self > ,
2219+ cx : & mut std:: task:: Context < ' _ > ,
2220+ buf : & mut tokio:: io:: ReadBuf < ' _ > ,
2221+ ) -> std:: task:: Poll < std:: io:: Result < ( ) > > {
2222+ if self . reset_fut . as_mut ( ) . poll ( cx) . is_ready ( ) {
2223+ return std:: task:: Poll :: Ready ( Err ( std:: io:: Error :: new (
2224+ std:: io:: ErrorKind :: ConnectionReset ,
2225+ "connection reset by live reload" ,
2226+ ) ) ) ;
2227+ }
2228+ std:: pin:: Pin :: new ( & mut self . inner ) . poll_read ( cx, buf)
2229+ }
2230+ }
2231+
2232+ impl tokio:: io:: AsyncWrite for ResetStream {
2233+ fn poll_write (
2234+ mut self : std:: pin:: Pin < & mut Self > ,
2235+ cx : & mut std:: task:: Context < ' _ > ,
2236+ buf : & [ u8 ] ,
2237+ ) -> std:: task:: Poll < std:: io:: Result < usize > > {
2238+ if self . reset_fut . as_mut ( ) . poll ( cx) . is_ready ( ) {
2239+ return std:: task:: Poll :: Ready ( Err ( std:: io:: Error :: new (
2240+ std:: io:: ErrorKind :: ConnectionReset ,
2241+ "connection reset by live reload" ,
2242+ ) ) ) ;
2243+ }
2244+ std:: pin:: Pin :: new ( & mut self . inner ) . poll_write ( cx, buf)
2245+ }
2246+
2247+ fn poll_flush (
2248+ mut self : std:: pin:: Pin < & mut Self > ,
2249+ cx : & mut std:: task:: Context < ' _ > ,
2250+ ) -> std:: task:: Poll < std:: io:: Result < ( ) > > {
2251+ if self . reset_fut . as_mut ( ) . poll ( cx) . is_ready ( ) {
2252+ return std:: task:: Poll :: Ready ( Err ( std:: io:: Error :: new (
2253+ std:: io:: ErrorKind :: ConnectionReset ,
2254+ "connection reset by live reload" ,
2255+ ) ) ) ;
2256+ }
2257+ std:: pin:: Pin :: new ( & mut self . inner ) . poll_flush ( cx)
2258+ }
2259+
2260+ fn poll_shutdown (
2261+ mut self : std:: pin:: Pin < & mut Self > ,
2262+ cx : & mut std:: task:: Context < ' _ > ,
2263+ ) -> std:: task:: Poll < std:: io:: Result < ( ) > > {
2264+ if self . reset_fut . as_mut ( ) . poll ( cx) . is_ready ( ) {
2265+ return std:: task:: Poll :: Ready ( Err ( std:: io:: Error :: new (
2266+ std:: io:: ErrorKind :: ConnectionReset ,
2267+ "connection reset by live reload" ,
2268+ ) ) ) ;
2269+ }
2270+ std:: pin:: Pin :: new ( & mut self . inner ) . poll_shutdown ( cx)
2271+ }
2272+ }
2273+
21582274#[ derive( Debug , Error ) ]
21592275#[ error( "failed to start the server: {0}" ) ]
21602276pub ( crate ) struct StartServerError ( #[ from] pub ( crate ) std:: io:: Error ) ;
0 commit comments