hyperlane/server/
impl.rs

1use crate::*;
2
3/// Provides a default implementation for ServerInner.
4impl Default for ServerInner {
5    /// Creates a new ServerInner instance with default values.
6    ///
7    /// # Returns
8    ///
9    /// - `Self` - A new instance with default configuration.
10    #[inline(always)]
11    fn default() -> Self {
12        Self {
13            config: ServerConfigInner::default(),
14            task_panic: vec![],
15            request_error: vec![],
16            route_matcher: RouteMatcher::new(),
17            request_middleware: vec![],
18            response_middleware: vec![],
19        }
20    }
21}
22
23/// Implements the `PartialEq` trait for `ServerInner`.
24///
25/// This allows for comparing two `ServerInner` instances for equality.
26impl PartialEq for ServerInner {
27    /// Checks if two `ServerInner` instances are equal.
28    ///
29    /// # Arguments
30    ///
31    /// - `&Self`- The other `ServerInner` instance to compare against.
32    ///
33    /// # Returns
34    ///
35    /// - `bool`- `true` if the instances are equal, `false` otherwise.
36    fn eq(&self, other: &Self) -> bool {
37        self.config == other.config
38            && self.route_matcher == other.route_matcher
39            && self.task_panic.len() == other.task_panic.len()
40            && self.request_error.len() == other.request_error.len()
41            && self.request_middleware.len() == other.request_middleware.len()
42            && self.response_middleware.len() == other.response_middleware.len()
43            && self
44                .task_panic
45                .iter()
46                .zip(other.task_panic.iter())
47                .all(|(a, b)| Arc::ptr_eq(a, b))
48            && self
49                .request_error
50                .iter()
51                .zip(other.request_error.iter())
52                .all(|(a, b)| Arc::ptr_eq(a, b))
53            && self
54                .request_middleware
55                .iter()
56                .zip(other.request_middleware.iter())
57                .all(|(a, b)| Arc::ptr_eq(a, b))
58            && self
59                .response_middleware
60                .iter()
61                .zip(other.response_middleware.iter())
62                .all(|(a, b)| Arc::ptr_eq(a, b))
63    }
64}
65
66/// Implements the `Eq` trait for `ServerInner`.
67///
68/// This indicates that `ServerInner` has a total equality relation.
69impl Eq for ServerInner {}
70
71/// Implements the `PartialEq` trait for `Server`.
72///
73/// This allows for comparing two `Server` instances for equality.
74impl PartialEq for Server {
75    /// Checks if two `Server` instances are equal.
76    ///
77    /// # Arguments
78    ///
79    /// - `&Self`- The other `Server` instance to compare against.
80    ///
81    /// # Returns
82    ///
83    /// - `bool`- `true` if the instances are equal, `false` otherwise.
84    #[inline(always)]
85    fn eq(&self, other: &Self) -> bool {
86        if Arc::ptr_eq(self.get_0(), other.get_0()) {
87            return true;
88        }
89        if let (Ok(s), Ok(o)) = (self.get_0().try_read(), other.get_0().try_read()) {
90            *s == *o
91        } else {
92            false
93        }
94    }
95}
96
97/// Implements the `Eq` trait for `Server`.
98///
99/// This indicates that `Server` has a total equality relation.
100impl Eq for Server {}
101
102/// Manages the state for handling a single connection, including the stream and context.
103///
104/// This struct provides a convenient way to pass around the necessary components
105/// for processing a request or WebSocket frame.
106impl HandlerState {
107    /// Creates a new HandlerState instance.
108    ///
109    /// # Arguments
110    ///
111    /// - `&'a ArcRwLockStream` - The network stream.
112    /// - `RequestConfig` - The request config.
113    ///
114    /// # Returns
115    ///
116    /// - `Self` - The newly created hook state.
117    #[inline(always)]
118    pub(super) fn new(stream: ArcRwLockStream, request_config: RequestConfig) -> Self {
119        Self {
120            stream,
121            request_config,
122        }
123    }
124}
125
126/// Represents the server, providing methods to configure and run it.
127///
128/// This struct wraps the `ServerInner` configuration and routing logic,
129/// offering a high-level API for setting up the HTTP and WebSocket server.
130impl Server {
131    /// Creates a new Server instance with default settings.
132    ///
133    /// # Returns
134    ///
135    /// - `Self` - A new Server instance.
136    pub async fn new() -> Self {
137        let server: ServerInner = ServerInner::default();
138        Self(arc_rwlock(server))
139    }
140
141    /// Creates a new Server instance from a configuration.
142    ///
143    /// # Arguments
144    ///
145    /// - `ServerConfig` - The server configuration.
146    ///
147    /// # Returns
148    ///
149    /// - `Self` - A new Server instance.
150    pub async fn from(config: ServerConfig) -> Self {
151        let server: Self = Self::new().await;
152        server.config(config).await;
153        server
154    }
155
156    /// Acquires a read lock on the inner server data.
157    ///
158    /// # Returns
159    ///
160    /// - `ServerStateReadGuard` - The read guard for ServerInner.
161    pub(super) async fn read(&self) -> ServerStateReadGuard<'_> {
162        self.get_0().read().await
163    }
164
165    /// Acquires a write lock on the inner server data.
166    ///
167    /// # Returns
168    ///
169    /// - `ServerStateWriteGuard` - The write guard for ServerInner.
170    async fn write(&self) -> ServerStateWriteGuard<'_> {
171        self.get_0().write().await
172    }
173
174    /// Gets the route matcher.
175    ///
176    /// # Returns
177    /// - `RouteMatcher` - The route matcher.
178    pub async fn get_route_matcher(&self) -> RouteMatcher {
179        self.read().await.get_route_matcher().clone()
180    }
181
182    /// Registers a hook into the server's processing pipeline.
183    ///
184    /// This function dispatches the provided `HookType` to the appropriate
185    /// internal hook collection based on its variant. The hook will be executed
186    /// at the corresponding stage of request processing according to its type:
187    /// - `Panic`: Added to panic handlers for error recovery
188    /// - `RequestError`: Added to request error handlers
189    /// - `RequestMiddleware`: Added to pre-route middleware chain
190    /// - `Route`: Registered as a route handler for the specified path
191    /// - `ResponseMiddleware`: Added to post-route middleware chain
192    ///
193    /// # Arguments
194    ///
195    /// - `HookType` - The `HookType` instance containing the hook configuration and factory.
196    pub async fn handle_hook(&self, hook: HookType) {
197        match hook {
198            HookType::TaskPanic(_, hook) => {
199                self.write().await.get_mut_task_panic().push(hook());
200            }
201            HookType::RequestError(_, hook) => {
202                self.write().await.get_mut_request_error().push(hook());
203            }
204            HookType::RequestMiddleware(_, hook) => {
205                self.write().await.get_mut_request_middleware().push(hook());
206            }
207            HookType::Route(path, hook) => {
208                self.write()
209                    .await
210                    .get_mut_route_matcher()
211                    .add(path, hook())
212                    .unwrap();
213            }
214            HookType::ResponseMiddleware(_, hook) => {
215                self.write()
216                    .await
217                    .get_mut_response_middleware()
218                    .push(hook());
219            }
220        };
221    }
222
223    /// Sets the server configuration from a string.
224    ///
225    /// # Arguments
226    ///
227    /// - `C: ToString` - The configuration.
228    ///
229    /// # Returns
230    ///
231    /// - `&Self` - Reference to self for method chaining.
232    pub async fn config_str<C: ToString>(&self, config_str: C) -> &Self {
233        let config: ServerConfig = ServerConfig::from_json_str(&config_str.to_string()).unwrap();
234        self.write().await.set_config(config.get_inner().await);
235        self
236    }
237
238    /// Sets the server configuration.
239    ///
240    /// # Arguments
241    ///
242    /// - `ServerConfig` - The server configuration.
243    ///
244    /// # Returns
245    ///
246    /// - `&Self` - Reference to self for method chaining.
247    pub async fn config(&self, config: ServerConfig) -> &Self {
248        self.write().await.set_config(config.get_inner().await);
249        self
250    }
251
252    /// Registers a task panic handler to the processing pipeline.
253    ///
254    /// This method allows registering task panic handlers that implement the `ServerHook` trait,
255    /// which will be executed when a panic occurs during request processing.
256    ///
257    /// # Type Parameters
258    ///
259    /// - `ServerHook` - The task panic handler type that implements `ServerHook`.
260    ///
261    /// # Returns
262    ///
263    /// - `&Self` - Reference to self for method chaining.
264    pub async fn task_panic<S>(&self) -> &Self
265    where
266        S: ServerHook,
267    {
268        self.write()
269            .await
270            .get_mut_task_panic()
271            .push(server_hook_factory::<S>());
272        self
273    }
274
275    /// Registers a request error handler to the processing pipeline.
276    ///
277    /// This method allows registering request error handlers that implement the `ServerHook` trait,
278    /// which will be executed when a request error occurs during HTTP request processing.
279    ///
280    /// # Type Parameters
281    ///
282    /// - `ServerHook` - The request error handler type that implements `ServerHook`.
283    ///
284    /// # Returns
285    ///
286    /// - `&Self` - Reference to self for method chaining.
287    pub async fn request_error<S>(&self) -> &Self
288    where
289        S: ServerHook,
290    {
291        self.write()
292            .await
293            .get_mut_request_error()
294            .push(server_hook_factory::<S>());
295        self
296    }
297
298    /// Registers a route hook for a specific path.
299    ///
300    /// This method allows registering route handlers that implement the `ServerHook` trait,
301    /// providing type safety and better code organization.
302    ///
303    /// # Type Parameters
304    ///
305    /// - `ServerHook` - The route hook type that implements `ServerHook`.
306    ///
307    /// # Arguments
308    ///
309    /// - `path` - The route path pattern.
310    ///
311    /// # Returns
312    ///
313    /// - `&Self` - Reference to self for method chaining.
314    pub async fn route<S>(&self, path: impl ToString) -> &Self
315    where
316        S: ServerHook,
317    {
318        self.write()
319            .await
320            .get_mut_route_matcher()
321            .add(&path.to_string(), server_hook_factory::<S>())
322            .unwrap();
323        self
324    }
325
326    /// Registers request middleware to the processing pipeline.
327    ///
328    /// This method allows registering middleware that implements the `ServerHook` trait,
329    /// which will be executed before route handlers for every incoming request.
330    ///
331    /// # Type Parameters
332    ///
333    /// - `ServerHook` - The middleware type that implements `ServerHook`.
334    ///
335    /// # Returns
336    ///
337    /// - `&Self` - Reference to self for method chaining.
338    pub async fn request_middleware<S>(&self) -> &Self
339    where
340        S: ServerHook,
341    {
342        self.write()
343            .await
344            .get_mut_request_middleware()
345            .push(server_hook_factory::<S>());
346        self
347    }
348
349    /// Registers response middleware to the processing pipeline.
350    ///
351    /// This method allows registering middleware that implements the `ServerHook` trait,
352    /// which will be executed after route handlers for every outgoing response.
353    ///
354    /// # Type Parameters
355    ///
356    /// - `ServerHook` - The middleware type that implements `ServerHook`.
357    ///
358    /// # Returns
359    ///
360    /// - `&Self` - Reference to self for method chaining.
361    pub async fn response_middleware<S>(&self) -> &Self
362    where
363        S: ServerHook,
364    {
365        self.write()
366            .await
367            .get_mut_response_middleware()
368            .push(server_hook_factory::<S>());
369        self
370    }
371
372    /// Formats the host and port into a bindable address string.
373    ///
374    /// # Arguments
375    ///
376    /// - `H: ToString` - The host address.
377    /// - `u16` - The port number.
378    ///
379    /// # Returns
380    ///
381    /// - `String` - The formatted address string.
382    #[inline(always)]
383    pub fn format_host_port<H: ToString>(host: H, port: u16) -> String {
384        format!("{}{COLON}{port}", host.to_string())
385    }
386
387    /// Flushes the standard output stream.
388    ///
389    /// # Returns
390    ///
391    /// - `io::Result<()>` - The result of the flush operation.
392    #[inline(always)]
393    pub fn try_flush_stdout() -> io::Result<()> {
394        stdout().flush()
395    }
396
397    /// Flushes the standard error stream.
398    ///
399    /// # Panics
400    ///
401    /// This function will panic if the flush operation fails.
402    #[inline(always)]
403    pub fn flush_stdout() {
404        stdout().flush().unwrap();
405    }
406
407    /// Flushes the standard error stream.
408    ///
409    /// # Returns
410    ///
411    /// - `io::Result<()>` - The result of the flush operation.
412    #[inline(always)]
413    pub fn try_flush_stderr() -> io::Result<()> {
414        stderr().flush()
415    }
416
417    /// Flushes the standard error stream.
418    ///
419    /// # Panics
420    ///
421    /// This function will panic if the flush operation fails.
422    #[inline(always)]
423    pub fn flush_stderr() {
424        stderr().flush().unwrap();
425    }
426
427    /// Flushes both the standard output and error streams.
428    ///
429    /// # Returns
430    ///
431    /// - `io::Result<()>` - The result of the flush operation.
432    #[inline(always)]
433    pub fn try_flush_stdout_and_stderr() -> io::Result<()> {
434        Self::try_flush_stdout()?;
435        Self::try_flush_stderr()
436    }
437
438    /// Flushes both the standard output and error streams.
439    ///
440    /// # Panics
441    ///
442    /// This function will panic if either flush operation fails.
443    #[inline(always)]
444    pub fn flush_stdout_and_stderr() {
445        Self::flush_stdout();
446        Self::flush_stderr();
447    }
448
449    /// Handles a panic that has been captured and associated with a specific request `Context`.
450    ///
451    /// This function is invoked when a panic occurs within a task that has access to the request
452    /// context, such as a route hook or middleware. It ensures that the panic information is
453    /// recorded in the `Context` and then passed to the server's configured panic hook for
454    /// processing.
455    ///
456    /// By associating the panic with the context, the hook can access request-specific details
457    /// to provide more meaningful error logging and responses.
458    ///
459    /// # Arguments
460    ///
461    /// - `&Context` - The context of the request during which the panic occurred.
462    /// - `&PanicData` - The captured panic information.
463    async fn handle_panic_with_context(&self, ctx: &Context, panic: &PanicData) {
464        let panic_clone: PanicData = panic.clone();
465        ctx.cancel_aborted().await.set_task_panic(panic_clone).await;
466        for hook in self.read().await.get_task_panic().iter() {
467            Box::pin(self.task_handler(ctx, hook, false)).await;
468            if ctx.get_aborted().await {
469                return;
470            }
471        }
472    }
473
474    /// Handles a panic that occurred within a spawned Tokio task.
475    ///
476    /// It extracts the panic information from the `JoinError` and processes it.
477    ///
478    /// # Arguments
479    ///
480    /// - `&Context` - The context associated with the task.
481    /// - `JoinError` - The `JoinError` returned from the panicked task.
482    async fn handle_task_panic(&self, ctx: &Context, join_error: JoinError) {
483        let panic: PanicData = PanicData::from_join_error(join_error);
484        ctx.set_response_status_code(HttpStatus::InternalServerError.code())
485            .await;
486        self.handle_panic_with_context(ctx, &panic).await;
487    }
488
489    /// Spawns a task handler for a given context and hook.
490    ///
491    /// # Arguments
492    ///
493    /// - `&Context` - The context of the request.
494    /// - `&ServerHookHandler` - The hook to execute.
495    /// - `bool` - Whether to handle panics that occur during execution.
496    async fn task_handler(&self, ctx: &Context, hook: &ServerHookHandler, progress: bool) {
497        if let Err(join_error) = spawn(hook(ctx)).await
498            && join_error.is_panic()
499        {
500            if progress {
501                Box::pin(self.handle_task_panic(ctx, join_error)).await;
502            } else {
503                eprintln!("Panic occurred in panic handler: {:?}", join_error);
504                let _ = Self::try_flush_stdout_and_stderr();
505            }
506        }
507    }
508
509    /// Creates and binds a `TcpListener` based on the server's configuration.
510    ///
511    /// # Returns
512    ///
513    /// - `Result<TcpListener, ServerError>` - A `Result` containing the bound `TcpListener` on success,
514    ///   or a `ServerError` on failure.
515    async fn create_tcp_listener(&self) -> Result<TcpListener, ServerError> {
516        let config: ServerConfigInner = self.read().await.get_config().clone();
517        let host: String = config.get_host().clone();
518        let port: u16 = *config.get_port();
519        let addr: String = Self::format_host_port(host, port);
520        TcpListener::bind(&addr)
521            .await
522            .map_err(|error| ServerError::TcpBind(error.to_string()))
523    }
524
525    /// Enters a loop to accept incoming TCP connections and spawn handlers for them.
526    ///
527    /// # Arguments
528    ///
529    /// - `&TcpListener` - A reference to the `TcpListener` to accept connections from.
530    ///
531    /// # Returns
532    ///
533    /// - `Result<(), ServerError>` - A `Result` which is typically `Ok(())` unless an unrecoverable
534    ///   error occurs.
535    async fn accept_connections(&self, tcp_listener: &TcpListener) -> Result<(), ServerError> {
536        while let Ok((stream, _socket_addr)) = tcp_listener.accept().await {
537            self.configure_stream(&stream).await;
538            let stream: ArcRwLockStream = ArcRwLockStream::from_stream(stream);
539            self.spawn_connection_handler(stream).await;
540        }
541        Ok(())
542    }
543
544    /// Configures socket options for a newly accepted `TcpStream`.
545    ///
546    /// This applies settings like `TCP_NODELAY`, and `IP_TTL` from the server's configuration.
547    ///
548    /// # Arguments
549    ///
550    /// - `&TcpStream` - A reference to the `TcpStream` to configure.
551    async fn configure_stream(&self, stream: &TcpStream) {
552        let server_inner: ServerStateReadGuard = self.read().await;
553        let config: &ServerConfigInner = server_inner.get_config();
554        if let Some(nodelay) = config.get_nodelay() {
555            let _ = stream.set_nodelay(*nodelay);
556        }
557        if let Some(ttl) = config.get_ttl() {
558            let _ = stream.set_ttl(*ttl);
559        }
560    }
561
562    /// Spawns a new asynchronous task to handle a single client connection.
563    ///
564    /// # Arguments
565    ///
566    /// - `ArcRwLockStream` - The thread-safe stream representing the client connection.
567    async fn spawn_connection_handler(&self, stream: ArcRwLockStream) {
568        let server: Server = self.clone();
569        let request_config: RequestConfig = *self.read().await.get_config().get_request_config();
570        spawn(async move {
571            server.handle_connection(stream, request_config).await;
572        });
573    }
574
575    /// Handles errors that occur while processing HTTP requests.
576    ///
577    /// # Arguments
578    ///
579    /// - `&Context` - The request context.
580    /// - `&RequestError` - The error that occurred.
581    pub async fn handle_request_error(&self, ctx: &Context, error: &RequestError) {
582        ctx.cancel_aborted()
583            .await
584            .set_request_error_data(error.clone())
585            .await;
586        for hook in self.read().await.get_request_error().iter() {
587            self.task_handler(ctx, hook, true).await;
588            if ctx.get_aborted().await {
589                return;
590            }
591        }
592    }
593
594    /// Handles a single client connection, determining whether it's an HTTP or WebSocket request.
595    ///
596    /// It reads the initial request from the stream and dispatches it to the appropriate hook.
597    ///
598    /// # Arguments
599    ///
600    /// - `ArcRwLockStream` - The stream for the client connection.
601    /// - `request_config` - The request config to use for reading the initial HTTP request.
602    async fn handle_connection(&self, stream: ArcRwLockStream, request_config: RequestConfig) {
603        match Request::http_from_stream(&stream, &request_config).await {
604            Ok(request) => {
605                let hook: HandlerState = HandlerState::new(stream, request_config);
606                self.handle_http_requests(&hook, &request).await;
607            }
608            Err(error) => {
609                self.handle_request_error(&stream.into(), &error).await;
610            }
611        }
612    }
613
614    /// The core request handling pipeline.
615    ///
616    /// This function orchestrates the execution of request middleware, the route hook,
617    /// and response middleware. It supports both function-based and trait-based handlers.
618    ///
619    /// # Arguments
620    ///
621    /// - `&HandlerState` - The `HandlerState` for the current connection.
622    /// - `&Request` - The incoming request to be processed.
623    ///
624    /// # Returns
625    ///
626    /// - `bool` - A boolean indicating whether the connection should be kept alive.
627    async fn request_hook(&self, state: &HandlerState, request: &Request) -> bool {
628        let route: &str = request.get_path();
629        let ctx: &Context = &Context::new(state.get_stream(), request);
630        let keep_alive: bool = request.is_enable_keep_alive();
631        if self.handle_request_middleware(ctx).await {
632            return ctx.is_keep_alive(keep_alive).await;
633        }
634        if self.handle_route_matcher(ctx, route).await {
635            return ctx.is_keep_alive(keep_alive).await;
636        }
637        if self.handle_response_middleware(ctx).await {
638            return ctx.is_keep_alive(keep_alive).await;
639        }
640        if let Some(panic) = ctx.try_get_task_panic_data().await {
641            ctx.set_response_status_code(HttpStatus::InternalServerError.code())
642                .await;
643            self.handle_panic_with_context(ctx, &panic).await;
644        }
645        ctx.is_keep_alive(keep_alive).await
646    }
647
648    /// Handles subsequent HTTP requests on a persistent (keep-alive) connection.
649    ///
650    /// # Arguments
651    ///
652    /// - `&HandlerState` - The `HandlerState` for the current connection.
653    /// - `&Request` - The initial request that established the keep-alive connection.
654    async fn handle_http_requests(&self, state: &HandlerState, request: &Request) {
655        if !self.request_hook(state, request).await {
656            return;
657        }
658        let stream: &ArcRwLockStream = state.get_stream();
659        let request_config: &RequestConfig = state.get_request_config();
660        loop {
661            match Request::http_from_stream(stream, request_config).await {
662                Ok(new_request) => {
663                    if !self.request_hook(state, &new_request).await {
664                        return;
665                    }
666                }
667                Err(error) => {
668                    self.handle_request_error(&state.get_stream().into(), &error)
669                        .await;
670                    return;
671                }
672            }
673        }
674    }
675
676    /// Executes trait-based request middleware in sequence.
677    ///
678    /// # Arguments
679    ///
680    /// - `&Context` - The request context.
681    ///
682    /// # Returns
683    ///
684    /// - `bool` - `true` if the lifecycle was aborted, `false` otherwise.
685    pub(super) async fn handle_request_middleware(&self, ctx: &Context) -> bool {
686        for hook in self.read().await.get_request_middleware().iter() {
687            self.task_handler(ctx, hook, true).await;
688            if ctx.get_aborted().await {
689                return true;
690            }
691        }
692        false
693    }
694
695    /// Executes a trait-based route hook if one matches.
696    ///
697    /// # Arguments
698    ///
699    /// - `&Context` - The request context.
700    /// - `&str` - The request path to match.
701    ///
702    /// # Returns
703    ///
704    /// - `bool` - `true` if the lifecycle was aborted, `false` otherwise.
705    pub(super) async fn handle_route_matcher(&self, ctx: &Context, path: &str) -> bool {
706        if let Some(hook) = self
707            .read()
708            .await
709            .get_route_matcher()
710            .try_resolve_route(ctx, path)
711            .await
712        {
713            self.task_handler(ctx, &hook, true).await;
714            if ctx.get_aborted().await {
715                return true;
716            }
717        }
718        false
719    }
720
721    /// Executes trait-based response middleware in sequence.
722    ///
723    /// # Arguments
724    ///
725    /// - `&Context` - The request context.
726    ///
727    /// # Returns
728    ///
729    /// - `bool` - `true` if the lifecycle was aborted, `false` otherwise.
730    pub(super) async fn handle_response_middleware(&self, ctx: &Context) -> bool {
731        for hook in self.read().await.get_response_middleware().iter() {
732            self.task_handler(ctx, hook, true).await;
733            if ctx.get_aborted().await {
734                return true;
735            }
736        }
737        false
738    }
739
740    /// Starts the server, binds to the configured address, and begins listening for connections.
741    ///
742    /// This is the main entry point to launch the server. It will initialize the panic hook,
743    /// create a TCP listener, and then enter the connection acceptance loop in a background task.
744    ///
745    /// # Returns
746    ///
747    /// Returns a `Result` containing a shutdown function on success.
748    /// Calling this function will shut down the server by aborting its main task.
749    /// Returns an error if the server fails to start.
750    pub async fn run(&self) -> Result<ServerControlHook, ServerError> {
751        let tcp_listener: TcpListener = self.create_tcp_listener().await?;
752        let server: Server = self.clone();
753        let (wait_sender, wait_receiver) = channel(());
754        let (shutdown_sender, mut shutdown_receiver) = channel(());
755        let accept_connections: JoinHandle<()> = spawn(async move {
756            let _ = server.accept_connections(&tcp_listener).await;
757            let _ = wait_sender.send(());
758        });
759        let wait_hook: SharedAsyncTaskFactory<()> = Arc::new(move || {
760            let mut wait_receiver_clone: Receiver<()> = wait_receiver.clone();
761            Box::pin(async move {
762                let _ = wait_receiver_clone.changed().await;
763            })
764        });
765        let shutdown_hook: SharedAsyncTaskFactory<()> = Arc::new(move || {
766            let shutdown_sender_clone: Sender<()> = shutdown_sender.clone();
767            Box::pin(async move {
768                let _ = shutdown_sender_clone.send(());
769            })
770        });
771        spawn(async move {
772            let _ = shutdown_receiver.changed().await;
773            accept_connections.abort();
774        });
775        let mut server_control_hook: ServerControlHook = ServerControlHook::default();
776        server_control_hook.set_shutdown_hook(shutdown_hook);
777        server_control_hook.set_wait_hook(wait_hook);
778        Ok(server_control_hook)
779    }
780}