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