### add_dependencies Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/services/struct.ServiceHandle.html Example demonstrating how to declare multiple dependencies for a service using add_dependencies. ```rust let db_id = server.add_service(database_service); let cache_id = server.add_service(cache_service); let api_id = server.add_service(api_service); // API service depends on database api_id.add_dependencies(&[&db_id, &cache_id]); ``` -------------------------------- ### Add Service Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/server/struct.Server.html Example demonstrating how to add services to a server and declare dependencies between them. ```rust let db_id = server.add_service(database_service); let api_id = server.add_service(api_service); // Declare that API depends on database api_id.add_dependency(&db_id); ``` -------------------------------- ### ServiceHandle Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/services/struct.ServiceHandle.html Example demonstrating how to add services and declare dependencies between them using ServiceHandle. ```rust let db_handle = server.add_service(database_service); let cache_handle = server.add_service(cache_service); let api_handle = server.add_service(api_service); api_handle.add_dependency(&db_handle); api_handle.add_dependency(&cache_handle); ``` -------------------------------- ### try_clone_from_ref_in Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/type.ModuleBuilder.html Example demonstrating the usage of `try_clone_from_ref_in` with `System` allocator. ```rust #![feature(clone_from_ref)] #![feature(allocator_api)] use std::alloc::System; let hello: Box = Box::try_clone_from_ref_in("hello", System)?; ``` -------------------------------- ### Builder::new() example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/http/v2/server/struct.H2Options.html Example of creating a new server builder and setting initial window size and max concurrent streams. ```rust // `server_fut` is a future representing the completion of the HTTP/2 // handshake. let server_fut = Builder::new() .initial_window_size(1_000_000) .max_concurrent_streams(1000) .handshake(my_io); ``` -------------------------------- ### Virtual Socket Write Example Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/protocols/l4/virt.rs.html An example demonstrating writing data to a virtual stream and asserting the content. ```rust stream.write_all(content).await.unwrap(); assert_eq!(write_buf.lock().unwrap().as_slice(), content); ``` -------------------------------- ### Builder::initial_window_size() example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/http/v2/server/struct.H2Options.html Example of setting the initial window size for stream-level flow control. ```rust // `server_fut` is a future representing the completion of the HTTP/2 // handshake. let server_fut = Builder::new() .initial_window_size(1_000_000) .handshake(my_io); ``` -------------------------------- ### Builder::initial_connection_window_size() example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/http/v2/server/struct.H2Options.html Example of setting the initial window size for connection-level flow control. ```rust // `server_fut` is a future representing the completion of the HTTP/2 // handshake. let server_fut = Builder::new() .initial_connection_window_size(1_000_000) .handshake(my_io); ``` -------------------------------- ### Receiver Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/services/type.ServiceReadyWatch.html Example demonstrating the use of Receiver::borrow() with tokio::sync::watch. ```rust use tokio::sync::watch; let (_, rx) = watch::channel("hello"); assert_eq!(*rx.borrow(), "hello"); ``` -------------------------------- ### Receiver Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/services/type.ServiceReadyWatch.html Example demonstrating the use of Receiver::has_changed() and Receiver::borrow_and_update(). ```rust use tokio::sync::watch; #[tokio::main] async fn main() { let (tx, mut rx) = watch::channel("hello"); tx.send("goodbye").unwrap(); assert!(rx.has_changed().unwrap()); assert_eq!(*rx.borrow_and_update(), "goodbye"); // The value has been marked as seen assert!(!rx.has_changed().unwrap()); drop(tx); // The `tx` handle has been dropped assert!(rx.has_changed().is_err()); } ``` -------------------------------- ### and method example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/prelude/type.Result.html Provides examples of the `and` method, showing its behavior when combining two `Result` types. ```Rust let x: Result = Ok(2); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("late error")); let x: Result = Err("early error"); let y: Result<&str, &str> = Ok("foo"); assert_eq!(x.and(y), Err("early error")); let x: Result = Err("not a 2"); let y: Result<&str, &str> = Err("late error"); assert_eq!(x.and(y), Err("not a 2")); let x: Result = Ok(2); let y: Result<&str, &str> = Ok("different result type"); assert_eq!(x.and(y), Ok("different result type")); ``` -------------------------------- ### Example with Connection Filtering Source: https://docs.rs/pingora-core/0.8.0/pingora_core/listeners/index.html This example demonstrates how to create and apply a custom connection filter to the listeners. ```rust use pingora_core::listeners::{Listeners, ConnectionFilter}; use std::sync::Arc; // Create a custom filter let filter = Arc::new(MyCustomFilter::new()); // Apply to listeners let mut listeners = Listeners::new(); listeners.set_connection_filter(filter); listeners.add_tcp("0.0.0.0:8080"); ``` -------------------------------- ### add_dependency Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/services/struct.ServiceHandle.html Example showing how to declare that one service depends on another using add_dependency. ```rust let db_id = server.add_service(database_service); let api_id = server.add_service(api_service); // API service depends on database api_id.add_dependency(&db_id); ``` -------------------------------- ### try_clone_from_ref_in Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/type.Module.html Example demonstrating the usage of the `try_clone_from_ref_in` function, which is a nightly-only experimental API. ```rust #![feature(clone_from_ref)] #![feature(allocator_api)] use std::alloc::System; let hello: Box = Box::try_clone_from_ref_in("hello", System)?; ``` -------------------------------- ### Equivalent manual cleanup Source: https://docs.rs/pingora-core/0.8.0/pingora_core/type.BError.html This is equivalent to the previous manual cleanup example. ```rust let x = Box::new(String::from("Hello")); let ptr = Box::into_raw(x); unsafe { drop(Box::from_raw(ptr)); } ``` -------------------------------- ### Complex Valid Graph Setup Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/services/mod.rs.html Initializes a complex dependency graph with multiple services and their dependencies, including a database, cache, authentication service, API, and frontend. This is a setup for a test case. ```rust #[test] fn test_complex_valid_graph() { let mut graph = DependencyGraph::new(); let (_tx1, rx1) = watch::channel(false); let (_tx2, rx2) = watch::channel(false); let (_tx3, rx3) = watch::channel(false); let (_tx4, rx4) = watch::channel(false); let (_tx5, rx5) = watch::channel(false); // Build a complex dependency graph: // db, cache - no deps // auth -> db // api -> db, cache, auth // frontend -> api let db = graph.add_node("db".to_string(), rx1); let cache = graph.add_node("cache".to_string(), rx2); ``` -------------------------------- ### provide Method Example (Nightly Only) Source: https://docs.rs/pingora-core/0.8.0/pingora_core/prelude/trait.ErrorTrait.html An example demonstrating the experimental `provide` method for accessing context from error types, requiring nightly Rust. ```rust #![feature(error_generic_member_access)] use core::fmt; use core::error::{request_ref, Request}; #[derive(Debug)] enum MyLittleTeaPot { Empty, } #[derive(Debug)] struct MyBacktrace { // ... } impl MyBacktrace { fn new() -> MyBacktrace { // ... } } #[derive(Debug)] struct Error { backtrace: MyBacktrace, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Example Error") } } impl std::error::Error for Error { fn provide<'a>(&'a self, request: &mut Request<'a>) { request .provide_ref::(&self.backtrace); } } fn main() { let backtrace = MyBacktrace::new(); let error = Error { backtrace }; let dyn_error = &error as &dyn std::error::Error; let backtrace_ref = request_ref::(dyn_error).unwrap(); assert!(core::ptr::eq(&error.backtrace, backtrace_ref)); assert!(request_ref::(dyn_error).is_none()); } ``` -------------------------------- ### Connection Filtering Example Source: https://docs.rs/pingora-core/0.8.0/index.html This example demonstrates how to implement and apply a custom connection filter using the `connection_filter` feature. ```rust use async_trait::async_trait; use pingora_core::listeners::ConnectionFilter; use std::net::SocketAddr; use std::sync::Arc; #[derive(Debug)] struct MyFilter; #[async_trait] impl ConnectionFilter for MyFilter { async fn should_accept(&self, addr: &SocketAddr) -> bool { // Custom logic to filter connections !is_blocked_ip(addr.ip()) } } // Apply the filter to a service let mut service = my_service(); service.set_connection_filter(Arc::new(MyFilter)); ``` -------------------------------- ### Server Creation with Options and Configuration Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/server/mod.rs.html Demonstrates how to create a new Server instance using custom options and server configuration, merging them if necessary. ```Rust pub fn new_with_opt_and_conf(raw_opt: impl Into>, mut conf: ServerConf) -> Server { let opt = raw_opt.into(); if let Some(opts) = &opt { if let Some(c) = opts.conf.as_ref() { warn!("Ignoring command line argument using '{c}' as configuration, and using provided configuration instead."); } conf.merge_with_opt(opts); } let (tx, rx) = watch::channel(false); let execution_phase_watch = broadcast::channel(100).0; let bootstrap = Arc::new(Mutex::new(Bootstrap::new( &opt, &conf, &execution_phase_watch, ))); Server { services: Default::default(), init_services: Default::default(), shutdown_watch: tx, shutdown_recv: rx, execution_phase_watch, configuration: Arc::new(conf), options: opt, dependencies: Arc::new(Mutex::new(DependencyGraph::new())), bootstrap, } } ``` -------------------------------- ### Getting the weak count of an Arc Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/tls/type.HandshakeCompleteHook.html Example showing how to get the number of `Weak` pointers to an `Arc` using `Arc::weak_count`. ```rust use std::sync::Arc; let five = Arc::new(5); let _weak_five = Arc::downgrade(&five); // This assertion is deterministic because we haven't shared // the `Arc` or `Weak` between threads. assert_eq!(1, Arc::weak_count(&five)); ``` -------------------------------- ### Getting the strong count of an Arc Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/tls/type.HandshakeCompleteHook.html Example demonstrating how to get the number of strong (`Arc`) pointers to an allocation using `Arc::strong_count`. ```rust use std::sync::Arc; let five = Arc::new(5); let _also_five = Arc::clone(&five); // This assertion is deterministic because we haven't shared // the `Arc` between threads. assert_eq!(2, Arc::strong_count(&five)); ``` -------------------------------- ### iter Source: https://docs.rs/pingora-core/0.8.0/pingora_core/prelude/type.Result.html Example of using iter to get an iterator over the contained value if the Result is Ok. ```rust let x: Result = Ok(7); assert_eq!(x.iter().next(), Some(&7)); let x: Result = Err("nothing!"); assert_eq!(x.iter().next(), None); ``` -------------------------------- ### Server Creation with Options Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/server/mod.rs.html Illustrates the creation of a new Server instance, handling configuration loading and merging with command-line options. ```Rust pub fn new(opt: impl Into>) -> Result { let opt = opt.into(); let (tx, rx) = watch::channel(false); let execution_phase_watch = broadcast::channel(100).0; let conf = if let Some(opt) = opt.as_ref() { opt.conf.as_ref().map_or_else( || // options, no conf, generated ServerConf::new_with_opt_override(opt).ok_or_else(|| { Error::explain(ErrorType::ReadError, "Conf generation failed") }), |_ // options and conf loaded ServerConf::load_yaml_with_opt_override(opt), ) } else { ServerConf::new() .ok_or_else(|| Error::explain(ErrorType::ReadError, "Conf generation failed")) }?; let bootstrap = Arc::new(Mutex::new(Bootstrap::new( &opt, &conf, &execution_phase_watch, ))); Ok(Server { services: Default::default(), init_services: Default::default(), shutdown_watch: tx, shutdown_recv: rx, execution_phase_watch, configuration: Arc::new(conf), options: opt, dependencies: Arc::new(Mutex::new(DependencyGraph::new())), bootstrap, }) } ``` -------------------------------- ### iter_mut Source: https://docs.rs/pingora-core/0.8.0/pingora_core/prelude/type.Result.html Example of using iter_mut to get a mutable iterator over the contained value if the Result is Ok. ```rust let mut x: Result = Ok(7); match x.iter_mut().next() { Some(v) => *v = 40, None => {}, } assert_eq!(x, Ok(40)); let mut x: Result = Err("nothing!"); assert_eq!(x.iter_mut().next(), None); ``` -------------------------------- ### get method Source: https://docs.rs/pingora-core/0.8.0/pingora_core/utils/struct.BufRef.html Returns a sub-slice of the provided byte slice based on the BufRef's start and length. ```rust pub fn get<'a>(&self, buf: &'a [u8]) -> &'a [u8] ``` -------------------------------- ### Service Startup Logic Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/server/mod.rs.html This snippet illustrates the logic for waiting for a service to become ready and handling potential errors, followed by starting the service. ```Rust if watch.wait_for(|&ready| ready).await.is_err() { error!( "Service '{}' dependency channel closed before ready", service_name ); } *time_waited_opt.get_or_insert_default() += start.elapsed().unwrap_or_default() if let Some(time_waited) = time_waited_opt { service.on_startup_delay(time_waited); } // Start the actual service, passing the ready notifier service .start_service( #[cfg(unix)] fds, shutdown, listeners_per_fd, ready_notifier, ) .await; info!("service '{}' exited.", service_name); ``` -------------------------------- ### Example for `AsFd` trait implementation Source: https://docs.rs/pingora-core/0.8.0/pingora_core/upstreams/peer/type.ProxyDigestUserDataHook.html This example demonstrates how to implement traits that require `AsFd` on `Arc` by providing an example with `UdpSocket`. ```rust use std::net::UdpSocket; use std::sync::Arc; trait MyTrait: AsFd {} impl MyTrait for Arc {} impl MyTrait for Box {} ``` -------------------------------- ### into_ok example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/prelude/type.Result.html Illustrates the usage of the experimental `into_ok` method, which returns the `Ok` value without panicking. ```Rust fn only_good_news() -> Result { Ok("this is fine".into()) } let s: String = only_good_news().into_ok(); println!("{s}"); ``` -------------------------------- ### Arc::try_new example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/server/type.ListenFds.html Example of using try_new for fallible Arc construction. ```rust #![feature(allocator_api)] use std::sync::Arc; let five = Arc::try_new(5)?; ``` -------------------------------- ### Example with Connection Filtering Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/listeners/mod.rs.html Demonstrates how to set up listeners with a custom connection filter using the `connection_filter` feature. ```rust # #[cfg(feature = "connection_filter")] # { use pingora_core::listeners::{Listeners, ConnectionFilter}; use std::sync::Arc; // Create a custom filter let filter = Arc::new(MyCustomFilter::new()); // Apply to listeners let mut listeners = Listeners::new(); listeners.set_connection_filter(filter); listeners.add_tcp("0.0.0.0:8080"); # } ``` -------------------------------- ### new_in example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/tls/type.HandshakeCompleteHook.html Example of constructing a new `Arc` using a specific allocator. ```rust #![feature(allocator_api)] use std::sync::Arc; use std::alloc::System; let five = Arc::new_in(5, System); ``` -------------------------------- ### Manually create a Box from scratch by using the system allocator Source: https://docs.rs/pingora-core/0.8.0/pingora_core/listeners/type.TlsAcceptCallbacks.html This example shows how to manually allocate memory using the system allocator, create a Box from it, and handle potential initialization issues. ```rust #![feature(allocator_api)] use std::alloc::{Allocator, Layout, System}; unsafe { let non_null = System.allocate(Layout::new::())?.cast::(); // In general .write is required to avoid attempting to destruct // the (uninitialized) previous contents of `non_null`. non_null.write(5); let x = Box::from_non_null_in(non_null, System); } ``` -------------------------------- ### Box::from_raw Example 2 Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/type.ModuleBuilder.html Manually creates a Box from scratch using the global allocator. ```rust use std::alloc::{alloc, Layout}; unsafe { let ptr = alloc(Layout::new::()) as *mut i32; // In general .write is required to avoid attempting to destruct // the (uninitialized) previous contents of `ptr`, though for this // simple example `*ptr = 5` would have worked as well. ptr.write(5); let x = Box::from_raw(ptr); } ``` -------------------------------- ### init function Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/compression/struct.ResponseCompressionBuilder.html Initialize and return the per request module context. ```rust fn init(&self) -> Module ``` -------------------------------- ### new_zeroed_in example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/tls/type.HandshakeCompleteHook.html Example of constructing an `Arc` with memory zeroed out, using a specific allocator. ```rust #![feature(allocator_api)] use std::sync::Arc; use std::alloc::System; let zero = Arc::::new_zeroed_in(System); let zero = unsafe { zero.assume_init() }; assert_eq!(*zero, 0) ``` -------------------------------- ### Creating a bootstrap service Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/server/mod.rs.html Illustrates the creation of a bootstrap service, including Sentry initialization. ```rust let bootstrap_service = background_service("Bootstrap Service", BootstrapService::new(&self.bootstrap)); let sentry_service = background_service( "Sentry Init Service", SentryInitService::new(&self.bootstrap), ); self.add_init_service(sentry_service); self.add_service(bootstrap_service) ``` -------------------------------- ### Box::new_in example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/type.ModuleBuilder.html Example of allocating memory with a specific allocator using `Box::new_in`. ```rust #![feature(allocator_api)] use std::alloc.System; let five = Box::new_in(5, System); ``` -------------------------------- ### Arc::new_uninit example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/server/type.ListenFds.html Shows how to create an Arc with uninitialized contents and defer initialization. ```rust use std::sync::Arc; let mut five = Arc::::new_uninit(); // Deferred initialization: Arc::get_mut(&mut five).unwrap().write(5); let five = unsafe { five.assume_init() }; assert_eq!(*five, 5) ``` -------------------------------- ### Box::into_raw Example 3 (Equivalent) Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/type.ModuleBuilder.html An equivalent manual cleanup for Box::into_raw using Box::from_raw and drop. ```rust let x = Box::new(String::from("Hello")); let ptr = Box::into_raw(x); unsafe { drop(Box::from_raw(ptr)); } ``` -------------------------------- ### Box::into_pin example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/type.ModuleBuilder.html Demonstrates a problematic implementation of `From> for Pin` that can cause ambiguity. ```rust struct Foo; impl From> for Pin { fn from(_: Box<()>) -> Pin { Pin::new(Foo) } } let foo = Box::new(()); let bar = Pin::from(foo); ``` -------------------------------- ### Builder::max_header_list_size() example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/http/v2/server/struct.H2Options.html Example of setting the maximum size of received header frames. ```rust // `server_fut` is a future representing the completion of the HTTP/2 // handshake. let server_fut = Builder::new() .max_header_list_size(16 * 1024) .handshake(my_io); ``` -------------------------------- ### Service Creation with Application Logic and Listeners Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/services/listening.rs.html This snippet demonstrates creating a `Service` with a name, pre-configured `Listeners`, and application logic. ```rust pub fn with_listeners(name: String, listeners: Listeners, app_logic: A) -> Self { Service { name, listeners, app_logic: Some(app_logic), threads: None, #[cfg(feature = "connection_filter")] connection_filter: Arc::new(AcceptAllFilter), } } ``` -------------------------------- ### Builder::max_frame_size() example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/http/v2/server/struct.H2Options.html Example of setting the maximum HTTP/2 frame payload size. ```rust // `server_fut` is a future representing the completion of the HTTP/2 // handshake. let server_fut = Builder::new() .max_frame_size(1_000_000) .handshake(my_io); ``` -------------------------------- ### Server Run Function Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/server/mod.rs.html The `run` function orchestrates the server startup process, including applying service dependencies, handling daemonization (on Unix), sorting services by dependency, and starting each service. ```rust pub fn run(mut self, run_args: RunArgs) { self.apply_init_service_dependencies(); info!("Server starting"); let conf = self.configuration.as_ref(); #[cfg(unix)] if conf.daemon { info!("Daemonizing the server"); fast_timeout::pause_for_fork(); daemonize(&self.configuration); fast_timeout::unpause(); } #[cfg(windows)] if conf.daemon { panic!("Daemonizing under windows is not supported"); } // Holds tuples of runtimes and their service name. let mut runtimes: Vec<(Runtime, String)> = Vec::new(); // Get services in topological order (dependencies first) let startup_order = match self.dependencies.lock().topological_sort() { Ok(order) => order, Err(e) => { error!("Failed to determine service startup order: {}", e); std::process::exit(1); } }; // Log service names in startup order let service_names: Vec = startup_order .iter() .map(|(_, service)| service.name.clone()) .collect(); info!("Starting services in dependency order: {:?}", service_names); // Start services in dependency order for (service_id, service) in startup_order { let mut wrapper = match self.services.remove(&service_id) { Some(w) => w, None => { warn!( "Service ID {:?}-{} in startup order but not found", service_id, service.name ); continue; } }; let threads = wrapper.service.threads().unwrap_or(conf.threads); let name = wrapper.service.name().to_string(); // Extract dependency watches from the ServiceHandle let dependencies = self .dependencies .lock() .get_dependencies(wrapper.service_handle.id); // Get the readiness notifier for this service by taking it from the Option. // Since service_id is the index, we can directly access it. // We take() the notifier, leaving None in its place. let ready_notifier = wrapper .ready_notifier .take() .expect("Service notifier should exist"); if !dependencies.is_empty() { info!( "Service '{}' will wait for dependencies: {:?}", name, dependencies.iter().map(|s| &s.name).collect::>() ); } else { info!("Starting service: {}", name); } let dependency_watches = dependencies .iter() .map(|s| s.ready_watch.clone()) .collect::>(); let runtime = Server::run_service( wrapper.service, #[cfg(unix)] self.listen_fds(), self.shutdown_recv.clone(), threads, conf.work_stealing, self.configuration.listener_tasks_per_fd, ready_notifier, dependency_watches, ); runtimes.push((runtime, name)); } // blocked on main loop so that it runs forever // Only work steal runtime can use block_on() let server_runtime = Server::create_runtime("Server", 1, true); #[cfg(unix)] let shutdown_type = server_runtime .get_handle() .block_on(self.main_loop(run_args)); #[cfg(windows)] let shutdown_type = server_runtime .get_handle() .block_on(self.main_loop(run_args)); self.execution_phase_watch .send(ExecutionPhase::ShutdownStarted) .ok(); if matches!(shutdown_type, ShutdownType::Graceful) { self.execution_phase_watch .send(ExecutionPhase::ShutdownGracePeriod) .ok(); let exit_timeout = self .configuration .as_ref() .grace_period_seconds .unwrap_or(EXIT_TIMEOUT); info!("Graceful shutdown: grace period {}s starts", exit_timeout); thread::sleep(Duration::from_secs(exit_timeout)); } } ``` -------------------------------- ### Manually create a Box from scratch by using the global allocator Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/type.Module.html Example of manually creating a Box from scratch using the global allocator and NonNull. ```Rust #![feature(box_vec_non_null)] use std::alloc::{alloc, Layout}; use std::ptr::NonNull; unsafe { let non_null = NonNull::new(alloc(Layout::new::()).cast::()) .expect("allocation failed"); // In general .write is required to avoid attempting to destruct // the (uninitialized) previous contents of `non_null`. non_null.write(5); let x = Box::from_non_null(non_null); } ``` -------------------------------- ### TCP Connection Establishment Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/connectors/l4.rs.html Illustrates the process of establishing a TCP connection, including handling proxy connections, custom L4 protocols, and applying various socket options like TCP Fast Open, receive buffer size, and DSCP. ```Rust pub(crate) async fn connect

