Skip to content

Commit 44f705f

Browse files
authored
fix(wasm)!: finish the WASM port of remote-config (#2315)
Fix tokio in Cargo.toml and adds missing SleepCapability.
1 parent 94f123f commit 44f705f

9 files changed

Lines changed: 72 additions & 52 deletions

File tree

datadog-sidecar/src/shm_remote_config.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use datadog_ipc::one_way_shared_memory::{open_named_shm, OneWayShmReader, OneWay
1010
use datadog_ipc::platform::{FileBackedHandle, NamedShmHandle};
1111
use datadog_ipc::rate_limiter::ShmLimiter;
1212
use datadog_live_debugger::LiveDebuggingData;
13-
use libdd_capabilities_impl::NativeHttpClient;
13+
use libdd_capabilities_impl::{HttpClientCapability, NativeCapabilities};
1414
use libdd_common::{tag::Tag, MutexExt};
1515
use libdd_remote_config::config::dynamic::{parse_json, Configs};
1616
use libdd_remote_config::fetch::{
@@ -246,12 +246,12 @@ fn dynamic_instrumentation_is_enabled(apm_config: Option<bool>, info: &TargetInf
246246
}
247247
}
248248

249-
impl<N: NotifyTarget + 'static> MultiTargetHandlers<N, Self, NativeHttpClient>
249+
impl<N: NotifyTarget + 'static> MultiTargetHandlers<N, Self, NativeCapabilities>
250250
for ConfigFileStorage<N>
251251
{
252252
fn fetched(
253253
&self,
254-
fetcher: &Arc<MultiTargetFetcher<N, Self, NativeHttpClient>>,
254+
fetcher: &Arc<MultiTargetFetcher<N, Self, NativeCapabilities>>,
255255
runtime_id: &Arc<String>,
256256
target: &Arc<Target>,
257257
files: &[Arc<StoredShmFile>],
@@ -425,7 +425,7 @@ impl<N: NotifyTarget + 'static> Drop for ShmRemoteConfigsGuard<N> {
425425

426426
#[derive(Clone)]
427427
pub struct ShmRemoteConfigs<N: NotifyTarget + 'static>(
428-
Arc<MultiTargetFetcher<N, ConfigFileStorage<N>, NativeHttpClient>>,
428+
Arc<MultiTargetFetcher<N, ConfigFileStorage<N>, NativeCapabilities>>,
429429
);
430430

431431
// we collect services per env, so that we always query, for each runtime + env, all the services
@@ -454,7 +454,7 @@ impl<N: NotifyTarget + 'static> ShmRemoteConfigs<N> {
454454
let fetcher = MultiTargetFetcher::new(
455455
storage,
456456
invariants,
457-
NativeHttpClient::new_without_connection_pooling(),
457+
NativeCapabilities::new_without_connection_pooling(),
458458
);
459459
fetcher
460460
.remote_config_interval

libdd-remote-config/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ base64 = { version = "0.22.1", optional = true }
4848
sha2 = { version = "0.10", optional = true }
4949
uuid = { workspace = true, features = ["v4", "std"], optional = true }
5050
futures-util = { version = "0.3", optional = true }
51-
tokio = { workspace = true, optional = true }
51+
tokio = { workspace = true, optional = true, features = ["macros"] }
5252
tokio-util = { version = "0.7.10", optional = true }
5353
manual_future = { version = "0.1.1", optional = true }
5454
time = { version = "0.3", features = ["parsing", "serde", "formatting"], optional = true }
@@ -67,6 +67,7 @@ hyper-util = { workspace = true, features = ["http1", "client", "client-legacy",
6767

6868
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
6969
libdd-capabilities-impl = { path = "../libdd-capabilities-impl", version = "3.0.0", default-features = false }
70+
tokio = { workspace = true, optional = true, features = ["rt", "sync", "time"] }
7071

7172
[dev-dependencies]
7273
futures.workspace = true

libdd-remote-config/examples/remote_config_fetch.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use libdd_capabilities_impl::NativeHttpClient;
4+
use libdd_capabilities::HttpClientCapability;
5+
use libdd_capabilities_impl::NativeCapabilities;
56
use libdd_common::Endpoint;
67
use libdd_remote_config::fetch::{ConfigInvariants, ConfigOptions, SingleChangesFetcher};
78
use libdd_remote_config::file_change_tracker::{Change, FilePath};
@@ -51,7 +52,7 @@ async fn main() {
5152
products: vec![ApmTracing],
5253
capabilities: vec![],
5354
},
54-
NativeHttpClient::new_without_connection_pooling(),
55+
NativeCapabilities::new_without_connection_pooling(),
5556
);
5657

5758
loop {

libdd-remote-config/src/fetch/fetcher.rs

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use base64::Engine;
77
use hashbrown::HashMap;
88
use http::uri::PathAndQuery;
99
use http::StatusCode;
10-
use libdd_capabilities::HttpClientCapability;
10+
use libdd_capabilities::{HttpClientCapability, SleepCapability};
1111
use libdd_common::{Endpoint, MutexExt};
1212
use libdd_trace_protobuf::remoteconfig::{
1313
ClientGetConfigsRequest, ClientGetConfigsResponse, ClientState, ClientTracer, ConfigState,
@@ -104,7 +104,7 @@ impl ConfigProductCapabilities {
104104
}
105105
}
106106

107-
pub struct ConfigFetcherState<S, C: HttpClientCapability> {
107+
pub struct ConfigFetcherState<S, C: HttpClientCapability + SleepCapability> {
108108
target_files_by_path: Mutex<HashMap<Arc<RemoteConfigPath>, StoredTargetFile<S>>>,
109109
pub invariants: ConfigInvariants,
110110
endpoint: Endpoint,
@@ -153,7 +153,7 @@ impl<S> ConfigFetcherFilesLock<'_, S> {
153153
}
154154
}
155155

156-
impl<S, C: HttpClientCapability> ConfigFetcherState<S, C> {
156+
impl<S, C: HttpClientCapability + SleepCapability> ConfigFetcherState<S, C> {
157157
pub fn with_client(invariants: ConfigInvariants, http_client: C) -> Self {
158158
ConfigFetcherState {
159159
target_files_by_path: Default::default(),
@@ -203,7 +203,7 @@ impl<S, C: HttpClientCapability> ConfigFetcherState<S, C> {
203203
}
204204
}
205205

206-
pub struct ConfigFetcher<S: FileStorage, C: HttpClientCapability> {
206+
pub struct ConfigFetcher<S: FileStorage, C: HttpClientCapability + SleepCapability> {
207207
pub file_storage: S,
208208
state: Arc<ConfigFetcherState<S::StoredFile, C>>,
209209
}
@@ -238,7 +238,7 @@ impl ConfigClientState {
238238
}
239239
}
240240

241-
impl<S: FileStorage, C: HttpClientCapability> ConfigFetcher<S, C> {
241+
impl<S: FileStorage, C: HttpClientCapability + SleepCapability> ConfigFetcher<S, C> {
242242
pub fn new(file_storage: S, state: Arc<ConfigFetcherState<S::StoredFile, C>>) -> Self {
243243
ConfigFetcher {
244244
file_storage,
@@ -364,19 +364,31 @@ impl<S: FileStorage, C: HttpClientCapability> ConfigFetcher<S, C> {
364364
libdd_common::header::APPLICATION_JSON,
365365
)
366366
.body(bytes::Bytes::from(serde_json::to_string(&config_req)?))?;
367-
let response = tokio::time::timeout(
368-
Duration::from_millis(self.state.endpoint.timeout_ms),
369-
self.state.http_client.request(req),
370-
)
371-
.await
372-
.map_err(|e| anyhow::Error::msg(e).context(format!("Url: {:?}", self.state.endpoint)))?
373-
.map_err(|e| anyhow::Error::msg(e).context(format!("Url: {:?}", self.state.endpoint)))?;
367+
let sleeper = <C as SleepCapability>::new();
368+
let response = tokio::select! {
369+
biased;
370+
result = self.state.http_client.request(req) => result
371+
.map_err(|e| anyhow::Error::msg(e).context(format!("Url: {:?}", self.state.endpoint)))?,
372+
_ = sleeper.sleep(Duration::from_millis(self.state.endpoint.timeout_ms)) => {
373+
anyhow::bail!(
374+
"Remote config request timed out after {}ms. Url: {:?}",
375+
self.state.endpoint.timeout_ms,
376+
self.state.endpoint
377+
)
378+
}
379+
};
374380
let status = response.status();
375381
let body_bytes = response.into_body();
376382
if status != StatusCode::OK {
377383
// Not active
378384
if status == StatusCode::NOT_FOUND {
379385
trace!("Requested remote config and but remote config not active");
386+
if self.state.expire_unused_files {
387+
self.state.target_files_by_path.lock_or_panic().clear();
388+
}
389+
client_state.last_config_paths.clear();
390+
client_state.targets_version = 0;
391+
client_state.opaque_backend_state.clear();
380392
return Ok(Some(vec![]));
381393
}
382394

@@ -592,7 +604,7 @@ pub mod tests {
592604
use crate::fetch::test_server::RemoteConfigServer;
593605
use crate::RemoteConfigSource;
594606
use http::Response;
595-
use libdd_capabilities_impl::NativeHttpClient;
607+
use libdd_capabilities_impl::NativeCapabilities;
596608
use libdd_common::http_common;
597609
use std::mem::transmute;
598610
use std::sync::LazyLock;
@@ -708,7 +720,7 @@ pub mod tests {
708720
storage.clone(),
709721
Arc::new(ConfigFetcherState::with_client(
710722
server.dummy_options().invariants,
711-
NativeHttpClient::new_without_connection_pooling(),
723+
NativeCapabilities::new_without_connection_pooling(),
712724
)),
713725
);
714726
let mut opaque_state = ConfigClientState::default();
@@ -746,7 +758,7 @@ pub mod tests {
746758
storage.clone(),
747759
Arc::new(ConfigFetcherState::with_client(
748760
server.dummy_options().invariants,
749-
NativeHttpClient::new_without_connection_pooling(),
761+
NativeCapabilities::new_without_connection_pooling(),
750762
)),
751763
);
752764
let mut opaque_state = ConfigClientState::default();
@@ -863,7 +875,7 @@ pub mod tests {
863875
storage.clone(),
864876
Arc::new(ConfigFetcherState::with_client(
865877
invariants,
866-
NativeHttpClient::new_without_connection_pooling(),
878+
NativeCapabilities::new_without_connection_pooling(),
867879
)),
868880
);
869881
let mut opaque_state = ConfigClientState::default();
@@ -1050,7 +1062,7 @@ pub mod tests {
10501062
storage,
10511063
Arc::new(ConfigFetcherState::with_client(
10521064
server.dummy_options().invariants,
1053-
NativeHttpClient::new_without_connection_pooling(),
1065+
NativeCapabilities::new_without_connection_pooling(),
10541066
)),
10551067
);
10561068
let mut opaque_state = ConfigClientState::default();
@@ -1151,7 +1163,7 @@ pub mod tests {
11511163
storage,
11521164
Arc::new(ConfigFetcherState::with_client(
11531165
server.dummy_options().invariants,
1154-
NativeHttpClient::new_without_connection_pooling(),
1166+
NativeCapabilities::new_without_connection_pooling(),
11551167
)),
11561168
);
11571169
let mut opaque_state = ConfigClientState::default();

libdd-remote-config/src/fetch/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
mod fetcher;
5+
#[cfg(not(target_arch = "wasm32"))]
56
mod multitarget;
7+
#[cfg(not(target_arch = "wasm32"))]
68
mod shared;
79
mod single;
810
#[cfg(any(test, feature = "test"))]
@@ -11,6 +13,8 @@ pub mod test_server;
1113
#[allow(clippy::useless_attribute)] // different clippy versions are differently picky
1214
#[cfg_attr(test, allow(ambiguous_glob_reexports))] // ignore mod tests re-export
1315
pub use fetcher::*;
16+
#[cfg(not(target_arch = "wasm32"))]
1417
pub use multitarget::*;
18+
#[cfg(not(target_arch = "wasm32"))]
1519
pub use shared::*;
1620
pub use single::*;

libdd-remote-config/src/fetch/multitarget.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::fetch::{
88
use crate::{RemoteConfigCapabilities, RemoteConfigProduct, Target};
99
use futures_util::future::Shared;
1010
use futures_util::FutureExt;
11-
use libdd_capabilities::HttpClientCapability;
11+
use libdd_capabilities::{HttpClientCapability, SleepCapability};
1212
use libdd_common::MutexExt;
1313
use manual_future::ManualFuture;
1414
use serde::{Deserialize, Serialize};
@@ -37,7 +37,7 @@ use tracing::{debug, error, trace};
3737
pub struct MultiTargetFetcher<
3838
N: NotifyTarget,
3939
S: FileStorage + Clone + Sync + Send,
40-
C: HttpClientCapability + Send + Sync,
40+
C: HttpClientCapability + SleepCapability + Send + Sync,
4141
> where
4242
S::StoredFile: RefcountedFile + Sync + Send,
4343
S: MultiTargetHandlers<N, S, C>,
@@ -156,7 +156,7 @@ pub trait NotifyTarget: Sync + Send + Sized + Hash + Eq + Clone + Debug {
156156
pub trait MultiTargetHandlers<
157157
N: NotifyTarget,
158158
S: FileStorage + Clone + Sync + Send + MultiTargetHandlers<N, S, C>,
159-
C: HttpClientCapability + Send + Sync,
159+
C: HttpClientCapability + SleepCapability + Send + Sync,
160160
> where
161161
S::StoredFile: RefcountedFile + Sync + Send,
162162
{
@@ -186,7 +186,7 @@ struct RuntimeInfo<N: NotifyTarget> {
186186
impl<
187187
N: NotifyTarget + 'static,
188188
S: FileStorage + Clone + Sync + Send + 'static,
189-
C: HttpClientCapability + Send + Sync + 'static,
189+
C: HttpClientCapability + SleepCapability + Send + Sync + 'static,
190190
> MultiTargetFetcher<N, S, C>
191191
where
192192
S::StoredFile: RefcountedFile + Sync + Send,
@@ -785,7 +785,7 @@ mod tests {
785785
use crate::fetch::shared::tests::*;
786786
use crate::fetch::test_server::RemoteConfigServer;
787787
use crate::{RemoteConfigPath, Target};
788-
use libdd_capabilities_impl::NativeHttpClient;
788+
use libdd_capabilities_impl::NativeCapabilities;
789789
use manual_future::ManualFutureCompleter;
790790
use std::hash::Hasher;
791791
use std::sync::atomic::AtomicU8;
@@ -822,10 +822,10 @@ mod tests {
822822
}
823823
}
824824

825-
impl MultiTargetHandlers<Notifier, MultiFileStorage, NativeHttpClient> for MultiFileStorage {
825+
impl MultiTargetHandlers<Notifier, MultiFileStorage, NativeCapabilities> for MultiFileStorage {
826826
fn fetched(
827827
&self,
828-
_fetcher: &Arc<MultiTargetFetcher<Notifier, MultiFileStorage, NativeHttpClient>>,
828+
_fetcher: &Arc<MultiTargetFetcher<Notifier, MultiFileStorage, NativeCapabilities>>,
829829
_runtime_id: &Arc<String>,
830830
target: &Arc<Target>,
831831
files: &[Arc<RcPathStore>],
@@ -967,10 +967,10 @@ mod tests {
967967

968968
let fut = storage.await_fetches(1);
969969

970-
let fetcher = MultiTargetFetcher::<Notifier, MultiFileStorage, NativeHttpClient>::new(
970+
let fetcher = MultiTargetFetcher::<Notifier, MultiFileStorage, NativeCapabilities>::new(
971971
storage.clone(),
972972
server.dummy_options().invariants,
973-
NativeHttpClient::new_without_connection_pooling(),
973+
NativeCapabilities::new_without_connection_pooling(),
974974
);
975975
fetcher.remote_config_interval.store(1000, Ordering::SeqCst);
976976

libdd-remote-config/src/fetch/shared.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::fetch::{
66
ConfigFetcherStateStats, ConfigInvariants, ConfigProductCapabilities, FileStorage,
77
};
88
use crate::{RemoteConfigPath, Target};
9-
use libdd_capabilities::HttpClientCapability;
9+
use libdd_capabilities::{HttpClientCapability, SleepCapability};
1010
use libdd_common::MutexExt;
1111
use serde::{Deserialize, Serialize};
1212
use std::collections::HashMap;
@@ -127,7 +127,7 @@ impl RunnersGeneration {
127127
}
128128
}
129129

130-
pub struct RefcountingStorage<S: FileStorage + Clone, C: HttpClientCapability>
130+
pub struct RefcountingStorage<S: FileStorage + Clone, C: HttpClientCapability + SleepCapability>
131131
where
132132
S::StoredFile: RefcountedFile,
133133
{
@@ -161,7 +161,8 @@ impl Add for RefcountingStorageStats {
161161
}
162162
}
163163

164-
impl<S: FileStorage + Clone, C: HttpClientCapability> Clone for RefcountingStorage<S, C>
164+
impl<S: FileStorage + Clone, C: HttpClientCapability + SleepCapability> Clone
165+
for RefcountingStorage<S, C>
165166
where
166167
S::StoredFile: RefcountedFile,
167168
{
@@ -175,7 +176,7 @@ where
175176
}
176177
}
177178

178-
impl<S: FileStorage + Clone, C: HttpClientCapability> RefcountingStorage<S, C>
179+
impl<S: FileStorage + Clone, C: HttpClientCapability + SleepCapability> RefcountingStorage<S, C>
179180
where
180181
S::StoredFile: RefcountedFile,
181182
{
@@ -223,7 +224,8 @@ where
223224
}
224225
}
225226

226-
impl<S: FileStorage + Clone, C: HttpClientCapability> FileStorage for RefcountingStorage<S, C>
227+
impl<S: FileStorage + Clone, C: HttpClientCapability + SleepCapability> FileStorage
228+
for RefcountingStorage<S, C>
227229
where
228230
S::StoredFile: RefcountedFile,
229231
{
@@ -268,7 +270,7 @@ impl SharedFetcher {
268270
/// On successful fetches on_fetch() is called with the new configuration.
269271
/// Should not be called more than once.
270272
#[allow(clippy::type_complexity)]
271-
pub async fn run<S: FileStorage + Clone, C: HttpClientCapability>(
273+
pub async fn run<S: FileStorage + Clone, C: HttpClientCapability + SleepCapability>(
272274
&self,
273275
storage: RefcountingStorage<S, C>,
274276
on_fetch: Box<dyn Send + Fn(&Vec<Arc<S::StoredFile>>)>,
@@ -378,7 +380,7 @@ pub mod tests {
378380
use crate::fetch::test_server::RemoteConfigServer;
379381
use crate::Target;
380382
use futures::future::join_all;
381-
use libdd_capabilities_impl::NativeHttpClient;
383+
use libdd_capabilities_impl::NativeCapabilities;
382384
use std::sync::{Arc, LazyLock};
383385

384386
pub(crate) static OTHER_TARGET: LazyLock<Arc<Target>> = LazyLock::new(|| {
@@ -439,7 +441,7 @@ pub mod tests {
439441
storage.clone(),
440442
ConfigFetcherState::with_client(
441443
server.dummy_options().invariants,
442-
NativeHttpClient::new_without_connection_pooling(),
444+
NativeCapabilities::new_without_connection_pooling(),
443445
),
444446
);
445447

@@ -504,7 +506,7 @@ pub mod tests {
504506
storage.clone(),
505507
ConfigFetcherState::with_client(
506508
server.dummy_options().invariants,
507-
NativeHttpClient::new_without_connection_pooling(),
509+
NativeCapabilities::new_without_connection_pooling(),
508510
),
509511
);
510512

0 commit comments

Comments
 (0)