Documentation
macro_rules! relay_impl {
    () => {
        pub fn build<B: FnOnce(Builder<P, F>) -> Builder<P, F>>(
            b: B,
        ) -> Result<Self, net_relay::Error> {
            let builder = Builder::new();
            let parts = b(builder).build_without_pool()?;
            
            let pools = Pools::new();
            for p in parts.pools.iter() {
                if p.get_id().len() != 0 {
                    pools.add_arc_pool(p.clone());
                }
            }

            Ok(Relay {
                parts,
                pending: None,
                pools,
            })
        }

        pub fn bind_addrs(&self) -> &Vec<SocketAddr> {
            &self.parts.bind_addrs
        }

        pub fn relay_fn(&self) -> Arc<F> {
            self.parts.relay_fn.as_ref().unwrap().clone()
        }

        /// 设置最大连接数
        pub fn set_max_conn(&self, max: Option<usize>) {
            for p in self.parts.pools.iter() {
                p.set_max_conn(max)
            }
        }

        /// 设置空闲连接保留时长
        pub fn set_keepalive(&self, duration: Option<Duration>) {
            for p in self.parts.pools.iter() {
                p.set_keepalive(duration)
            }
        }

        /// 获取连接池管理器
        pub fn pools(&self) -> Pools<P> {
            self.pools.clone()
        }
        
        /// 设置路由器
        pub fn set_pools(&mut self, ps: Pools<P>) -> Pools<P> {
            let old = self.pools.clone();
            self.pools = ps;
            old
        }
    };
}

macro_rules! process_impl {
    (
        $pools: expr,
        $service_fn: expr
    ) => {{
        let process = {
            let pools = $pools.clone();
            let service_fn = $service_fn.clone();
            move |req| {
                let pools = pools.clone();
                let service_fn = service_fn.clone();
                async move { service_fn(pools, req).await }
            }
        };
        process
    }};
}

macro_rules! serve1_connection_impl {
    (
        $pools: expr,
        $service_fn: expr,
        $client: expr
    ) => {{
        let process = process_impl! {$pools, $service_fn};
        async move {
            let io = hyper_util::rt::TokioIo::new($client);
            if let Err(_e) = hyper::server::conn::http1::Builder::new()
                .serve_connection(io, hyper::service::service_fn(process))
                .await
            {
                warn2!(
                    "recv invalid request, error occurred: {:?}",
                    _e
                );
            }
        }
    }};
}

macro_rules! serve2_connection_impl {
    (
        $pools: expr,
        $service_fn: expr,
        $client: expr,
        $max_streams: expr
    ) => {{
        let process = process_impl! {$pools, $service_fn};
        async move {
            let io = hyper_util::rt::TokioIo::new($client);
            if let Err(_e) =
                hyper::server::conn::http2::Builder::new(hyper_util::rt::TokioExecutor::new())
                    .max_concurrent_streams($max_streams)
                    .serve_connection(io, hyper::service::service_fn(process))
                    .await
            {
                warn2!(
                    "recv invalid request, error occurred: {:?}",
                    _e
                );
            }
        }
    }};
}

pub(crate) use process_impl;
pub(crate) use relay_impl;
pub(crate) use serve1_connection_impl;
pub(crate) use serve2_connection_impl;