(peer: &P, bind_to: Option) -> Result where P: Peer + Send + Sync, { if peer.get_proxy().is_some() { return proxy_connect(peer) .await .err_context(|| format!("Fail to establish CONNECT proxy: {}", peer)); } let peer_addr = peer.address(); let mut stream: Stream = if let Some(custom_l4) = peer.get_peer_options().and_then(|o| o.custom_l4.as_ref()) { custom_l4.connect(peer_addr).await? } else { match peer_addr { SocketAddr::Inet(addr) => { let connect_future = tcp_connect(addr, bind_to.as_ref(), |socket| { #[cfg(unix)] let raw = socket.as_raw_fd(); #[cfg(windows)] let raw = socket.as_raw_socket(); if peer.tcp_fast_open() { set_tcp_fastopen_connect(raw)?; } if let Some(recv_buf) = peer.tcp_recv_buf() { debug!("Setting recv buf size"); set_recv_buf(raw, recv_buf)?; } if let Some(dscp) = peer.dscp() { debug!("Setting dscp"); ``` -------------------------------- ### Basic Connection and Reuse Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/connectors/mod.rs.html Demonstrates establishing a new stream and then retrieving a reused stream for the same peer. ```rust let stream = connector.new_stream(&peer).await.unwrap(); connector.release_stream(stream, peer.reuse_hash(), None); let (_, reused) = connector.get_stream(&peer).await.unwrap(); assert!(reused); ``` -------------------------------- ### Service start_service implementation Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/services/listening.rs.html The `start_service` method for the Service trait, responsible for setting up and running endpoints. ```rust async fn start_service( &mut self, #[cfg(unix)] fds: Option, shutdown: ShutdownWatch, listeners_per_fd: usize, ) { let runtime = current_handle(); let endpoints = self .listeners .build( #[cfg(unix)] fds, ) .await .expect("Failed to build listeners"); let app_logic = self .app_logic .take() .expect("can only start_service() once"); let app_logic = Arc::new(app_logic); let mut handlers = Vec::new(); endpoints.into_iter().for_each(|endpoint| { for _ in 0..listeners_per_fd { let shutdown = shutdown.clone(); let my_app_logic = app_logic.clone(); let endpoint = endpoint.clone(); let jh = runtime.spawn(async move { Self::run_endpoint(my_app_logic, endpoint, shutdown).await; }); handlers.push(jh); } }); futures::future::join_all(handlers).await; self.listeners.cleanup(); app_logic.cleanup().await; } ``` -------------------------------- ### new_uninit_in example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/tls/type.HandshakeCompleteHook.html Example of constructing an `Arc` with uninitialized contents using a specific allocator, followed by deferred initialization. ```rust #![feature(get_mut_unchecked)] #![feature(allocator_api)] use std::sync::Arc; use std::alloc::System; let mut five = Arc::::new_uninit_in(System); let five = unsafe { // Deferred initialization: Arc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); five.assume_init() }; assert_eq!(*five, 5) ``` -------------------------------- ### clone_from_ref Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/tls/type.HandshakeCompleteHook.html Example of using clone_from_ref to construct a new Arc with a clone of a value. This is a nightly-only experimental API. ```Rust #![feature(clone_from_ref)] use std::sync::Arc; let hello: Arc = Arc::clone_from_ref("hello"); ``` -------------------------------- ### Box::from_raw Example 2 Source: https://docs.rs/pingora-core/0.8.0/pingora_core/listeners/type.TlsAcceptCallbacks.html Manually creates a Box from scratch using the global allocator. ```Rust use std::alloc::{alloc, Layout}; unsafe { let ptr = alloc(Layout::new::()) as *mut i32; // In general .write is required to avoid attempting to destruct // the (uninitialized) previous contents of `ptr`, though for this // simple example `*ptr = 5` would have worked as well. ptr.write(5); let x = Box::from_raw(ptr); } ``` -------------------------------- ### Error Display Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/prelude/trait.ErrorTrait.html An example demonstrating how an error's Display implementation should be concise and without trailing punctuation. ```rust let err = "NaN".parse::().unwrap_err(); assert_eq!(err.to_string(), "invalid digit found in string"); ``` -------------------------------- ### Box::from_raw_in (manual creation) Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/type.ModuleBuilder.html Manually creates a `Box` from scratch by using the system allocator. ```rust #![feature(allocator_api, slice_ptr_get)] use std::alloc::{Allocator, Layout, System}; unsafe { let ptr = System.allocate(Layout::new::())?.as_mut_ptr() as *mut i32; // In general .write is required to avoid attempting to destruct // the (uninitialized) previous contents of `ptr`, though for this // simple example `*ptr = 5` would have worked as well. ptr.write(5); let x = Box::from_raw_in(ptr, System); } ``` -------------------------------- ### Box::leak unsized data example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/listeners/type.TlsAcceptCallbacks.html Example of using `Box::leak` with unsized data like a boxed slice. ```rust let x = vec![1, 2, 3].into_boxed_slice(); let static_ref = Box::leak(x); static_ref[0] = 4; assert_eq!(*static_ref, [4, 2, 3]); ``` -------------------------------- ### BootstrapService and SentryInitService Constructors Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/server/bootstrap_services.rs.html These snippets show how to create instances of BootstrapService and SentryInitService, which are used to manage the server's bootstrap process and Sentry initialization respectively. ```rust impl BootstrapService { pub fn new(inner: &Arc>) -> Self { BootstrapService { inner: Arc::clone(inner), } } } impl SentryInitService { pub fn new(inner: &Arc>) -> Self { SentryInitService { inner: Arc::clone(inner), } } } ``` -------------------------------- ### Deprecated description Method Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/prelude/trait.ErrorTrait.html An example showing the deprecated `description` method, with a note that Display or to_string() should be used instead. ```rust if let Err(e) = "xc".parse::() { // Print `e` itself, no need for description(). eprintln!("Error: {e}"); } ``` -------------------------------- ### Error Source Method Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/prelude/trait.ErrorTrait.html An example demonstrating the usage of the `source` method to access the underlying error in a nested error structure. ```rust use std::error::Error; use std::fmt; #[derive(Debug)] struct SuperError { source: SuperErrorSideKick, } impl fmt::Display for SuperError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "SuperError is here!") } } impl Error for SuperError { fn source(&self) -> Option<&(dyn Error + 'static)> { Some(&self.source) } } #[derive(Debug)] struct SuperErrorSideKick; impl fmt::Display for SuperErrorSideKick { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "SuperErrorSideKick is here!") } } impl Error for SuperErrorSideKick {} fn get_super_error() -> Result<(), SuperError> { Err(SuperError { source: SuperErrorSideKick }) } fn main() { match get_super_error() { Err(e) => { println!("Error: {e}"); println!("Caused by: {}", e.source().unwrap()); } _ => println!("No error"), } } ``` -------------------------------- ### Arc::new example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/server/type.ListenFds.html Demonstrates the basic usage of Arc::new to create a reference-counted pointer. ```rust use std::sync::Arc; let five = Arc::new(5); ``` -------------------------------- ### Linux Get Receive Buffer Size Source: https://docs.rs/pingora-core/0.8.0/src/pingora_core/protocols/l4/ext.rs.html Gets the SO_RCVBUF socket option to retrieve the TCP receive buffer size on Linux. ```Rust #[cfg(target_os = "linux")] pub fn get_recv_buf(fd: RawFd) -> io::Result { get_opt_sized::(fd, libc::SOL_SOCKET, libc::SO_RCVBUF).map(|v| v as usize) } ``` -------------------------------- ### Box::into_pin example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/modules/http/type.Module.html Demonstrates a potentially problematic implementation of From> for Pin that can lead to ambiguity when calling Pin::from. ```rust struct Foo; // A type defined in this crate. impl From> for Pin { fn from(_: Box<()>) -> Pin { Pin::new(Foo) } } let foo = Box::new(()); let bar = Pin::from(foo); ``` -------------------------------- ### increment_strong_count Example Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/tls/type.HandshakeCompleteHook.html Example of incrementing the strong reference count of an Arc using Arc::increment_strong_count. The pointer must be obtained from Arc::into_raw. ```Rust use std::sync::Arc; let five = Arc::new(5); unsafe { let ptr = Arc::into_raw(five); Arc::increment_strong_count(ptr); // This assertion is deterministic because we haven't shared // the `Arc` between threads. let five = Arc::from_raw(ptr); assert_eq!(2, Arc::strong_count(&five)); } ``` -------------------------------- ### from_raw Example 2 Source: https://docs.rs/pingora-core/0.8.0/pingora_core/protocols/tls/type.HandshakeCompleteHook.html Example of converting a raw pointer of a slice back to its original array type using Arc::from_raw and casting. ```Rust use std::sync::Arc; let x: Arc<[u32]> = Arc::new([1, 2, 3]); let x_ptr: *const [u32] = Arc::into_raw(x); unsafe { let x: Arc<[u32; 3]> = Arc::from_raw(x_ptr.cast::<[u32; 3]>()); assert_eq!(&*x, &[1, 2, 3]); } ```