From 7358ffdc9856e574d277279e27d2b7f09891d8fc Mon Sep 17 00:00:00 2001 From: Jules Wiriath Date: Tue, 18 Aug 2026 10:30:13 +0200 Subject: [PATCH 1/2] chore: bump libdatadog --- Cargo.lock | 126 +++++++++++++++++++------------- crates/capabilities/Cargo.toml | 2 +- crates/capabilities/src/http.rs | 4 + crates/capabilities/src/lib.rs | 9 +++ crates/pipeline/Cargo.toml | 14 ++-- crates/sketches/Cargo.toml | 2 +- test/pipeline.js | 4 +- 7 files changed, 100 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b69d0b47..658e86be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -897,7 +897,7 @@ dependencies = [ "futures-core", "http", "js-sys", - "libdd-capabilities 2.1.0", + "libdd-capabilities 3.0.0", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", @@ -916,11 +916,13 @@ dependencies = [ [[package]] name = "libdd-capabilities" -version = "2.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "3.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", "bytes", + "futures-channel", + "futures-util", "http", "thiserror", ] @@ -940,15 +942,15 @@ dependencies = [ [[package]] name = "libdd-capabilities-impl" -version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "4.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", "bytes", "http", "http-body-util", - "libdd-capabilities 2.1.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0", + "libdd-common 5.1.1", "tokio", ] @@ -989,8 +991,8 @@ dependencies = [ [[package]] name = "libdd-common" -version = "5.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "5.1.1" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", "bytes", @@ -1053,7 +1055,7 @@ dependencies = [ [[package]] name = "libdd-data-pipeline" version = "7.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", "arc-swap", @@ -1064,16 +1066,16 @@ dependencies = [ "getrandom 0.2.17", "http", "http-body-util", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.1.1", "libdd-ddsketch 1.1.0", "libdd-dogstatsd-client", "libdd-shared-runtime 2.0.0", "libdd-telemetry 6.0.0", "libdd-tinybytes", "libdd-trace-normalization", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-trace-protobuf 4.0.1", "libdd-trace-stats", "libdd-trace-utils", "rmp-serde", @@ -1098,7 +1100,7 @@ dependencies = [ [[package]] name = "libdd-ddsketch" version = "1.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "prost", ] @@ -1106,13 +1108,16 @@ dependencies = [ [[package]] name = "libdd-dogstatsd-client" version = "4.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", + "async-trait", "cadence", "http", - "libdd-common 5.1.0", + "libdd-common 5.1.1", + "libdd-shared-runtime 2.0.0", "serde", + "tokio", "tracing", ] @@ -1123,7 +1128,7 @@ source = "git+https://github.com/DataDog/libdatadog.git?rev=0c6e2a5df2a163d34c4f dependencies = [ "anyhow", "libc", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4)", + "libdd-trace-protobuf 4.0.0", "memfd", "prost", "rand", @@ -1164,14 +1169,14 @@ dependencies = [ [[package]] name = "libdd-shared-runtime" version = "2.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "async-trait", "futures", "futures-util", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.1.1", "tokio", "tokio-util", "tracing", @@ -1208,7 +1213,7 @@ dependencies = [ [[package]] name = "libdd-telemetry" version = "6.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", "async-trait", @@ -1219,12 +1224,14 @@ dependencies = [ "hashbrown 0.15.5", "http", "libc", - "libdd-capabilities 2.1.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0", + "libdd-common 5.1.1", "libdd-ddsketch 1.1.0", "libdd-shared-runtime 2.0.0", "serde", "serde_json", + "strum", + "strum_macros", "sys-info", "tokio", "tokio-util", @@ -1236,30 +1243,30 @@ dependencies = [ [[package]] name = "libdd-tinybytes" -version = "1.1.1" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "1.1.2" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "serde", ] [[package]] name = "libdd-trace-normalization" -version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "3.0.1" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-trace-protobuf 4.0.1", ] [[package]] name = "libdd-trace-obfuscation" version = "5.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", "fluent-uri", - "libdd-common 5.1.0", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-common 5.1.1", + "libdd-trace-protobuf 4.0.1", "libdd-trace-utils", "log", "percent-encoding", @@ -1279,8 +1286,8 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" -version = "4.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "4.0.1" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "prost", "serde", @@ -1290,7 +1297,7 @@ dependencies = [ [[package]] name = "libdd-trace-stats" version = "6.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", "arc-swap", @@ -1298,15 +1305,15 @@ dependencies = [ "futures", "hashbrown 0.15.5", "http", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.1.1", "libdd-ddsketch 1.1.0", "libdd-dogstatsd-client", "libdd-shared-runtime 2.0.0", "libdd-telemetry 6.0.0", "libdd-trace-obfuscation", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-trace-protobuf 4.0.1", "libdd-trace-utils", "rmp-serde", "serde", @@ -1318,8 +1325,8 @@ dependencies = [ [[package]] name = "libdd-trace-utils" -version = "9.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "10.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=1b9b7a26f54f116a0f6525abdcd2013b341921a7#1b9b7a26f54f116a0f6525abdcd2013b341921a7" dependencies = [ "anyhow", "base64", @@ -1332,12 +1339,12 @@ dependencies = [ "http-body-util", "indexmap", "itoa", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.1.1", "libdd-tinybytes", "libdd-trace-normalization", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-trace-protobuf 4.0.1", "prost", "rand", "rmp", @@ -1824,11 +1831,11 @@ dependencies = [ "http", "js-sys", "libdatadog-nodejs-capabilities", - "libdd-capabilities 2.1.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0", + "libdd-common 5.1.1", "libdd-data-pipeline", "libdd-shared-runtime 2.0.0", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-trace-protobuf 4.0.1", "libdd-trace-stats", "libdd-trace-utils", "rmp-serde", @@ -1890,7 +1897,7 @@ version = "0.1.0" dependencies = [ "anyhow", "libdd-library-config", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4)", + "libdd-trace-protobuf 4.0.0", "napi", "napi-derive", ] @@ -2406,6 +2413,25 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "subtle" version = "2.6.1" diff --git a/crates/capabilities/Cargo.toml b/crates/capabilities/Cargo.toml index edb40adc..f4b46e6b 100644 --- a/crates/capabilities/Cargo.toml +++ b/crates/capabilities/Cargo.toml @@ -15,7 +15,7 @@ http = "1" bytes = "1.4" futures-core = "0.3" anyhow = "1" -libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f" } +libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "1b9b7a26f54f116a0f6525abdcd2013b341921a7" } [dev-dependencies] wasm-bindgen-test = "0.3" diff --git a/crates/capabilities/src/http.rs b/crates/capabilities/src/http.rs index 4248cb30..2ee1bf78 100644 --- a/crates/capabilities/src/http.rs +++ b/crates/capabilities/src/http.rs @@ -59,6 +59,10 @@ impl HttpClientCapability for WasmHttpClient { Self } + fn new_without_connection_pooling() -> Self { + Self + } + #[allow(clippy::manual_async_fn)] fn request( &self, diff --git a/crates/capabilities/src/lib.rs b/crates/capabilities/src/lib.rs index e76a3812..399e9539 100644 --- a/crates/capabilities/src/lib.rs +++ b/crates/capabilities/src/lib.rs @@ -65,6 +65,15 @@ impl HttpClientCapability for WasmCapabilities { Self::new() } + fn new_without_connection_pooling() -> Self { + Self { + http: WasmHttpClient::new_without_connection_pooling(), + sleep: WasmSleepCapability, + file: WasmFileCapability, + env: WasmEnvCapability, + } + } + fn request( &self, req: ::http::Request<::bytes::Bytes>, diff --git a/crates/pipeline/Cargo.toml b/crates/pipeline/Cargo.toml index 8056816e..0d914374 100644 --- a/crates/pipeline/Cargo.toml +++ b/crates/pipeline/Cargo.toml @@ -14,13 +14,13 @@ js-sys = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1" libdatadog-nodejs-capabilities = { path = "../capabilities" } -libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f" } -libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } -libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false, features = ["telemetry"] } -libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false, features = ["change-buffer"] } -libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } -libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } -libdd-shared-runtime = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } +libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "1b9b7a26f54f116a0f6525abdcd2013b341921a7" } +libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "1b9b7a26f54f116a0f6525abdcd2013b341921a7", default-features = false } +libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "1b9b7a26f54f116a0f6525abdcd2013b341921a7", default-features = false, features = ["telemetry"] } +libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog.git", rev = "1b9b7a26f54f116a0f6525abdcd2013b341921a7", default-features = false, features = ["change-buffer"] } +libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog.git", rev = "1b9b7a26f54f116a0f6525abdcd2013b341921a7", default-features = false } +libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "1b9b7a26f54f116a0f6525abdcd2013b341921a7", default-features = false } +libdd-shared-runtime = { git = "https://github.com/DataDog/libdatadog.git", rev = "1b9b7a26f54f116a0f6525abdcd2013b341921a7", default-features = false } rmp-serde = "1" bytes = "1" http = "1" diff --git a/crates/sketches/Cargo.toml b/crates/sketches/Cargo.toml index 6747f461..43d14deb 100644 --- a/crates/sketches/Cargo.toml +++ b/crates/sketches/Cargo.toml @@ -8,7 +8,7 @@ description = "Wasm bindings for Datadog's DDSketch" crate-type = ["cdylib", "rlib"] [dependencies] -libdd-ddsketch = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f" } +libdd-ddsketch = { git = "https://github.com/DataDog/libdatadog.git", rev = "1b9b7a26f54f116a0f6525abdcd2013b341921a7" } wasm-bindgen = "0.2" [package.metadata.wasm-pack.profile.release] diff --git a/test/pipeline.js b/test/pipeline.js index 59511fef..bd4c8977 100644 --- a/test/pipeline.js +++ b/test/pipeline.js @@ -1154,9 +1154,9 @@ describe('pipeline', { skip }, () => { try { for (let i = 0; i < 15_000; i++) { const span = ns.createSpan() - span.name = 'stats-span' + span.name = `stats-span-${i}` span.service = 'stats-svc' - span.resource = `/stats/${i}` + span.resource = '/stats' span.type = 'web' span.setTag('span.kind', 'server') span.duration = 5_000_000n From 8d8f65e567f96be52086ae68c1f0d1ab8aa88711 Mon Sep 17 00:00:00 2001 From: Jules Wiriath Date: Tue, 18 Aug 2026 11:00:02 +0200 Subject: [PATCH 2/2] fix: propagate no_pooling --- crates/capabilities/src/http.rs | 17 ++++-- crates/capabilities/src/http_transport.js | 6 ++- test/http_transport.js | 64 +++++++++++++++++++++++ 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/crates/capabilities/src/http.rs b/crates/capabilities/src/http.rs index 2ee1bf78..779cd889 100644 --- a/crates/capabilities/src/http.rs +++ b/crates/capabilities/src/http.rs @@ -37,6 +37,7 @@ extern "C" { body_ptr: *const u8, body_len: u32, wasm_memory: &JsValue, + no_pooling: bool, ) -> js_sys::Promise; #[wasm_bindgen(js_name = "setStorage")] @@ -52,15 +53,23 @@ extern "C" { /// [`crate::WasmCapabilities`] alongside the sleep and log-output capabilities /// that `TraceExporter` requires. #[derive(Debug, Clone)] -pub struct WasmHttpClient; +pub struct WasmHttpClient { + no_pooling: bool, +} impl HttpClientCapability for WasmHttpClient { fn new_client() -> Self { - Self + Self { no_pooling: false } } + /// Requested by libdatadog's telemetry worker, whose sends are paced further + /// apart than the agent's HTTP keep-alive: a pooled socket is typically + /// half-closed by the next send, so reuse fails with EOF/ECONNRESET. + /// libdatadog used to force a fresh socket with a `Connection: close` header + /// and dropped it in #2286, because the agent's telemetry proxy mishandles + /// that hop-by-hop header. fn new_without_connection_pooling() -> Self { - Self + Self { no_pooling: true } } #[allow(clippy::manual_async_fn)] @@ -68,6 +77,7 @@ impl HttpClientCapability for WasmHttpClient { &self, req: http::Request, ) -> impl Future, HttpError>> + MaybeSend { + let no_pooling = self.no_pooling; async move { let scheme = req.uri().scheme_str().unwrap_or("http"); @@ -110,6 +120,7 @@ impl HttpClientCapability for WasmHttpClient { body.as_ptr(), body.len() as u32, WASM_MEMORY.as_ref(), + no_pooling, )) .await .map_err(|e| HttpError::Network(anyhow::anyhow!("{:?}", e)))?; diff --git a/crates/capabilities/src/http_transport.js b/crates/capabilities/src/http_transport.js index 962b6ba4..9ad45f18 100644 --- a/crates/capabilities/src/http_transport.js +++ b/crates/capabilities/src/http_transport.js @@ -171,7 +171,7 @@ module.exports._resetEntityHeadersCache = () => { cachedEntityHeaders = undefined } -module.exports.httpRequest = function (host, port, isHttps, socketPath, head_ptr, head_len, body_ptr, body_len, wasm_memory) { +module.exports.httpRequest = function (host, port, isHttps, socketPath, head_ptr, head_len, body_ptr, body_len, wasm_memory, noPooling) { // A non-empty socketPath routes over a Unix domain socket (or Windows named // pipe) instead of TCP. Sockets are always plaintext HTTP/1.1, so https is // ignored in that mode. @@ -204,6 +204,10 @@ module.exports.httpRequest = function (host, port, isHttps, socketPath, head_ptr const requestOptions = useSocket ? { socketPath, method, path, headers } : { host, port, method, path, headers } + // `agent: false` builds a throwaway agent for this request instead of + // taking a possibly stale keep-alive socket from `globalAgent`, whose + // keep-alive is on by default since Node 19. + if (noPooling) requestOptions.agent = false const req = transport.request(requestOptions, (res) => { const chunks = [] res.on('data', chunk => chunks.push(chunk)) diff --git a/test/http_transport.js b/test/http_transport.js index 5a97a58a..afff3d46 100644 --- a/test/http_transport.js +++ b/test/http_transport.js @@ -409,3 +409,67 @@ describe('http_transport entity headers', () => { }) }) }) + +// The `noPooling` argument carries libdatadog's `new_without_connection_pooling()` +// down to the socket. +describe('http_transport connection pooling', () => { + let server + let port + let connections = 0 + + before(async () => { + server = http.createServer((req, res) => { + req.on('data', () => {}) + req.on('end', () => res.end(RESPONSE_BODY)) + }) + server.on('connection', () => { + connections++ + }) + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + port = server.address().port + }) + + after(() => new Promise((resolve) => { + // A keep-alive socket left in the agent pool would hold `server.close()` + // open until the server's keep-alive timeout. + server.closeAllConnections?.() + server.close(resolve) + })) + + // No `Connection: close` in the head — that header, not the agent, would then + // decide the socket's fate and mask what this is testing. + function doRequest (noPooling) { + const head = Buffer.from( + `POST /telemetry/proxy/api/v2/apmtelemetry HTTP/1.1\r\nHost: 127.0.0.1:${port}\r\n` + + 'Content-Length: 0\r\n\r\n', + 'utf8', + ) + return transport.httpRequest( + '127.0.0.1', port, false, '', 0, head.length, 0, 0, fakeWasmMemory(head), noPooling, + ) + } + + it('reuses one connection across requests by default', async function () { + // `globalAgent` only pools with keep-alive on, the default from Node 19. + if (!http.globalAgent.keepAlive) return this.skip?.() + connections = 0 + + const [first] = await doRequest() + const [second] = await doRequest() + + assert.strictEqual(first, 200) + assert.strictEqual(second, 200) + assert.strictEqual(connections, 1, 'second request reused the pooled socket') + }) + + it('opens a fresh connection per request when pooling is disabled', async () => { + connections = 0 + + const [first] = await doRequest(true) + const [second] = await doRequest(true) + + assert.strictEqual(first, 200) + assert.strictEqual(second, 200) + assert.strictEqual(connections, 2, 'each request opened its own socket') + }) +})