LCOV - code coverage report
Current view: top level - storage_broker/src - lib.rs (source / functions) Coverage Total Hit
Test: 20b6afc7b7f34578dcaab2b3acdaecfe91cd8bf1.info Lines: 22.7 % 44 10
Test Date: 2024-11-25 17:48:16 Functions: 14.3 % 7 1

            Line data    Source code
       1              : use std::time::Duration;
       2              : use tonic::codegen::StdError;
       3              : use tonic::transport::{ClientTlsConfig, Endpoint};
       4              : use tonic::{transport::Channel, Status};
       5              : use utils::id::{TenantId, TenantTimelineId, TimelineId};
       6              : 
       7              : use proto::{
       8              :     broker_service_client::BrokerServiceClient, TenantTimelineId as ProtoTenantTimelineId,
       9              : };
      10              : 
      11              : // Code generated by protobuf.
      12              : pub mod proto {
      13              :     // Tonic does derives as `#[derive(Clone, PartialEq, ::prost::Message)]`
      14              :     // we don't use these types for anything but broker data transmission,
      15              :     // so it's ok to ignore this one.
      16              :     #![allow(clippy::derive_partial_eq_without_eq)]
      17              :     tonic::include_proto!("storage_broker");
      18              : }
      19              : 
      20              : pub mod metrics;
      21              : 
      22              : // Re-exports to avoid direct tonic dependency in user crates.
      23              : pub use tonic::Code;
      24              : pub use tonic::Request;
      25              : pub use tonic::Streaming;
      26              : 
      27              : pub use hyper::Uri;
      28              : 
      29              : pub const DEFAULT_LISTEN_ADDR: &str = "127.0.0.1:50051";
      30              : pub const DEFAULT_ENDPOINT: &str = const_format::formatcp!("http://{DEFAULT_LISTEN_ADDR}");
      31              : 
      32              : pub const DEFAULT_KEEPALIVE_INTERVAL: &str = "5000 ms";
      33              : pub const DEFAULT_CONNECT_TIMEOUT: Duration = Duration::from_millis(5000);
      34              : 
      35              : // BrokerServiceClient charged with tonic provided Channel transport; helps to
      36              : // avoid depending on tonic directly in user crates.
      37              : pub type BrokerClientChannel = BrokerServiceClient<Channel>;
      38              : 
      39              : // Create connection object configured to run TLS if schema starts with https://
      40              : // and plain text otherwise. Connection is lazy, only endpoint sanity is
      41              : // validated here.
      42              : //
      43              : // NB: this function is not async, but still must be run on a tokio runtime thread
      44              : // because that's a requirement of tonic_endpoint.connect_lazy()'s Channel::new call.
      45            0 : pub fn connect<U>(endpoint: U, keepalive_interval: Duration) -> anyhow::Result<BrokerClientChannel>
      46            0 : where
      47            0 :     U: std::convert::TryInto<Uri>,
      48            0 :     U::Error: std::error::Error + Send + Sync + 'static,
      49            0 : {
      50            0 :     let uri: Uri = endpoint.try_into()?;
      51            0 :     let mut tonic_endpoint: Endpoint = uri.into();
      52              :     // If schema starts with https, start encrypted connection; do plain text
      53              :     // otherwise.
      54            0 :     if let Some("https") = tonic_endpoint.uri().scheme_str() {
      55              :         // if there's no default provider and both ring+aws-lc-rs are enabled
      56              :         // this the tls settings on tonic will not work.
      57              :         // erroring is ok.
      58            0 :         rustls::crypto::ring::default_provider()
      59            0 :             .install_default()
      60            0 :             .ok();
      61            0 :         let tls = ClientTlsConfig::new();
      62            0 :         tonic_endpoint = tonic_endpoint.tls_config(tls)?;
      63            0 :     }
      64            0 :     tonic_endpoint = tonic_endpoint
      65            0 :         .http2_keep_alive_interval(keepalive_interval)
      66            0 :         .keep_alive_while_idle(true)
      67            0 :         .connect_timeout(DEFAULT_CONNECT_TIMEOUT);
      68            0 :     //  keep_alive_timeout is 20s by default on both client and server side
      69            0 :     let channel = tonic_endpoint.connect_lazy();
      70            0 :     Ok(BrokerClientChannel::new(channel))
      71            0 : }
      72              : 
      73              : impl BrokerClientChannel {
      74              :     /// Create a new client to the given endpoint, but don't actually connect until the first request.
      75            0 :     pub async fn connect_lazy<D>(dst: D) -> Result<Self, tonic::transport::Error>
      76            0 :     where
      77            0 :         D: std::convert::TryInto<tonic::transport::Endpoint>,
      78            0 :         D::Error: Into<StdError>,
      79            0 :     {
      80            0 :         let conn = tonic::transport::Endpoint::new(dst)?.connect_lazy();
      81            0 :         Ok(Self::new(conn))
      82            0 :     }
      83              : }
      84              : 
      85              : // parse variable length bytes from protobuf
      86            2 : pub fn parse_proto_ttid(proto_ttid: &ProtoTenantTimelineId) -> Result<TenantTimelineId, Status> {
      87            2 :     let tenant_id = TenantId::from_slice(&proto_ttid.tenant_id)
      88            2 :         .map_err(|e| Status::new(Code::InvalidArgument, format!("malformed tenant_id: {}", e)))?;
      89            2 :     let timeline_id = TimelineId::from_slice(&proto_ttid.timeline_id).map_err(|e| {
      90            0 :         Status::new(
      91            0 :             Code::InvalidArgument,
      92            0 :             format!("malformed timeline_id: {}", e),
      93            0 :         )
      94            2 :     })?;
      95            2 :     Ok(TenantTimelineId {
      96            2 :         tenant_id,
      97            2 :         timeline_id,
      98            2 :     })
      99            2 : }
        

Generated by: LCOV version 2.1-beta