From 39d4b979616b9cbf51bcf68d23c1a9647ec62bfd Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 16 Jul 2026 19:33:44 +0200 Subject: [PATCH 1/2] Expose HttpClientCapability in remote config As a side-effect, this fixes the missing timeout on the remote config body awaiting. Signed-off-by: Bob Weinand --- Cargo.lock | 4 ++ datadog-sidecar/src/shm_remote_config.rs | 12 +++-- libdd-capabilities-impl/src/http.rs | 34 ++++++++++++- libdd-remote-config/Cargo.toml | 11 ++++- .../examples/remote_config_fetch.rs | 4 +- libdd-remote-config/src/fetch/fetcher.rs | 48 ++++++++++++------- libdd-remote-config/src/fetch/multitarget.rs | 41 ++++++++++------ libdd-remote-config/src/fetch/shared.rs | 28 +++++++---- libdd-remote-config/src/fetch/single.rs | 36 ++++++++++---- libdd-tracer-flare/Cargo.toml | 3 ++ libdd-tracer-flare/src/lib.rs | 6 ++- 11 files changed, 166 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f4b2e9f9d4..0b444be9f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3328,6 +3328,7 @@ version = "2.0.0" dependencies = [ "anyhow", "base64 0.22.1", + "bytes", "futures", "futures-util", "hashbrown 0.15.1", @@ -3335,6 +3336,8 @@ dependencies = [ "http-body-util", "hyper", "hyper-util", + "libdd-capabilities", + "libdd-capabilities-impl", "libdd-common", "libdd-remote-config", "libdd-trace-protobuf", @@ -3574,6 +3577,7 @@ dependencies = [ "bytes", "http", "httpmock", + "libdd-capabilities-impl", "libdd-common", "libdd-remote-config", "libdd-trace-utils", diff --git a/datadog-sidecar/src/shm_remote_config.rs b/datadog-sidecar/src/shm_remote_config.rs index e94e1f305e..a8ca4fa1ec 100644 --- a/datadog-sidecar/src/shm_remote_config.rs +++ b/datadog-sidecar/src/shm_remote_config.rs @@ -10,6 +10,7 @@ use datadog_ipc::one_way_shared_memory::{open_named_shm, OneWayShmReader, OneWay use datadog_ipc::platform::{FileBackedHandle, NamedShmHandle}; use datadog_ipc::rate_limiter::ShmLimiter; use datadog_live_debugger::LiveDebuggingData; +use libdd_capabilities_impl::NativeHttpClient; use libdd_common::{tag::Tag, MutexExt}; use libdd_remote_config::config::dynamic::{parse_json, Configs}; use libdd_remote_config::fetch::{ @@ -245,10 +246,12 @@ fn dynamic_instrumentation_is_enabled(apm_config: Option, info: &TargetInf } } -impl MultiTargetHandlers for ConfigFileStorage { +impl MultiTargetHandlers + for ConfigFileStorage +{ fn fetched( &self, - fetcher: &Arc>, + fetcher: &Arc>, runtime_id: &Arc, target: &Arc, files: &[Arc], @@ -422,7 +425,7 @@ impl Drop for ShmRemoteConfigsGuard { #[derive(Clone)] pub struct ShmRemoteConfigs( - Arc>>, + Arc, NativeHttpClient>>, ); // we collect services per env, so that we always query, for each runtime + env, all the services @@ -448,7 +451,8 @@ impl ShmRemoteConfigs { on_dead: Arc::new(Mutex::new(Some(on_dead))), _phantom: Default::default(), }; - let fetcher = MultiTargetFetcher::new(storage, invariants); + let fetcher = + MultiTargetFetcher::new(storage, invariants, NativeHttpClient::new_periodic_client()); fetcher .remote_config_interval .store(interval.as_nanos() as u64, Ordering::Relaxed); diff --git a/libdd-capabilities-impl/src/http.rs b/libdd-capabilities-impl/src/http.rs index e6af5b853c..9f76efe6ae 100644 --- a/libdd-capabilities-impl/src/http.rs +++ b/libdd-capabilities-impl/src/http.rs @@ -9,27 +9,47 @@ mod native { use libdd_capabilities::http::{HttpClientCapability, HttpError}; use libdd_capabilities::maybe_send::MaybeSend; use libdd_common::connector::Connector; - use libdd_common::http_common::{new_default_client, Body, GenericHttpClient}; + use libdd_common::http_common::{ + new_client_periodic, new_default_client, Body, GenericHttpClient, + }; use http_body_util::BodyExt; #[derive(Clone)] pub struct NativeHttpClient { client: Arc>>, + periodic: bool, } impl std::fmt::Debug for NativeHttpClient { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("NativeHttpClient") .field("initialized", &self.client.get().is_some()) + .field("periodic", &self.periodic) .finish() } } + impl NativeHttpClient { + /// Like [`HttpClientCapability::new_client`], but disables connection pooling. + /// + /// Intended for clients that issue requests on a fixed interval (e.g. remote + /// config polling): the agent's low keep-alive setting can close an idle + /// connection between polls, which turns a pooled/reused connection into + /// intermittent request failures. + pub fn new_periodic_client() -> Self { + Self { + client: Arc::new(OnceLock::new()), + periodic: true, + } + } + } + impl HttpClientCapability for NativeHttpClient { fn new_client() -> Self { Self { client: Arc::new(OnceLock::new()), + periodic: false, } } @@ -39,7 +59,17 @@ mod native { req: http::Request, ) -> impl std::future::Future, HttpError>> + MaybeSend { - let client = self.client.get_or_init(new_default_client).clone(); + let periodic = self.periodic; + let client = self + .client + .get_or_init(|| { + if periodic { + new_client_periodic() + } else { + new_default_client() + } + }) + .clone(); async move { let hyper_req = req.map(Body::from_bytes); diff --git a/libdd-remote-config/Cargo.toml b/libdd-remote-config/Cargo.toml index 0cfcca5f25..34dbaeb514 100644 --- a/libdd-remote-config/Cargo.toml +++ b/libdd-remote-config/Cargo.toml @@ -13,6 +13,8 @@ description = "Datadog Remote Configuration client and config parsers" default = ["client", "https"] client = [ "libdd-trace-protobuf", + "libdd-capabilities", + "bytes", "http-body-util", "http", "base64", @@ -28,14 +30,16 @@ client = [ regex-lite = ["libdd-common/regex-lite"] # Enable HTTPS support in the fetcher (rustls + ring via libdd-common). -https = ["libdd-common/https"] +https = ["libdd-common/https", "libdd-capabilities-impl/https"] # FIPS-compliant crypto provider (aws-lc-rs via libdd-common). Unix only. -fips = ["libdd-common/fips"] +fips = ["libdd-common/fips", "libdd-capabilities-impl/fips"] test = ["hyper/server", "hyper-util"] [dependencies] anyhow = { version = "1.0" } +bytes = { version = "1", optional = true } libdd-common = { path = "../libdd-common", version = "5.1.0", default-features = false } +libdd-capabilities = { path = "../libdd-capabilities", version = "2.1.0", optional = true } libdd-trace-protobuf = { path = "../libdd-trace-protobuf", version = "4.0.0", optional = true } hyper = { workspace = true, optional = true, default-features = false } http-body-util = {version = "0.1", optional = true } @@ -61,6 +65,9 @@ strum_macros = "0.26" # Test feature hyper-util = { workspace = true, features = ["service"], optional = true } +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +libdd-capabilities-impl = { path = "../libdd-capabilities-impl", version = "3.0.0", default-features = false } + [dev-dependencies] futures = "0.3" libdd-remote-config = { path = ".", features = ["test"] } diff --git a/libdd-remote-config/examples/remote_config_fetch.rs b/libdd-remote-config/examples/remote_config_fetch.rs index 9686643c15..a49281bc94 100644 --- a/libdd-remote-config/examples/remote_config_fetch.rs +++ b/libdd-remote-config/examples/remote_config_fetch.rs @@ -1,6 +1,7 @@ // Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ // SPDX-License-Identifier: Apache-2.0 +use libdd_capabilities_impl::NativeHttpClient; use libdd_common::Endpoint; use libdd_remote_config::fetch::{ConfigInvariants, ConfigOptions, SingleChangesFetcher}; use libdd_remote_config::file_change_tracker::{Change, FilePath}; @@ -21,7 +22,7 @@ async fn main() { // Otherwise a SharedFetcher (or even a MultiTargetFetcher for a potentially high number of // targets) for multiple targets is needed. These can be manually wired together with a // ChangeTracker to keep track of changes. The SingleChangesTracker does it for you. - let mut fetcher = SingleChangesFetcher::new( + let mut fetcher = SingleChangesFetcher::with_client( // Use SimpleFileStorage if you desire just the raw, unparsed contents // (e.g. to do processing directly in your language) // For more complicated use cases, like needing to store data in shared memory, a custom @@ -50,6 +51,7 @@ async fn main() { products: vec![ApmTracing], capabilities: vec![], }, + NativeHttpClient::new_periodic_client(), ); loop { diff --git a/libdd-remote-config/src/fetch/fetcher.rs b/libdd-remote-config/src/fetch/fetcher.rs index e43aa23b43..42d06ad63f 100644 --- a/libdd-remote-config/src/fetch/fetcher.rs +++ b/libdd-remote-config/src/fetch/fetcher.rs @@ -7,8 +7,8 @@ use base64::Engine; use hashbrown::HashMap; use http::uri::PathAndQuery; use http::StatusCode; -use http_body_util::BodyExt; -use libdd_common::{http_common, Endpoint, MutexExt}; +use libdd_capabilities::HttpClientCapability; +use libdd_common::{Endpoint, MutexExt}; use libdd_trace_protobuf::remoteconfig::{ ClientGetConfigsRequest, ClientGetConfigsResponse, ClientState, ClientTracer, ConfigState, TargetFileHash, TargetFileMeta, @@ -104,11 +104,12 @@ impl ConfigProductCapabilities { } } -pub struct ConfigFetcherState { +pub struct ConfigFetcherState { target_files_by_path: Mutex, StoredTargetFile>>, pub invariants: ConfigInvariants, endpoint: Endpoint, pub expire_unused_files: bool, + http_client: C, } #[derive(Debug, Default, Serialize, Deserialize)] @@ -152,13 +153,14 @@ impl ConfigFetcherFilesLock<'_, S> { } } -impl ConfigFetcherState { - pub fn new(invariants: ConfigInvariants) -> Self { +impl ConfigFetcherState { + pub fn with_client(invariants: ConfigInvariants, http_client: C) -> Self { ConfigFetcherState { target_files_by_path: Default::default(), endpoint: get_agent_configs_endpoint(&invariants.endpoint), invariants, expire_unused_files: true, + http_client, } } @@ -201,9 +203,9 @@ impl ConfigFetcherState { } } -pub struct ConfigFetcher { +pub struct ConfigFetcher { pub file_storage: S, - state: Arc>, + state: Arc>, } pub struct ConfigClientState { @@ -236,8 +238,8 @@ impl ConfigClientState { } } -impl ConfigFetcher { - pub fn new(file_storage: S, state: Arc>) -> Self { +impl ConfigFetcher { + pub fn new(file_storage: S, state: Arc>) -> Self { ConfigFetcher { file_storage, state, @@ -361,16 +363,16 @@ impl ConfigFetcher { http::header::CONTENT_TYPE, libdd_common::header::APPLICATION_JSON, ) - .body(http_common::Body::from(serde_json::to_string(&config_req)?))?; + .body(bytes::Bytes::from(serde_json::to_string(&config_req)?))?; let response = tokio::time::timeout( Duration::from_millis(self.state.endpoint.timeout_ms), - http_common::new_default_client().request(req), + self.state.http_client.request(req), ) .await .map_err(|e| anyhow::Error::msg(e).context(format!("Url: {:?}", self.state.endpoint)))? .map_err(|e| anyhow::Error::msg(e).context(format!("Url: {:?}", self.state.endpoint)))?; let status = response.status(); - let body_bytes = response.into_body().collect().await?.to_bytes(); + let body_bytes = response.into_body(); if status != StatusCode::OK { // Not active if status == StatusCode::NOT_FOUND { @@ -578,6 +580,8 @@ pub mod tests { use crate::fetch::test_server::RemoteConfigServer; use crate::RemoteConfigSource; use http::Response; + use libdd_capabilities_impl::NativeHttpClient; + use libdd_common::http_common; use std::mem::transmute; use std::sync::LazyLock; @@ -690,7 +694,10 @@ pub mod tests { let storage = Arc::new(Storage::default()); let mut fetcher = ConfigFetcher::new( storage.clone(), - Arc::new(ConfigFetcherState::new(server.dummy_options().invariants)), + Arc::new(ConfigFetcherState::with_client( + server.dummy_options().invariants, + NativeHttpClient::new_periodic_client(), + )), ); let mut opaque_state = ConfigClientState::default(); @@ -740,7 +747,10 @@ pub mod tests { let mut fetcher = ConfigFetcher::new( storage.clone(), - Arc::new(ConfigFetcherState::new(invariants)), + Arc::new(ConfigFetcherState::with_client( + invariants, + NativeHttpClient::new_periodic_client(), + )), ); let mut opaque_state = ConfigClientState::default(); @@ -924,7 +934,10 @@ pub mod tests { let storage = Arc::new(Storage::default()); let mut fetcher = ConfigFetcher::new( storage, - Arc::new(ConfigFetcherState::new(server.dummy_options().invariants)), + Arc::new(ConfigFetcherState::with_client( + server.dummy_options().invariants, + NativeHttpClient::new_periodic_client(), + )), ); let mut opaque_state = ConfigClientState::default(); @@ -1022,7 +1035,10 @@ pub mod tests { let storage = Arc::new(Storage::default()); let mut fetcher = ConfigFetcher::new( storage, - Arc::new(ConfigFetcherState::new(server.dummy_options().invariants)), + Arc::new(ConfigFetcherState::with_client( + server.dummy_options().invariants, + NativeHttpClient::new_periodic_client(), + )), ); let mut opaque_state = ConfigClientState::default(); diff --git a/libdd-remote-config/src/fetch/multitarget.rs b/libdd-remote-config/src/fetch/multitarget.rs index a3a04572cf..c9a1f80d45 100644 --- a/libdd-remote-config/src/fetch/multitarget.rs +++ b/libdd-remote-config/src/fetch/multitarget.rs @@ -8,6 +8,7 @@ use crate::fetch::{ use crate::{RemoteConfigCapabilities, RemoteConfigProduct, Target}; use futures_util::future::Shared; use futures_util::FutureExt; +use libdd_capabilities::HttpClientCapability; use libdd_common::MutexExt; use manual_future::ManualFuture; use serde::{Deserialize, Serialize}; @@ -33,10 +34,13 @@ use tracing::{debug, error, trace}; /// This fetcher is designed for use cases with more than one Target tuple associated to a /// specific runtime id and/or handling hundreds to thousands of different runtime ids with a low /// amount of actual remote config clients. -pub struct MultiTargetFetcher -where +pub struct MultiTargetFetcher< + N: NotifyTarget, + S: FileStorage + Clone + Sync + Send, + C: HttpClientCapability + Send + Sync, +> where S::StoredFile: RefcountedFile + Sync + Send, - S: MultiTargetHandlers, + S: MultiTargetHandlers, { /// Keyed by runtime_id runtimes: Mutex>>, @@ -46,7 +50,7 @@ where /// WARNING: do NOT lock runtimes while holding a lock to services! services: Mutex, KnownTarget>>, pending_async_insertions: AtomicU32, - pub storage: RefcountingStorage, + pub storage: RefcountingStorage, /// Limit on how many fetchers can be active at once. /// This functionality is mostly targeted at CLI programs which generally have their file name /// as the service name. E.g. a phpt testsuite will generate one service for every single file. @@ -151,13 +155,14 @@ pub trait NotifyTarget: Sync + Send + Sized + Hash + Eq + Clone + Debug { pub trait MultiTargetHandlers< N: NotifyTarget, - S: FileStorage + Clone + Sync + Send + MultiTargetHandlers, + S: FileStorage + Clone + Sync + Send + MultiTargetHandlers, + C: HttpClientCapability + Send + Sync, > where S::StoredFile: RefcountedFile + Sync + Send, { fn fetched( &self, - fetcher: &Arc>, + fetcher: &Arc>, runtime_id: &Arc, target: &Arc, files: &[Arc], @@ -178,17 +183,23 @@ struct RuntimeInfo { targets: HashMap, u32>, } -impl - MultiTargetFetcher +impl< + N: NotifyTarget + 'static, + S: FileStorage + Clone + Sync + Send + 'static, + C: HttpClientCapability + Send + Sync + 'static, + > MultiTargetFetcher where S::StoredFile: RefcountedFile + Sync + Send, - S: MultiTargetHandlers, + S: MultiTargetHandlers, { pub const DEFAULT_CLIENTS_LIMIT: u32 = 100; - pub fn new(storage: S, invariants: ConfigInvariants) -> Arc { + pub fn new(storage: S, invariants: ConfigInvariants, http_client: C) -> Arc { Arc::new(MultiTargetFetcher { - storage: RefcountingStorage::new(storage, ConfigFetcherState::new(invariants)), + storage: RefcountingStorage::new( + storage, + ConfigFetcherState::with_client(invariants, http_client), + ), runtimes: Mutex::new(Default::default()), remote_config_interval: AtomicU64::new(5_000_000_000), services: Mutex::new(Default::default()), @@ -774,6 +785,7 @@ mod tests { use crate::fetch::shared::tests::*; use crate::fetch::test_server::RemoteConfigServer; use crate::{RemoteConfigPath, Target}; + use libdd_capabilities_impl::NativeHttpClient; use manual_future::ManualFutureCompleter; use std::hash::Hasher; use std::sync::atomic::AtomicU8; @@ -810,10 +822,10 @@ mod tests { } } - impl MultiTargetHandlers for MultiFileStorage { + impl MultiTargetHandlers for MultiFileStorage { fn fetched( &self, - _fetcher: &Arc>, + _fetcher: &Arc>, _runtime_id: &Arc, target: &Arc, files: &[Arc], @@ -955,9 +967,10 @@ mod tests { let fut = storage.await_fetches(1); - let fetcher = MultiTargetFetcher::::new( + let fetcher = MultiTargetFetcher::::new( storage.clone(), server.dummy_options().invariants, + NativeHttpClient::new_periodic_client(), ); fetcher.remote_config_interval.store(1000, Ordering::SeqCst); diff --git a/libdd-remote-config/src/fetch/shared.rs b/libdd-remote-config/src/fetch/shared.rs index d4e3b6e11f..0cd12bdbf8 100644 --- a/libdd-remote-config/src/fetch/shared.rs +++ b/libdd-remote-config/src/fetch/shared.rs @@ -6,6 +6,7 @@ use crate::fetch::{ ConfigFetcherStateStats, ConfigInvariants, ConfigProductCapabilities, FileStorage, }; use crate::{RemoteConfigPath, Target}; +use libdd_capabilities::HttpClientCapability; use libdd_common::MutexExt; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -126,12 +127,12 @@ impl RunnersGeneration { } } -pub struct RefcountingStorage +pub struct RefcountingStorage where S::StoredFile: RefcountedFile, { pub storage: S, - state: Arc>, + state: Arc>, /// Stores recently expired files. When a file refcount drops to zero, they're no longer sent /// via the remote config client. However, there may still be in-flight requests, with telling /// the remote config server that we know about these files. Thus, as long as these requests @@ -160,7 +161,7 @@ impl Add for RefcountingStorageStats { } } -impl Clone for RefcountingStorage +impl Clone for RefcountingStorage where S::StoredFile: RefcountedFile, { @@ -174,11 +175,11 @@ where } } -impl RefcountingStorage +impl RefcountingStorage where S::StoredFile: RefcountedFile, { - pub fn new(storage: S, mut state: ConfigFetcherState) -> Self { + pub fn new(storage: S, mut state: ConfigFetcherState) -> Self { state.expire_unused_files = false; RefcountingStorage { storage, @@ -222,7 +223,7 @@ where } } -impl FileStorage for RefcountingStorage +impl FileStorage for RefcountingStorage where S::StoredFile: RefcountedFile, { @@ -267,9 +268,9 @@ impl SharedFetcher { /// On successful fetches on_fetch() is called with the new configuration. /// Should not be called more than once. #[allow(clippy::type_complexity)] - pub async fn run( + pub async fn run( &self, - storage: RefcountingStorage, + storage: RefcountingStorage, on_fetch: Box>)>, ) where S::StoredFile: RefcountedFile, @@ -377,6 +378,7 @@ pub mod tests { use crate::fetch::test_server::RemoteConfigServer; use crate::Target; use futures::future::join_all; + use libdd_capabilities_impl::NativeHttpClient; use std::sync::{Arc, LazyLock}; pub(crate) static OTHER_TARGET: LazyLock> = LazyLock::new(|| { @@ -435,7 +437,10 @@ pub mod tests { let storage = RcFileStorage::default(); let rc_storage = RefcountingStorage::new( storage.clone(), - ConfigFetcherState::new(server.dummy_options().invariants), + ConfigFetcherState::with_client( + server.dummy_options().invariants, + NativeHttpClient::new_periodic_client(), + ), ); server.files.lock().unwrap().insert( @@ -497,7 +502,10 @@ pub mod tests { let storage = RcFileStorage::default(); let rc_storage = RefcountingStorage::new( storage.clone(), - ConfigFetcherState::new(server.dummy_options().invariants), + ConfigFetcherState::with_client( + server.dummy_options().invariants, + NativeHttpClient::new_periodic_client(), + ), ); server.files.lock().unwrap().insert( diff --git a/libdd-remote-config/src/fetch/single.rs b/libdd-remote-config/src/fetch/single.rs index bcc4398066..2b6461acfe 100644 --- a/libdd-remote-config/src/fetch/single.rs +++ b/libdd-remote-config/src/fetch/single.rs @@ -7,11 +7,12 @@ use crate::fetch::{ }; use crate::file_change_tracker::{Change, ChangeTracker, FilePath, UpdatedFiles}; use crate::{RemoteConfigCapabilities, RemoteConfigPath, RemoteConfigProduct, Target}; +use libdd_capabilities::HttpClientCapability; use std::sync::Arc; /// Simple implementation -pub struct SingleFetcher { - fetcher: ConfigFetcher, +pub struct SingleFetcher { + fetcher: ConfigFetcher, target: Arc, product_capabilities: ConfigProductCapabilities, runtime_id: String, @@ -26,12 +27,21 @@ pub struct ConfigOptions { pub capabilities: Vec, } -impl SingleFetcher { - pub fn new(sink: S, target: Target, runtime_id: String, options: ConfigOptions) -> Self { +impl SingleFetcher { + pub fn with_client( + sink: S, + target: Target, + runtime_id: String, + options: ConfigOptions, + http_client: C, + ) -> Self { SingleFetcher { fetcher: ConfigFetcher::new( sink, - Arc::new(ConfigFetcherState::new(options.invariants)), + Arc::new(ConfigFetcherState::with_client( + options.invariants, + http_client, + )), ), target: Arc::new(target), product_capabilities: ConfigProductCapabilities::new( @@ -96,22 +106,28 @@ impl SingleFetcher { } } -pub struct SingleChangesFetcher +pub struct SingleChangesFetcher where S::StoredFile: FilePath, { changes: ChangeTracker, - pub fetcher: SingleFetcher, + pub fetcher: SingleFetcher, } -impl SingleChangesFetcher +impl SingleChangesFetcher where S::StoredFile: FilePath, { - pub fn new(sink: S, target: Target, runtime_id: String, options: ConfigOptions) -> Self { + pub fn with_client( + sink: S, + target: Target, + runtime_id: String, + options: ConfigOptions, + http_client: C, + ) -> Self { SingleChangesFetcher { changes: ChangeTracker::default(), - fetcher: SingleFetcher::new(sink, target, runtime_id, options), + fetcher: SingleFetcher::with_client(sink, target, runtime_id, options, http_client), } } diff --git a/libdd-tracer-flare/Cargo.toml b/libdd-tracer-flare/Cargo.toml index 972ed66b0f..05b31d8984 100644 --- a/libdd-tracer-flare/Cargo.toml +++ b/libdd-tracer-flare/Cargo.toml @@ -24,6 +24,9 @@ zip = { version = "4.0.0", default-features = false, features = ["deflate"] } walkdir = "2.4" tempfile = "3.8" +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +libdd-capabilities-impl = { version = "3.0.0", path = "../libdd-capabilities-impl", default-features = false } + [lib] bench = false diff --git a/libdd-tracer-flare/src/lib.rs b/libdd-tracer-flare/src/lib.rs index e093dd8cb9..1f6c548c4e 100644 --- a/libdd-tracer-flare/src/lib.rs +++ b/libdd-tracer-flare/src/lib.rs @@ -25,6 +25,7 @@ use libdd_remote_config::{ use crate::error::FlareError; #[cfg(feature = "listener")] use { + libdd_capabilities_impl::NativeHttpClient, libdd_common::Endpoint, libdd_remote_config::{ fetch::{ConfigInvariants, ConfigOptions, SingleChangesFetcher}, @@ -189,11 +190,12 @@ impl TracerFlareManager { capabilities: vec![], }; - tracer_flare.listener = Some(SingleChangesFetcher::new( + tracer_flare.listener = Some(SingleChangesFetcher::with_client( ParsedFileStorage::default(), Target::new(service, env, app_version, vec![], vec![]), runtime_id, config_to_fetch, + NativeHttpClient::new_periodic_client(), )); Ok(tracer_flare) @@ -361,7 +363,7 @@ impl TryFrom<&str> for LogLevel { #[cfg(feature = "listener")] pub type RemoteConfigFile = std::sync::Arc>>>; #[cfg(feature = "listener")] -pub type Listener = SingleChangesFetcher; +pub type Listener = SingleChangesFetcher; #[cfg(feature = "listener")] impl TryFrom for FlareAction { From 3d29427932d6d9b71224c3eb9d5cfdb95ea88a45 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 20 Jul 2026 15:29:47 +0200 Subject: [PATCH 2/2] Rename new() functions Signed-off-by: Bob Weinand --- libdd-remote-config/examples/remote_config_fetch.rs | 2 +- libdd-remote-config/src/fetch/single.rs | 6 +++--- libdd-tracer-flare/src/lib.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libdd-remote-config/examples/remote_config_fetch.rs b/libdd-remote-config/examples/remote_config_fetch.rs index a49281bc94..11cd855628 100644 --- a/libdd-remote-config/examples/remote_config_fetch.rs +++ b/libdd-remote-config/examples/remote_config_fetch.rs @@ -22,7 +22,7 @@ async fn main() { // Otherwise a SharedFetcher (or even a MultiTargetFetcher for a potentially high number of // targets) for multiple targets is needed. These can be manually wired together with a // ChangeTracker to keep track of changes. The SingleChangesTracker does it for you. - let mut fetcher = SingleChangesFetcher::with_client( + let mut fetcher = SingleChangesFetcher::new( // Use SimpleFileStorage if you desire just the raw, unparsed contents // (e.g. to do processing directly in your language) // For more complicated use cases, like needing to store data in shared memory, a custom diff --git a/libdd-remote-config/src/fetch/single.rs b/libdd-remote-config/src/fetch/single.rs index 2b6461acfe..247ed16e75 100644 --- a/libdd-remote-config/src/fetch/single.rs +++ b/libdd-remote-config/src/fetch/single.rs @@ -28,7 +28,7 @@ pub struct ConfigOptions { } impl SingleFetcher { - pub fn with_client( + pub fn new( sink: S, target: Target, runtime_id: String, @@ -118,7 +118,7 @@ impl SingleChangesFetcher where S::StoredFile: FilePath, { - pub fn with_client( + pub fn new( sink: S, target: Target, runtime_id: String, @@ -127,7 +127,7 @@ where ) -> Self { SingleChangesFetcher { changes: ChangeTracker::default(), - fetcher: SingleFetcher::with_client(sink, target, runtime_id, options, http_client), + fetcher: SingleFetcher::new(sink, target, runtime_id, options, http_client), } } diff --git a/libdd-tracer-flare/src/lib.rs b/libdd-tracer-flare/src/lib.rs index 1f6c548c4e..be6607b898 100644 --- a/libdd-tracer-flare/src/lib.rs +++ b/libdd-tracer-flare/src/lib.rs @@ -190,7 +190,7 @@ impl TracerFlareManager { capabilities: vec![], }; - tracer_flare.listener = Some(SingleChangesFetcher::with_client( + tracer_flare.listener = Some(SingleChangesFetcher::new( ParsedFileStorage::default(), Target::new(service, env, app_version, vec![], vec![]), runtime_id,