From a79bd1c29f9eccbe1ca973236ffd0c27d5b06680 Mon Sep 17 00:00:00 2001 From: Janito Vaqueiro Ferreira Filho Date: Fri, 31 May 2024 07:42:56 -0300 Subject: [PATCH] Refactor usage of `SocketAddr` (#2088) * Remove unnecessary reference for parameter Not needed because `u16` implements `Copy`. * Replace `.to_socket_addrs` with `lookup_host` The `ToSocketAddrs::to_socket_addrs` function performs a blocking DNS lookup, so it should be avoided in asynchronous tasks. It can be replaced by `tokio::net::lookup_host` which receives a `tokio::net::ToSocketAddrs` implementation. * Change address parameter to be generic Don't force a string to be built, which then needs to be parsed into a `SocketAddr`. * Use `(String, u16)` instead of a raw `String` Avoid having to format the string to include the port, which will then get parsed out later. * Create a `SocketAddr` directly from integers Avoid parsing the IP address and port. * Avoid parsing `SocketAddr` if not needed Let the IP address be parsed by Tokio, and avoid formatting a string just to include the port which will get parsed out again later. --- linera-rpc/src/simple/server.rs | 4 ++-- linera-rpc/src/simple/transport.rs | 17 ++++++++++------- linera-service/src/prometheus_server.rs | 5 +++-- linera-service/src/proxy.rs | 19 ++++++++----------- linera-service/src/server.rs | 15 ++++++--------- 5 files changed, 29 insertions(+), 31 deletions(-) diff --git a/linera-rpc/src/simple/server.rs b/linera-rpc/src/simple/server.rs index a6c2ca28db9..1f720a69b31 100644 --- a/linera-rpc/src/simple/server.rs +++ b/linera-rpc/src/simple/server.rs @@ -139,7 +139,7 @@ where "Listening to {:?} traffic on {}:{}", self.network.protocol, self.host, self.port ); - let address = format!("{}:{}", self.host, self.port); + let address = (self.host.clone(), self.port); let (cross_chain_sender, cross_chain_receiver) = mpsc::channel(self.cross_chain_config.queue_size); @@ -161,7 +161,7 @@ where cross_chain_sender, }; // Launch server for the appropriate protocol. - protocol.spawn_server(&address, state).await + protocol.spawn_server(address, state).await } } diff --git a/linera-rpc/src/simple/transport.rs b/linera-rpc/src/simple/transport.rs index e000f8cc1c0..d40542d89c3 100644 --- a/linera-rpc/src/simple/transport.rs +++ b/linera-rpc/src/simple/transport.rs @@ -2,7 +2,7 @@ // Copyright (c) Zefchain Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use std::{collections::HashMap, io, net::ToSocketAddrs, sync::Arc}; +use std::{collections::HashMap, io, sync::Arc}; use async_trait::async_trait; use futures::{ @@ -12,7 +12,7 @@ use futures::{ }; use serde::{Deserialize, Serialize}; use tokio::{ - net::{TcpListener, TcpStream, UdpSocket}, + net::{lookup_host, TcpListener, TcpStream, ToSocketAddrs, UdpSocket}, sync::Mutex, }; use tokio_util::{codec::Framed, udp::UdpFramed}; @@ -111,9 +111,12 @@ impl Transport for T where impl TransportProtocol { /// Creates a transport for this protocol. - pub async fn connect(self, address: String) -> Result { - let mut addresses = address - .to_socket_addrs() + pub async fn connect( + self, + address: impl ToSocketAddrs, + ) -> Result { + let mut addresses = lookup_host(address) + .await .expect("Invalid address to connect to"); let address = addresses .next() @@ -152,7 +155,7 @@ impl TransportProtocol { /// Runs a server for this protocol and the given message handler. pub async fn spawn_server( self, - address: &str, + address: impl ToSocketAddrs, state: S, ) -> Result where @@ -161,7 +164,7 @@ impl TransportProtocol { let (abort, registration) = AbortHandle::new_pair(); let handle = match self { Self::Udp => { - let socket = UdpSocket::bind(&address).await?; + let socket = UdpSocket::bind(address).await?; tokio::spawn(Self::run_udp_server(socket, state, registration)) } Self::Tcp => { diff --git a/linera-service/src/prometheus_server.rs b/linera-service/src/prometheus_server.rs index dadbf63fa4b..f3af93f720f 100644 --- a/linera-service/src/prometheus_server.rs +++ b/linera-service/src/prometheus_server.rs @@ -1,12 +1,13 @@ // Copyright (c) Zefchain Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use std::net::SocketAddr; +use std::fmt::Debug; use axum::{http::StatusCode, response::IntoResponse, routing::get, Router}; +use tokio::net::ToSocketAddrs; use tracing::info; -pub fn start_metrics(address: SocketAddr) { +pub fn start_metrics(address: impl ToSocketAddrs + Debug + Send + 'static) { info!("Starting to serve metrics on {:?}", address); let prometheus_router = Router::new().route("/metrics", get(serve_metrics)); diff --git a/linera-service/src/proxy.rs b/linera-service/src/proxy.rs index b2e504269ee..c9b13351773 100644 --- a/linera-service/src/proxy.rs +++ b/linera-service/src/proxy.rs @@ -1,7 +1,7 @@ // Copyright (c) Zefchain Labs, Inc. // SPDX-License-Identifier: Apache-2.0 -use std::{path::PathBuf, time::Duration}; +use std::{net::SocketAddr, path::PathBuf, time::Duration}; use anyhow::{bail, Result}; use async_trait::async_trait; @@ -15,6 +15,8 @@ use linera_rpc::{ simple::{MessageHandler, TransportProtocol}, RpcMessage, }; +#[cfg(with_metrics)] +use linera_service::prometheus_server; use linera_service::{ config::{GenesisConfig, Import, ValidatorServerConfig}, grpc_proxy::GrpcProxy, @@ -24,8 +26,6 @@ use linera_service::{ use linera_storage::Storage; use linera_views::{common::CommonStoreConfig, views::ViewError}; use tracing::{error, info, instrument}; -#[cfg(with_metrics)] -use {linera_service::prometheus_server, std::net::SocketAddr}; /// Options for running the proxy. #[derive(clap::Parser, Debug, Clone)] @@ -232,7 +232,7 @@ where let address = self.get_listen_address(self.public_config.port); #[cfg(with_metrics)] - Self::start_metrics(&self.get_listen_address(self.internal_config.metrics_port)); + Self::start_metrics(self.get_listen_address(self.internal_config.metrics_port)); self.public_config .protocol @@ -244,15 +244,12 @@ where } #[cfg(with_metrics)] - pub fn start_metrics(address: &String) { - match address.parse::() { - Err(err) => panic!("Invalid metrics address for {address}: {err}"), - Ok(address) => prometheus_server::start_metrics(address), - } + pub fn start_metrics(address: SocketAddr) { + prometheus_server::start_metrics(address) } - fn get_listen_address(&self, port: u16) -> String { - format!("0.0.0.0:{}", port) + fn get_listen_address(&self, port: u16) -> SocketAddr { + SocketAddr::from(([0, 0, 0, 0], port)) } async fn try_proxy_message( diff --git a/linera-service/src/server.rs b/linera-service/src/server.rs index 808bece8367..0eabdc24458 100644 --- a/linera-service/src/server.rs +++ b/linera-service/src/server.rs @@ -17,6 +17,8 @@ use linera_rpc::{ }, grpc, simple, }; +#[cfg(with_metrics)] +use linera_service::prometheus_server; use linera_service::{ config::{ CommitteeConfig, Export, GenesisConfig, Import, ValidatorConfig, ValidatorServerConfig, @@ -28,8 +30,6 @@ use linera_storage::Storage; use linera_views::{common::CommonStoreConfig, views::ViewError}; use serde::Deserialize; use tracing::{error, info}; -#[cfg(with_metrics)] -use {linera_service::prometheus_server, std::net::SocketAddr}; struct ServerContext { server_config: ValidatorServerConfig, @@ -84,7 +84,7 @@ impl ServerContext { handles.push(async move { #[cfg(with_metrics)] if let Some(port) = shard.metrics_port { - Self::start_metrics(listen_address, &port); + Self::start_metrics(listen_address, port); } let server = simple::Server::new( internal_network, @@ -128,7 +128,7 @@ impl ServerContext { handles.push(async move { #[cfg(with_metrics)] if let Some(port) = shard.metrics_port { - Self::start_metrics(listen_address, &port); + Self::start_metrics(listen_address, port); } let spawned_server = match grpc::GrpcServer::spawn( listen_address.to_string(), @@ -159,11 +159,8 @@ impl ServerContext { } #[cfg(with_metrics)] - fn start_metrics(host: &str, port: &u16) { - match format!("{}:{}", host, port).parse::() { - Err(err) => panic!("Invalid metrics address for {host}:{port}: {err}"), - Ok(address) => prometheus_server::start_metrics(address), - } + fn start_metrics(host: &str, port: u16) { + prometheus_server::start_metrics((host.to_owned(), port)); } fn get_listen_address(&self) -> String {