From fe816e6fbf165f3ebeba3557e11c1cd793644f1c Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Mon, 15 Aug 2022 13:54:33 -0600 Subject: [PATCH 1/3] Use anyhow::Result instead of Result<_, Box> You can't put the latter into the former, and the former can move across thread boundaries while the latter can't. --- Cargo.lock | 1 + ddprof-ffi/Cargo.toml | 1 + ddprof-ffi/src/exporter.rs | 11 ++++------- profiling/src/exporter/config.rs | 9 +++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b4bfca61..e0ad94dbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,6 +183,7 @@ dependencies = [ name = "ddprof-ffi" version = "0.7.0-rc.1" dependencies = [ + "anyhow", "chrono", "datadog-profiling", "ddcommon", diff --git a/ddprof-ffi/Cargo.toml b/ddprof-ffi/Cargo.toml index a7d7a1cf5..e1de958ba 100644 --- a/ddprof-ffi/Cargo.toml +++ b/ddprof-ffi/Cargo.toml @@ -13,6 +13,7 @@ license = "Apache-2.0" crate-type = ["staticlib", "cdylib"] [dependencies] +anyhow = "1.0" chrono = "0.4" datadog-profiling = { path = "../profiling", version = "0.7.0-rc.1" } hyper = {version = "0.14", default-features = false} diff --git a/ddprof-ffi/src/exporter.rs b/ddprof-ffi/src/exporter.rs index 282db6dc1..5fece6d14 100644 --- a/ddprof-ffi/src/exporter.rs +++ b/ddprof-ffi/src/exporter.rs @@ -82,19 +82,16 @@ pub extern "C" fn endpoint_agentless<'a>( Endpoint::Agentless(site, api_key) } -unsafe fn try_to_url(slice: CharSlice) -> Result> { +unsafe fn try_to_url(slice: CharSlice) -> anyhow::Result { let str: &str = slice.try_to_utf8()?; #[cfg(unix)] if let Some(path) = str.strip_prefix("unix://") { return Ok(exporter::socket_path_to_uri(path.as_ref())?); } - match hyper::Uri::from_str(str) { - Ok(url) => Ok(url), - Err(err) => Err(Box::new(err)), - } + Ok(hyper::Uri::from_str(str)?) } -unsafe fn try_to_endpoint(endpoint: Endpoint) -> Result> { +unsafe fn try_to_endpoint(endpoint: Endpoint) -> anyhow::Result { // convert to utf8 losslessly -- URLs and API keys should all be ASCII, so // a failed result is likely to be an error. match endpoint { @@ -216,7 +213,7 @@ pub unsafe extern "C" fn profile_exporter_send( let cancel_option = unwrap_cancellation_token(cancel); - match || -> Result> { + match || -> Result> { let response = exp_ptr.as_ref().send((*request_ptr).0, cancel_option)?; Ok(HttpStatus(response.status().as_u16())) diff --git a/profiling/src/exporter/config.rs b/profiling/src/exporter/config.rs index 311adb7ea..67ab8ff57 100644 --- a/profiling/src/exporter/config.rs +++ b/profiling/src/exporter/config.rs @@ -6,13 +6,14 @@ use ddcommon::connector::uds; use ddcommon::Endpoint; use http::Uri; -use std::{borrow::Cow, error::Error, str::FromStr}; +use std::borrow::Cow; +use std::str::FromStr; /// Creates an Endpoint for talking to the Datadog agent. /// /// # Arguments /// * `base_url` - has protocol, host, and port e.g. http://localhost:8126/ -pub fn agent(base_url: Uri) -> Result> { +pub fn agent(base_url: Uri) -> anyhow::Result { let mut parts = base_url.into_parts(); let p_q = match parts.path_and_query { None => None, @@ -32,7 +33,7 @@ pub fn agent(base_url: Uri) -> Result> { /// # Arguments /// * `socket_path` - file system path to the socket #[cfg(unix)] -pub fn agent_uds(path: &std::path::Path) -> Result> { +pub fn agent_uds(path: &std::path::Path) -> anyhow::Result { let base_url = uds::socket_path_to_uri(path)?; agent(base_url) } @@ -46,7 +47,7 @@ pub fn agent_uds(path: &std::path::Path) -> Result> { pub fn agentless, IntoCow: Into>>( site: AsStrRef, api_key: IntoCow, -) -> Result> { +) -> anyhow::Result { let intake_url: String = format!("https://intake.profile.{}/v1/input", site.as_ref()); Ok(Endpoint { From 37770624fbc6d0f917392663b7b44fc75c865138 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Mon, 15 Aug 2022 15:04:10 -0600 Subject: [PATCH 2/3] Continue the anyhow::Result adoption --- ddcommon-ffi/src/vec.rs | 10 ++-------- ddprof-ffi/src/exporter.rs | 5 ++--- ddprof-ffi/src/profiles.rs | 5 +++-- profiling/src/exporter/mod.rs | 10 +++++----- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/ddcommon-ffi/src/vec.rs b/ddcommon-ffi/src/vec.rs index 4ea1399b3..0474dab74 100644 --- a/ddcommon-ffi/src/vec.rs +++ b/ddcommon-ffi/src/vec.rs @@ -47,20 +47,14 @@ impl From> for Vec { } } -impl From<&dyn std::error::Error> for Vec { - fn from(err: &dyn std::error::Error) -> Self { +impl From for Vec { + fn from(err: anyhow::Error) -> Self { let mut vec = vec![]; write!(vec, "{}", err).expect("write to vec to always succeed"); Self::from(vec) } } -impl From> for Vec { - fn from(err: Box) -> Self { - Self::from(&*err) - } -} - impl<'a, T> IntoIterator for &'a Vec { type Item = &'a T; type IntoIter = core::slice::Iter<'a, T>; diff --git a/ddprof-ffi/src/exporter.rs b/ddprof-ffi/src/exporter.rs index 5fece6d14..339bf3161 100644 --- a/ddprof-ffi/src/exporter.rs +++ b/ddprof-ffi/src/exporter.rs @@ -10,7 +10,6 @@ use ddcommon::tag::Tag; use ddcommon_ffi::slice::{AsBytes, ByteSlice, CharSlice, Slice}; use exporter::ProfileExporter; use std::borrow::Cow; -use std::error::Error; use std::ptr::NonNull; use std::str::FromStr; @@ -117,7 +116,7 @@ pub extern "C" fn profile_exporter_new( tags: Option<&ddcommon_ffi::Vec>, endpoint: Endpoint, ) -> NewProfileExporterResult { - match || -> Result> { + match || -> anyhow::Result { let family = unsafe { family.to_utf8_lossy() }.into_owned(); let converted_endpoint = unsafe { try_to_endpoint(endpoint)? }; let tags = tags.map(|tags| tags.iter().map(|tag| tag.clone().into_owned()).collect()); @@ -213,7 +212,7 @@ pub unsafe extern "C" fn profile_exporter_send( let cancel_option = unwrap_cancellation_token(cancel); - match || -> Result> { + match || -> anyhow::Result { let response = exp_ptr.as_ref().send((*request_ptr).0, cancel_option)?; Ok(HttpStatus(response.status().as_u16())) diff --git a/ddprof-ffi/src/profiles.rs b/ddprof-ffi/src/profiles.rs index 688e947b1..9c1906f5e 100644 --- a/ddprof-ffi/src/profiles.rs +++ b/ddprof-ffi/src/profiles.rs @@ -5,7 +5,6 @@ use crate::Timespec; use datadog_profiling::profile as profiles; use ddcommon_ffi::slice::{AsBytes, CharSlice, Slice}; use std::convert::{TryFrom, TryInto}; -use std::error::Error; use std::str::Utf8Error; use std::time::{Duration, SystemTime}; @@ -420,7 +419,9 @@ pub unsafe extern "C" fn ddog_Profile_serialize( Some(x) if *x < 0 => None, Some(x) => Some(Duration::from_nanos((*x) as u64)), }; - match || -> Result<_, Box> { Ok(profile.serialize(end_time, duration)?) }() { + match || -> anyhow::Result { + Ok(profile.serialize(end_time, duration)?) + }() { Ok(ok) => SerializeResult::Ok(ok.into()), Err(err) => SerializeResult::Err(err.into()), } diff --git a/profiling/src/exporter/mod.rs b/profiling/src/exporter/mod.rs index f47215737..339881570 100644 --- a/profiling/src/exporter/mod.rs +++ b/profiling/src/exporter/mod.rs @@ -83,7 +83,7 @@ impl Request { self, client: &HttpClient, cancel: Option<&CancellationToken>, - ) -> Result, Box> { + ) -> anyhow::Result> { tokio::select! { _ = async { match cancel { Some(cancellation_token) => cancellation_token.cancelled().await, @@ -108,7 +108,7 @@ impl ProfileExporter { family: IntoCow, tags: Option>, endpoint: Endpoint, - ) -> Result> { + ) -> anyhow::Result { Ok(Self { exporter: Exporter::new()?, endpoint, @@ -163,7 +163,7 @@ impl ProfileExporter { &self, request: Request, cancel: Option<&CancellationToken>, - ) -> Result> { + ) -> anyhow::Result { self.exporter .runtime .block_on(request.send(&self.exporter.client, cancel)) @@ -172,7 +172,7 @@ impl ProfileExporter { impl Exporter { /// Creates a new Exporter, initializing the TLS stack. - pub fn new() -> Result> { + pub fn new() -> anyhow::Result { // Set idle to 0, which prevents the pipe being broken every 2nd request let client = hyper::Client::builder() .pool_max_idle_per_host(0) @@ -190,7 +190,7 @@ impl Exporter { mut headers: hyper::header::HeaderMap, body: &[u8], timeout: std::time::Duration, - ) -> Result, Box> { + ) -> anyhow::Result> { self.runtime.block_on(async { let mut request = hyper::Request::builder() .method(http_method) From 02e9ff72a82ed85a31f368e8d9d6824d1f1e4251 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Mon, 15 Aug 2022 15:11:06 -0600 Subject: [PATCH 3/3] Continue the anyhow::Result adoption --- profiling/src/exporter/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/profiling/src/exporter/mod.rs b/profiling/src/exporter/mod.rs index 339881570..40aea7448 100644 --- a/profiling/src/exporter/mod.rs +++ b/profiling/src/exporter/mod.rs @@ -2,7 +2,6 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021-Present Datadog, Inc. use std::borrow::Cow; -use std::error::Error; use std::future; use std::io::Cursor; @@ -125,7 +124,7 @@ impl ProfileExporter { files: &[File], additional_tags: Option<&Vec>, timeout: std::time::Duration, - ) -> Result> { + ) -> anyhow::Result { let mut form = multipart::Form::default(); form.add_text("version", "3");