diff --git a/packages/common/src/metrics.ts b/packages/common/src/metrics.ts index c7fe003ca..92a7788dd 100644 --- a/packages/common/src/metrics.ts +++ b/packages/common/src/metrics.ts @@ -69,8 +69,43 @@ export interface Metric { * The description of the metric, if any. */ description?: string; + + /** + * The kind of the metric (e.g. `counter`, `histogram`, `gauge`). + */ + kind: MetricKind; + + /** + * The type of value recorded by the metric. Either `int` or `float`. + */ + valueType: NumericMetricValueType; } +/** + * Tags to be attached to some metrics. + * + * @experimental The Metric API is an experimental feature and may be subject to change. + */ +export type MetricTags = Record; + +/** + * Type of numerical values recorded by a metric. + * + * Note that this represents the _configuration_ of the metric; however, since JavaScript doesn't + * have different runtime representation for integers and floats, the actual value type is always + * a JS 'number'. + * + * @experimental The Metric API is an experimental feature and may be subject to change. + */ +export type NumericMetricValueType = 'int' | 'float'; + +/** + * The kind of a metric. + * + * @experimental The Metric API is an experimental feature and may be subject to change. + */ +export type MetricKind = 'counter' | 'histogram' | 'gauge'; + /** * A metric that supports adding values as a counter. * @@ -91,6 +126,9 @@ export interface MetricCounter extends Metric { * @param tags Tags to append to existing tags. */ withTags(tags: MetricTags): MetricCounter; + + kind: 'counter'; + valueType: 'int'; } /** @@ -99,11 +137,6 @@ export interface MetricCounter extends Metric { * @experimental The Metric API is an experimental feature and may be subject to change. */ export interface MetricHistogram extends Metric { - /** - * The type of value to record. Either `int` or `float`. - */ - valueType: NumericMetricValueType; - /** * Record the given value on the histogram. * @@ -120,6 +153,8 @@ export interface MetricHistogram extends Metric { * @param tags Tags to append to existing tags. */ withTags(tags: MetricTags): MetricHistogram; + + kind: 'histogram'; } /** @@ -128,11 +163,6 @@ export interface MetricHistogram extends Metric { * @experimental The Metric API is an experimental feature and may be subject to change. */ export interface MetricGauge extends Metric { - /** - * The type of value to set. Either `int` or `float`. - */ - valueType: NumericMetricValueType; - /** * Set the given value on the gauge. * @@ -147,16 +177,9 @@ export interface MetricGauge extends Metric { * @param tags Tags to append to existing tags. */ withTags(tags: MetricTags): MetricGauge; -} -/** - * Tags to be attached to some metrics. - * - * @experimental The Metric API is an experimental feature and may be subject to change. - */ -export type MetricTags = Record; - -export type NumericMetricValueType = 'int' | 'float'; + kind: 'gauge'; +} //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -170,6 +193,9 @@ class NoopMetricMeter implements MetricMeter { unit, description, + kind: 'counter', + valueType: 'int', + add(_value, _extraTags) {}, withTags(_extraTags) { @@ -186,10 +212,12 @@ class NoopMetricMeter implements MetricMeter { ): MetricHistogram { return { name, - valueType, unit, description, + kind: 'histogram', + valueType, + record(_value, _extraTags) {}, withTags(_extraTags) { @@ -198,13 +226,20 @@ class NoopMetricMeter implements MetricMeter { }; } - createGauge(name: string, valueType?: NumericMetricValueType, unit?: string, description?: string): MetricGauge { + createGauge( + name: string, + valueType: NumericMetricValueType = 'int', + unit?: string, + description?: string + ): MetricGauge { return { name, - valueType: valueType ?? 'int', unit, description, + kind: 'gauge', + valueType, + set(_value, _extraTags) {}, withTags(_extraTags) { @@ -300,6 +335,9 @@ export class MetricMeterWithComposedTags implements MetricMeter { * @experimental The Metric API is an experimental feature and may be subject to change. */ class MetricCounterWithComposedTags implements MetricCounter { + public readonly kind = 'counter'; + public readonly valueType = 'int'; + constructor( private parentCounter: MetricCounter, private contributors: MetricTagsOrFunc[] @@ -332,6 +370,8 @@ class MetricCounterWithComposedTags implements MetricCounter { * @experimental The Metric API is an experimental feature and may be subject to change. */ class MetricHistogramWithComposedTags implements MetricHistogram { + public readonly kind = 'histogram'; + constructor( private parentHistogram: MetricHistogram, private contributors: MetricTagsOrFunc[] @@ -369,6 +409,8 @@ class MetricHistogramWithComposedTags implements MetricHistogram { * @hidden */ class MetricGaugeWithComposedTags implements MetricGauge { + public readonly kind = 'gauge'; + constructor( private parentGauge: MetricGauge, private contributors: MetricTagsOrFunc[] diff --git a/packages/core-bridge/Cargo.lock b/packages/core-bridge/Cargo.lock index 8a5f025cf..573cd2142 100644 --- a/packages/core-bridge/Cargo.lock +++ b/packages/core-bridge/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.1" @@ -19,9 +10,9 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -34,15 +25,15 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arbitrary" @@ -78,9 +69,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" -version = "0.8.4" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" +checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" dependencies = [ "axum-core", "bytes", @@ -94,8 +85,7 @@ dependencies = [ "mime", "percent-encoding", "pin-project-lite", - "rustversion", - "serde", + "serde_core", "sync_wrapper", "tower", "tower-layer", @@ -104,9 +94,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.2" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ "bytes", "futures-core", @@ -115,7 +105,6 @@ dependencies = [ "http-body-util", "mime", "pin-project-lite", - "rustversion", "sync_wrapper", "tower-layer", "tower-service", @@ -127,26 +116,11 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "instant", "rand 0.8.5", ] -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base64" version = "0.22.1" @@ -155,15 +129,15 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bon" -version = "3.8.1" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebeb9aaf9329dff6ceb65c689ca3db33dbf15f324909c60e4e5eef5701ce31b1" +checksum = "234655ec178edd82b891e262ea7cf71f6584bcd09eff94db786be23f1821825c" dependencies = [ "bon-macros", "rustversion", @@ -171,9 +145,9 @@ dependencies = [ [[package]] name = "bon-macros" -version = "3.8.1" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e9d642a7e3a318e37c2c9427b5a6a48aa1ad55dcd986f3034ab2239045a645" +checksum = "89ec27229c38ed0eb3c0feee3d2c1d6a4379ae44f418a29a658890e062d8f365" dependencies = [ "darling", "ident_case", @@ -188,7 +162,7 @@ dependencies = [ name = "bridge-macros" version = "0.1.0" dependencies = [ - "convert_case", + "convert_case 0.6.0", "proc-macro2", "quote", "syn", @@ -196,9 +170,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytes" @@ -208,19 +182,20 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "bzip2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bea8dcd42434048e4f7a304411d9273a411f647446c1234a65ce0554923f4cff" +checksum = "f3a53fac24f34a81bc9954b5d6cfce0c21e18ec6959f44f56e8e90e4bb7c346c" dependencies = [ "libbz2-rs-sys", ] [[package]] name = "cc" -version = "1.2.33" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee0f8803222ba5a7e2777dd72ca451868909b1ac410621b676adf07280e9b5f" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -228,9 +203,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -240,9 +215,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ "num-traits", "serde", @@ -257,6 +232,15 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -308,9 +292,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "darling" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ "darling_core", "darling_macro", @@ -318,11 +302,10 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "fnv", "ident_case", "proc-macro2", "quote", @@ -332,9 +315,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", @@ -368,21 +351,23 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ + "convert_case 0.10.0", "proc-macro2", "quote", + "rustc_version", "syn", "unicode-xid", ] @@ -418,18 +403,18 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "enum-iterator" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635" +checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016" dependencies = [ "enum-iterator-derive", ] [[package]] name = "enum-iterator-derive" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" dependencies = [ "proc-macro2", "quote", @@ -456,22 +441,23 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "erased-serde" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" dependencies = [ "serde", + "serde_core", "typeid", ] [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -482,16 +468,21 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "filetime" -version = "0.2.25" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.59.0", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "fixedbitset" version = "0.5.7" @@ -500,13 +491,13 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", - "libz-rs-sys", "miniz_oxide", + "zlib-rs", ] [[package]] @@ -529,9 +520,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -650,60 +641,54 @@ dependencies = [ [[package]] name = "gethostname" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ "rustix", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "governor" -version = "0.10.1" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444405bbb1a762387aa22dd569429533b54a1d8759d35d3b64cb39b0293eaa19" +checksum = "9efcab3c1958580ff1f25a2a41be1668f7603d849bb63af523b208a3cc1223b8" dependencies = [ "cfg-if", "dashmap", "futures-sink", "futures-timer", "futures-util", - "getrandom 0.3.3", - "hashbrown 0.15.5", + "getrandom 0.3.4", + "hashbrown 0.16.1", "nonzero_ext", "parking_lot", "portable-atomic", @@ -716,9 +701,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" dependencies = [ "atomic-waker", "bytes", @@ -745,8 +730,6 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "allocator-api2", - "equivalent", "foldhash 0.1.5", ] @@ -769,12 +752,11 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -815,9 +797,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ "atomic-waker", "bytes", @@ -868,14 +850,13 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64", "bytes", "futures-channel", - "futures-core", "futures-util", "http", "http-body", @@ -884,7 +865,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.0", + "socket2", "tokio", "tower-service", "tracing", @@ -892,9 +873,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -905,9 +886,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -918,11 +899,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -933,42 +913,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -984,9 +960,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -1005,12 +981,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.1", ] [[package]] @@ -1024,24 +1000,13 @@ dependencies = [ [[package]] name = "inventory" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83" +checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" dependencies = [ "rustversion", ] -[[package]] -name = "io-uring" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -1050,9 +1015,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" dependencies = [ "memchr", "serde", @@ -1069,25 +1034,25 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -1107,54 +1072,45 @@ checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-link 0.2.1", ] [[package]] name = "libredox" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ "bitflags", "libc", - "redox_syscall", -] - -[[package]] -name = "libz-rs-sys" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "840db8cf39d9ec4dd794376f38acc40d0fc65eec2a8f484f7fd375b84602becd" -dependencies = [ - "zlib-rs", + "redox_syscall 0.7.0", ] [[package]] name = "linkme" -version = "0.3.33" +version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b1703c00b2a6a70738920544aa51652532cacddfec2e162d2e29eae01e665c" +checksum = "5e3283ed2d0e50c06dd8602e0ab319bb048b6325d0bba739db64ed8205179898" dependencies = [ "linkme-impl", ] [[package]] name = "linkme-impl" -version = "0.3.33" +version = "0.3.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04d55ca5d5a14363da83bf3c33874b8feaa34653e760d5216d7ef9829c88001a" +checksum = "e5cec0ec4228b4853bb129c84dbf093a27e6c7a20526da046defc334a1b017f7" dependencies = [ "proc-macro2", "quote", @@ -1163,31 +1119,30 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru" @@ -1221,9 +1176,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "mime" @@ -1238,17 +1193,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "1.0.4" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -1319,20 +1275,20 @@ checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" [[package]] name = "ntapi" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081" dependencies = [ "winapi", ] [[package]] name = "nu-ansi-term" -version = "0.50.1" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1346,32 +1302,23 @@ dependencies = [ [[package]] name = "objc2-core-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags", ] [[package]] name = "objc2-io-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" +checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15" dependencies = [ "libc", "objc2-core-foundation", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -1380,9 +1327,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openssl-probe" -version = "0.1.6" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "opentelemetry" @@ -1394,7 +1341,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.14", + "thiserror 2.0.18", "tracing", ] @@ -1424,7 +1371,7 @@ dependencies = [ "opentelemetry_sdk", "prost", "reqwest", - "thiserror 2.0.14", + "thiserror 2.0.18", "tokio", "tonic", "tracing", @@ -1455,26 +1402,26 @@ dependencies = [ "opentelemetry", "percent-encoding", "rand 0.9.2", - "thiserror 2.0.14", + "thiserror 2.0.18", "tokio", "tokio-stream", ] [[package]] name = "os_pipe" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224" +checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1482,30 +1429,31 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "petgraph" -version = "0.7.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset", + "hashbrown 0.15.5", "indexmap", ] @@ -1558,24 +1506,24 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -1617,9 +1565,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.36" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn", @@ -1627,9 +1575,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.97" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -1646,14 +1594,14 @@ dependencies = [ "memchr", "parking_lot", "protobuf", - "thiserror 2.0.14", + "thiserror 2.0.18", ] [[package]] name = "prost" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" dependencies = [ "bytes", "prost-derive", @@ -1661,15 +1609,14 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" +checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" dependencies = [ "heck", "itertools", "log", "multimap", - "once_cell", "petgraph", "prettyplease", "prost", @@ -1683,9 +1630,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", "itertools", @@ -1696,18 +1643,18 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.14.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" dependencies = [ "prost", ] [[package]] name = "prost-wkt" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655944d0ce015e71b3ec21279437e6a09e58433e50c7b0677901f3d5235e74f5" +checksum = "cd3de5e9c9e84fcb5efa204b8e283d23e615a8bc8c777bf1d6622bb01dc61445" dependencies = [ "chrono", "inventory", @@ -1720,9 +1667,9 @@ dependencies = [ [[package]] name = "prost-wkt-build" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f869f1443fee474b785e935d92e1007f57443e485f51668ed41943fc01a321a2" +checksum = "fe500dc80e757a75e1e8fb7290e448d62dfba3105ece1d058579cb00b58151cd" dependencies = [ "heck", "prost", @@ -1733,9 +1680,9 @@ dependencies = [ [[package]] name = "prost-wkt-types" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeeffd6b9becd4600dd461399f3f71aeda2ff0848802a9ed526cf12e8f42902a" +checksum = "13807eaa7e15833d06e899008371926201cdcd11d74b6d490f49130cdb3f415e" dependencies = [ "chrono", "prost", @@ -1782,9 +1729,9 @@ dependencies = [ [[package]] name = "pulldown-cmark-to-cmark" -version = "21.0.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5b6a0769a491a08b31ea5c62494a8f144ee0987d86d670a8af4df1e1b7cde75" +checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90" dependencies = [ "pulldown-cmark", ] @@ -1799,16 +1746,16 @@ dependencies = [ "libc", "once_cell", "raw-cpuid", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "web-sys", "winapi", ] [[package]] name = "quinn" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", "cfg_aliases", @@ -1817,8 +1764,8 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.5.10", - "thiserror 2.0.14", + "socket2", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -1826,12 +1773,12 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.12" +version = "0.11.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", - "getrandom 0.3.3", + "getrandom 0.3.4", "lru-slab", "rand 0.9.2", "ring", @@ -1839,7 +1786,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.14", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -1847,23 +1794,23 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.10", + "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -1892,7 +1839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -1912,7 +1859,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -1921,41 +1868,50 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] name = "raw-cpuid" -version = "11.5.0" +version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ "bitflags", ] [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -1965,9 +1921,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -1976,15 +1932,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "reqwest" -version = "0.12.23" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64", "bytes", @@ -2030,7 +1986,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -2047,36 +2003,39 @@ dependencies = [ "portable-atomic-util", ] -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - [[package]] name = "rustc-hash" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ "log", "once_cell", @@ -2089,9 +2048,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -2101,9 +2060,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.12.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "web-time", "zeroize", @@ -2111,9 +2070,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "ring", "rustls-pki-types", @@ -2128,17 +2087,17 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2149,9 +2108,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "3.3.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ "bitflags", "core-foundation", @@ -2162,9 +2121,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -2172,9 +2131,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "send_wrapper" @@ -2184,18 +2143,28 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -2204,14 +2173,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.142" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -2243,36 +2213,37 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] [[package]] name = "simd-adler32" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "slotmap" -version = "1.0.7" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +checksum = "bdd58c3c93c3d278ca835519292445cb4b0d4dc59ccfdf7ceadaab3f8aeb4038" dependencies = [ "version_check", ] @@ -2285,22 +2256,12 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.10" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "socket2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" -dependencies = [ - "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2314,9 +2275,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "strsim" @@ -2332,9 +2293,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.106" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -2363,9 +2324,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.37.1" +version = "0.37.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bddd368fda2f82ead69c03d46d351987cfa0c2a57abfa37a017f3aa3e9bf69a" +checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f" dependencies = [ "libc", "memchr", @@ -2388,15 +2349,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.20.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2418,7 +2379,7 @@ dependencies = [ "temporalio-client", "temporalio-common", "temporalio-sdk-core", - "thiserror 2.0.14", + "thiserror 2.0.18", "tokio", "tokio-stream", "tonic", @@ -2448,7 +2409,7 @@ dependencies = [ "rand 0.9.2", "slotmap", "temporalio-common", - "thiserror 2.0.14", + "thiserror 2.0.18", "tokio", "tonic", "tower", @@ -2473,7 +2434,7 @@ dependencies = [ "rand 0.9.2", "serde", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.18", "tonic", "tonic-prost", "tonic-prost-build", @@ -2539,7 +2500,7 @@ dependencies = [ "temporalio-client", "temporalio-common", "temporalio-macros", - "thiserror 2.0.14", + "thiserror 2.0.18", "tokio", "tokio-stream", "tokio-util", @@ -2568,11 +2529,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.14" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0949c3a6c842cbde3f1686d6eea5a010516deb7085f79db747562d4102f41e" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.14", + "thiserror-impl 2.0.18", ] [[package]] @@ -2588,9 +2549,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.14" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -2608,9 +2569,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -2618,9 +2579,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -2633,29 +2594,26 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.47.1" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2 0.6.0", + "socket2", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -2664,9 +2622,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", @@ -2674,9 +2632,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -2685,9 +2643,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -2698,9 +2656,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" +checksum = "a286e33f82f8a1ee2df63f4fa35c0becf4a85a0cb03091a15fd7bf0b402dc94a" dependencies = [ "async-trait", "axum", @@ -2716,7 +2674,7 @@ dependencies = [ "percent-encoding", "pin-project", "rustls-native-certs", - "socket2 0.6.0", + "socket2", "sync_wrapper", "tokio", "tokio-rustls", @@ -2729,9 +2687,9 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40aaccc9f9eccf2cd82ebc111adc13030d23e887244bc9cfa5d1d636049de3" +checksum = "27aac809edf60b741e2d7db6367214d078856b8a5bff0087e94ff330fb97b6fc" dependencies = [ "prettyplease", "proc-macro2", @@ -2741,9 +2699,9 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" +checksum = "d6c55a2d6a14174563de34409c9f92ff981d006f56da9c6ecd40d9d4a31500b0" dependencies = [ "bytes", "prost", @@ -2752,9 +2710,9 @@ dependencies = [ [[package]] name = "tonic-prost-build" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a16cba4043dc3ff43fcb3f96b4c5c154c64cbd18ca8dce2ab2c6a451d058a2" +checksum = "a4556786613791cfef4ed134aa670b61a85cfcacf71543ef33e8d801abae988f" dependencies = [ "prettyplease", "proc-macro2", @@ -2768,9 +2726,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", @@ -2787,9 +2745,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags", "bytes", @@ -2817,9 +2775,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -2828,9 +2786,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", @@ -2839,9 +2797,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -2849,9 +2807,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", @@ -2878,9 +2836,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typetag" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f22b40dd7bfe8c14230cf9702081366421890435b2d625fa92b4acc4c3de6f" +checksum = "be2212c8a9b9bcfca32024de14998494cf9a5dfa59ea1b829de98bac374b86bf" dependencies = [ "erased-serde", "inventory", @@ -2891,9 +2849,9 @@ dependencies = [ [[package]] name = "typetag-impl" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952" +checksum = "27a7a9b72ba121f6f1f6c3632b85604cac41aedb5ddc70accbebb6cac83de846" dependencies = [ "proc-macro2", "quote", @@ -2902,15 +2860,15 @@ dependencies = [ [[package]] name = "unicase" -version = "2.8.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-segmentation" @@ -2932,13 +2890,14 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.4" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -2949,11 +2908,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.18.1" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "js-sys", "wasm-bindgen", ] @@ -2986,47 +2945,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ "cfg-if", + "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -3035,9 +2982,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3045,22 +2992,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] @@ -3080,9 +3027,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -3129,7 +3076,7 @@ dependencies = [ "windows-collections", "windows-core", "windows-future", - "windows-link", + "windows-link 0.1.3", "windows-numerics", ] @@ -3150,7 +3097,7 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", + "windows-link 0.1.3", "windows-result", "windows-strings", ] @@ -3162,15 +3109,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core", - "windows-link", + "windows-link 0.1.3", "windows-threading", ] [[package]] name = "windows-implement" -version = "0.60.1" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -3179,9 +3126,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.2" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -3194,6 +3141,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-numerics" version = "0.2.0" @@ -3201,7 +3154,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ "windows-core", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -3210,7 +3163,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -3219,7 +3172,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -3233,20 +3186,20 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.52.6", + "windows-targets 0.53.5", ] [[package]] name = "windows-sys" -version = "0.60.2" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.53.3", + "windows-link 0.2.1", ] [[package]] @@ -3267,19 +3220,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -3288,7 +3241,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -3299,9 +3252,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -3311,9 +3264,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -3323,9 +3276,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -3335,9 +3288,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -3347,9 +3300,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -3359,9 +3312,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -3371,9 +3324,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -3383,30 +3336,27 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "xattr" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", "rustix", @@ -3414,11 +3364,10 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -3426,9 +3375,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -3438,18 +3387,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "57cf3aa6855b23711ee9852dfc97dfaa51c45feaba5b645d0c777414d494a961" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "8a616990af1a287837c4fe6596ad77ef57948f787e46ce28e166facc0cc1cb75" dependencies = [ "proc-macro2", "quote", @@ -3479,15 +3428,15 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -3496,9 +3445,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -3507,9 +3456,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", @@ -3534,15 +3483,21 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2" +checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" + +[[package]] +name = "zmij" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" [[package]] name = "zopfli" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" dependencies = [ "bumpalo", "crc32fast", @@ -3570,9 +3525,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.15+zstd.1.5.7" +version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ "cc", "pkg-config", diff --git a/packages/core-bridge/bridge-macros/src/derive_tryintojs.rs b/packages/core-bridge/bridge-macros/src/derive_tryintojs.rs index 68ed64998..a9b57e5b9 100644 --- a/packages/core-bridge/bridge-macros/src/derive_tryintojs.rs +++ b/packages/core-bridge/bridge-macros/src/derive_tryintojs.rs @@ -30,6 +30,46 @@ pub fn derive_tryintojs_struct(input: &DeriveInput, data: &syn::DataStruct) -> T } pub fn derive_tryintojs_enum(input: &DeriveInput, data: &syn::DataEnum) -> TokenStream { + let all_unit = data + .variants + .iter() + .all(|v| matches!(v.fields, syn::Fields::Unit)); + if all_unit { + derive_tryintojs_enum_as_string(input, data) + } else { + derive_tryintojs_enum_as_objects(input, data) + } +} + +fn derive_tryintojs_enum_as_string(input: &DeriveInput, data: &syn::DataEnum) -> TokenStream { + let enum_ident = &input.ident; + let generics = &input.generics; + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let variant_conversions = data.variants.iter().map(|v| { + let variant_ident = &v.ident; + let js_discriminant = variant_ident.to_string().to_case(Case::Camel); + quote! { + #enum_ident::#variant_ident => cx.string(#js_discriminant) + } + }); + + let expanded = quote! { + impl #impl_generics crate::helpers::TryIntoJs for #enum_ident #ty_generics #where_clause { + type Output = neon::types::JsString; + + fn try_into_js<'a>(self, cx: &mut impl neon::prelude::Context<'a>) -> neon::result::JsResult<'a, Self::Output> { + Ok(match self { + #(#variant_conversions),* + }) + } + } + }; + + TokenStream::from(expanded) +} + +fn derive_tryintojs_enum_as_objects(input: &DeriveInput, data: &syn::DataEnum) -> TokenStream { let enum_ident = &input.ident; let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); diff --git a/packages/core-bridge/sdk-core b/packages/core-bridge/sdk-core index 9dedad111..231e21cad 160000 --- a/packages/core-bridge/sdk-core +++ b/packages/core-bridge/sdk-core @@ -1 +1 @@ -Subproject commit 9dedad1115ab64a0ffb8decf3ad3f338979dea9f +Subproject commit 231e21cadb8004197a5b1dba2ecb1313596cc34c diff --git a/packages/core-bridge/src/helpers/try_into_js.rs b/packages/core-bridge/src/helpers/try_into_js.rs index fb0e3ca04..9818b6a9e 100644 --- a/packages/core-bridge/src/helpers/try_into_js.rs +++ b/packages/core-bridge/src/helpers/try_into_js.rs @@ -1,11 +1,11 @@ use std::{ - sync::Arc, + sync::{Arc, Mutex}, time::{Duration, SystemTime, UNIX_EPOCH}, }; use neon::{ object::Object, - prelude::Context, + prelude::{Context, Root}, result::JsResult, types::{ JsArray, JsBigInt, JsBoolean, JsBuffer, JsNumber, JsString, JsUndefined, JsValue, Value, @@ -36,6 +36,13 @@ impl TryIntoJs for u32 { } } +impl TryIntoJs for f64 { + type Output = JsNumber; + fn try_into_js<'a>(self, cx: &mut impl Context<'a>) -> JsResult<'a, JsNumber> { + Ok(cx.number(self)) + } +} + impl TryIntoJs for String { type Output = JsString; fn try_into_js<'a>(self, cx: &mut impl Context<'a>) -> JsResult<'a, JsString> { @@ -127,3 +134,82 @@ impl TryIntoJs for (T0, T1) { Ok(array) } } + +/// A handle that wraps another `TryIntoJs` type, memoizing the converted JavaScript value. +/// That is, the value is converted to JavaScript only once, and then the same JavaScript value +/// is returned for subsequent calls. This notably ensures that the value sent to the JS side +/// is exactly the same object every time (i.e. `===` comparison is true). +#[derive(Clone, Debug)] +pub struct MemoizedHandle +where + T::Output: std::fmt::Debug, +{ + internal: Arc>>, +} + +#[derive(Debug)] +enum MemoizedInternal { + Pending(T), + Rooted(Root), +} + +impl MemoizedHandle +where + T::Output: Object + std::fmt::Debug, +{ + pub fn new(value: T) -> Self { + Self { + internal: Arc::new(Mutex::new(MemoizedInternal::Pending(value))), + } + } +} + +impl TryIntoJs for MemoizedHandle +where + T::Output: Object + std::fmt::Debug, +{ + type Output = T::Output; + fn try_into_js<'cx>(self, cx: &mut impl Context<'cx>) -> JsResult<'cx, T::Output> { + let mut guard = self.internal.lock().expect("MemoizedHandle lock"); + match *guard { + MemoizedInternal::Pending(ref value) => { + let rooted_value = value.clone().try_into_js(cx)?.root(cx); + let js_value = rooted_value.to_inner(cx); + *guard = MemoizedInternal::Rooted(rooted_value); + Ok(js_value) + } + MemoizedInternal::Rooted(ref handle) => Ok(handle.to_inner(cx)), + } + } +} + +/// To avoid some recurring error patterns when crossing the JS bridge, we normally translate +/// `Option` to `T | null` on the JS side. This however implies extra code on the JS side +/// to check for `null` and convert to `undefined` as appropriate. This generally poses no +/// problem, as manipulation of objects on the JS side is anyway desirable for other reasons. +/// +/// In rare cases, however, this extra manipulation may not be desirable. For example, when +/// passing buffered metrics to the JS Side, we want to preserve object identity. Modifying +/// objects on the JS side would either break object identity or introduce unnecessary overhead. +/// +/// For those rare cases, this newtype wrapper to indicate that an option property should be +/// translated to `undefined` on the JS side, rather than `null`. +#[derive(Clone, Debug)] +pub struct OptionAsUndefined(Option); + +impl From> for OptionAsUndefined { + fn from(value: Option) -> Self { + Self(value) + } +} + +impl TryIntoJs for OptionAsUndefined { + type Output = JsValue; + fn try_into_js<'a>(self, cx: &mut impl Context<'a>) -> JsResult<'a, JsValue> { + if let Some(value) = self.0 { + Ok(value.try_into_js(cx)?.upcast()) + } else { + Ok(cx.undefined().upcast()) + } + } +} diff --git a/packages/core-bridge/src/metrics.rs b/packages/core-bridge/src/metrics.rs index 41411cdee..182cac487 100644 --- a/packages/core-bridge/src/metrics.rs +++ b/packages/core-bridge/src/metrics.rs @@ -1,27 +1,39 @@ +use std::any::Any; use std::collections::HashMap; +use std::sync::Arc; use neon::prelude::*; use serde::Deserialize; use temporalio_common::telemetry::metrics::{ - CoreMeter, Counter as CoreCounter, Gauge as CoreGauge, Histogram as CoreHistogram, - MetricParameters, NewAttributes, TemporalMeter, + BufferInstrumentRef as CoreBufferInstrumentRef, CoreMeter, Counter as CoreCounter, + CustomMetricAttributes, Gauge as CoreGauge, Histogram as CoreHistogram, MetricCallBufferer, + MetricEvent as CoreMetricEvent, MetricKind as CoreMetricKind, + MetricParameters as CoreMetricParameters, NewAttributes, TemporalMeter, }; use temporalio_common::telemetry::metrics::{ GaugeF64 as CoreGaugeF64, HistogramF64 as CoreHistogramF64, }; -use temporalio_common::telemetry::metrics::{ - MetricKeyValue as CoreMetricKeyValue, MetricValue as CoreMetricValue, +use temporalio_common::telemetry::{ + metrics, + metrics::{MetricKeyValue as CoreMetricKeyValue, MetricValue as CoreMetricValue}, }; -use bridge_macros::js_function; +use bridge_macros::{TryIntoJs, js_function}; +use temporalio_sdk_core::telemetry::MetricsCallBuffer as CoreMetricsCallBuffer; +use crate::helpers::properties::ObjectExt as _; +use crate::helpers::try_into_js::{MemoizedHandle, OptionAsUndefined}; use crate::helpers::{ BridgeError, BridgeResult, JsonString, MutableFinalize, OpaqueInboundHandle, - OpaqueOutboundHandle, + OpaqueOutboundHandle, TryIntoJs, }; use crate::runtime::Runtime; +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Metric Meter (aka Custom Metrics) +//////////////////////////////////////////////////////////////////////////////////////////////////// + pub fn init(cx: &mut neon::prelude::ModuleContext) -> neon::prelude::NeonResult<()> { cx.export_function("newMetricCounter", new_metric_counter)?; cx.export_function("newMetricHistogram", new_metric_histogram)?; @@ -115,7 +127,7 @@ pub fn new_metric_counter( ))?; let counter = meter.inner.counter( - MetricParameters::builder() + CoreMetricParameters::builder() .name(name) .unit(unit) .description(description) @@ -141,7 +153,7 @@ pub fn new_metric_histogram( ))?; let histogram = meter.inner.histogram( - MetricParameters::builder() + CoreMetricParameters::builder() .name(name) .unit(unit) .description(description) @@ -167,7 +179,7 @@ pub fn new_metric_histogram_f64( ))?; let histogram = meter.inner.histogram_f64( - MetricParameters::builder() + CoreMetricParameters::builder() .name(name) .unit(unit) .description(description) @@ -193,7 +205,7 @@ pub fn new_metric_gauge( ))?; let gauge = meter.inner.gauge( - MetricParameters::builder() + CoreMetricParameters::builder() .name(name) .unit(unit) .description(description) @@ -219,7 +231,7 @@ pub fn new_metric_gauge_f64( ))?; let gauge = meter.inner.gauge_f64( - MetricParameters::builder() + CoreMetricParameters::builder() .name(name) .unit(unit) .description(description) @@ -239,10 +251,12 @@ pub fn add_metric_counter_value( attributes: JsonString, ) -> BridgeResult<()> { let counter_handle = counter_handle.borrow()?; + let attributes = counter_handle .meter .inner .new_attributes(parse_metric_attributes(attributes.value)); + counter_handle.counter.add(value as u64, &attributes); Ok(()) } @@ -307,6 +321,235 @@ pub fn set_metric_gauge_f64_value( Ok(()) } +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Buffered Metrics (aka lang-side metrics exporter) +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#[derive(Debug)] +pub struct MetricsCallBuffer { + pub(crate) core_buffer: Arc>, + use_seconds_for_durations: bool, +} + +impl MetricsCallBuffer { + pub(crate) fn new(max_buffer_size: usize, use_seconds_for_durations: bool) -> Self { + Self { + core_buffer: Arc::new(CoreMetricsCallBuffer::new(max_buffer_size)), + use_seconds_for_durations, + } + } + + pub(crate) fn retrieve(&self) -> Vec { + self.core_buffer + .retrieve() + .iter() + .filter_map(|e| self.convert_metric_event(e)) + .collect() + } + + fn convert_metric_event( + &self, + event: &CoreMetricEvent, + ) -> Option { + match event { + CoreMetricEvent::Create { + params, + populate_into, + kind, + } => { + // Create the metric and put it on the lazy ref + let metric = BufferedMetric::new(params, *kind, self.use_seconds_for_durations); + populate_into + .set(Arc::new(BufferedMetricRef(MemoizedHandle::new(metric)))) + .expect("Unable to set buffered metric on reference"); + + None + } + + // Create the attributes and put it on the lazy ref + CoreMetricEvent::CreateAttributes { + populate_into, + append_from, + attributes, + } => { + let append_from = append_from.as_ref().map(|f| { + f.get() + .clone() + .as_any() + .downcast::() + .expect("Unable to downcast to expected buffered metric attributes") + }); + let attributes = BufferedMetricAttributes { + new_attributes: attributes.clone(), + append_from: append_from.map(|f| f.as_ref().clone()), + }; + + let r = BufferedMetricAttributesRef(MemoizedHandle::new(attributes)); + populate_into + .set(Arc::new(r)) + .expect("Unable to set buffered metric attributes on reference"); + + None + } + + CoreMetricEvent::Update { + instrument, + attributes, + update, + } => Some(BufferedMetricUpdate { + metric: instrument.get().as_ref().clone(), + #[allow(clippy::match_same_arms, clippy::cast_precision_loss)] + value: match update { + metrics::MetricUpdateVal::Duration(v) if self.use_seconds_for_durations => { + v.as_secs_f64() + } + metrics::MetricUpdateVal::Duration(v) => v.as_millis() as f64, + metrics::MetricUpdateVal::Delta(v) => *v as f64, + metrics::MetricUpdateVal::DeltaF64(v) => *v, + metrics::MetricUpdateVal::Value(v) => *v as f64, + metrics::MetricUpdateVal::ValueF64(v) => *v, + }, + attributes: attributes + .get() + .clone() + .as_any() + .downcast::() + .expect("Unable to downcast to expected buffered metric attributes") + .as_ref() + .clone(), + }), + } + } +} + +#[derive(TryIntoJs)] +pub struct BufferedMetricUpdate { + metric: BufferedMetricRef, + value: f64, + attributes: BufferedMetricAttributesRef, +} + +#[derive(TryIntoJs, Clone, Debug)] +struct BufferedMetric { + name: String, + description: OptionAsUndefined, + unit: OptionAsUndefined, + kind: MetricKind, + value_type: MetricValueType, +} + +impl BufferedMetric { + pub fn new( + params: &CoreMetricParameters, + kind: CoreMetricKind, + use_seconds_for_durations: bool, + ) -> Self { + let unit = match kind { + CoreMetricKind::HistogramDuration if params.unit == "duration" => { + Some((if use_seconds_for_durations { "s" } else { "ms" }).to_string()) + } + _ => (!params.unit.is_empty()).then_some(params.unit.to_string()), + }; + + #[allow(clippy::match_same_arms)] + let (kind, value_type) = match kind { + CoreMetricKind::Counter => (MetricKind::Counter, MetricValueType::Int), + CoreMetricKind::Gauge => (MetricKind::Gauge, MetricValueType::Int), + CoreMetricKind::GaugeF64 => (MetricKind::Gauge, MetricValueType::Float), + CoreMetricKind::Histogram => (MetricKind::Histogram, MetricValueType::Int), + CoreMetricKind::HistogramF64 => (MetricKind::Histogram, MetricValueType::Float), + CoreMetricKind::HistogramDuration => (MetricKind::Histogram, MetricValueType::Int), + }; + + let description = + (!params.description.is_empty()).then_some(params.description.to_string()); + + Self { + name: params.name.to_string(), + description: description.into(), + unit: unit.into(), + kind, + value_type, + } + } +} + +#[derive(Clone, Debug)] +pub struct BufferedMetricRef(MemoizedHandle); +impl CoreBufferInstrumentRef for BufferedMetricRef {} + +impl TryIntoJs for BufferedMetricRef { + type Output = JsObject; + fn try_into_js<'cx>(self, cx: &mut impl Context<'cx>) -> JsResult<'cx, Self::Output> { + self.0.try_into_js(cx) + } +} + +#[derive(Clone, Debug)] +struct BufferedMetricAttributes { + new_attributes: Vec, + append_from: Option, +} + +impl TryIntoJs for BufferedMetricAttributes { + type Output = JsObject; + fn try_into_js<'cx>(self, cx: &mut impl Context<'cx>) -> JsResult<'cx, Self::Output> { + let object = cx.empty_object(); + + // Copy existing attributes, if any + if let Some(existing) = self.append_from { + let existing_attrs = existing.try_into_js(cx)?; + + object_assign(cx, object, existing_attrs)?; + } + + // Assign new attributes + for kv in self.new_attributes { + let k = kv.key.as_str(); + #[allow(clippy::cast_precision_loss)] + match &kv.value { + metrics::MetricValue::String(v) => object.set_property_from(cx, k, v.as_str()), + metrics::MetricValue::Int(v) => object.set_property_from(cx, k, *v as f64), + metrics::MetricValue::Float(v) => object.set_property_from(cx, k, *v), + metrics::MetricValue::Bool(v) => object.set_property_from(cx, k, *v), + }?; + } + + Ok(object) + } +} + +#[derive(Clone, Debug)] +struct BufferedMetricAttributesRef(MemoizedHandle); + +impl CustomMetricAttributes for BufferedMetricAttributesRef { + fn as_any(self: Arc) -> Arc { + self as Arc + } +} + +impl TryIntoJs for BufferedMetricAttributesRef { + type Output = JsObject; + fn try_into_js<'cx>(self, cx: &mut impl Context<'cx>) -> JsResult<'cx, Self::Output> { + self.0.try_into_js(cx) + } +} + +#[derive(TryIntoJs, Clone, Debug)] +enum MetricKind { + Counter, + Gauge, + Histogram, +} + +#[derive(TryIntoJs, Clone, Debug)] +enum MetricValueType { + Int, + Float, +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Helpers //////////////////////////////////////////////////////////////////////////////////////////////////// fn parse_metric_attributes(attrs: MetricAttributes) -> NewAttributes { @@ -320,3 +563,16 @@ fn parse_metric_attributes(attrs: MetricAttributes) -> NewAttributes { .collect(); NewAttributes { attributes: attrs } } + +fn object_assign<'cx>( + cx: &mut impl Context<'cx>, + object: Handle<'cx, JsObject>, + source: Handle<'cx, JsObject>, +) -> JsResult<'cx, JsObject> { + let object_class = cx.global::("Object")?; + let assign_function = object_class.get::(cx, "assign")?; + let null = cx.null(); + assign_function.call(cx, null, vec![object.upcast(), source.upcast()])?; + + Ok(object) +} diff --git a/packages/core-bridge/src/runtime.rs b/packages/core-bridge/src/runtime.rs index a825dc279..5eb10f07b 100644 --- a/packages/core-bridge/src/runtime.rs +++ b/packages/core-bridge/src/runtime.rs @@ -20,6 +20,7 @@ use tokio_stream::StreamExt as _; use crate::{ helpers::{handles::MutableFinalize, *}, logs::LogEntry, + metrics::{BufferedMetricUpdate, MetricsCallBuffer}, }; #[macro_export] @@ -36,6 +37,10 @@ macro_rules! enter_sync { pub fn init(cx: &mut neon::prelude::ModuleContext) -> neon::prelude::NeonResult<()> { cx.export_function("newRuntime", runtime_new)?; cx.export_function("runtimeShutdown", runtime_shutdown)?; + cx.export_function( + "runtimeRetrieveBufferedMetrics", + runtime_retrieve_buffered_metrics, + )?; Ok(()) } @@ -51,6 +56,9 @@ pub struct Runtime { // For some unknown reason, the otel metrics exporter will go crazy on shutdown in some // scenarios if we don't hold on to the `CoreOtelMeter` till the `Runtime` finally gets dropped. _otel_metrics_exporter: Option>, + + // Buffered metrics call buffer, if buffered metrics are enabled + pub(crate) metrics_call_buffer: Option, } /// Initialize Core global telemetry and create the tokio runtime required to run Core. @@ -77,30 +85,44 @@ pub fn runtime_new( enter_sync!(core_runtime); // Run the metrics exporter task, if needed. Created after Runtime since it needs Tokio handle - let (prom_metrics_exporter_task, otel_metrics_exporter) = match metrics_options { - Some(BridgeMetricsExporter::Prometheus(prom_opts)) => { - let exporter = start_prometheus_metric_exporter(prom_opts) - .context("Failed to start prometheus metrics exporter")?; + let (prom_metrics_exporter_task, otel_metrics_exporter, metrics_call_buffer) = + match metrics_options { + Some(BridgeMetricsExporter::Prometheus(prom_opts)) => { + let exporter = start_prometheus_metric_exporter(prom_opts) + .context("Failed to start prometheus metrics exporter")?; - core_runtime - .telemetry_mut() - .attach_late_init_metrics(exporter.meter); + core_runtime + .telemetry_mut() + .attach_late_init_metrics(exporter.meter); - (Some(exporter.abort_handle), None) - } - Some(BridgeMetricsExporter::Otel(otel_opts)) => { - let exporter = build_otlp_metric_exporter(otel_opts) - .context("Failed to start OTel metrics exporter")?; + (Some(exporter.abort_handle), None, None) + } + Some(BridgeMetricsExporter::Otel(otel_opts)) => { + let exporter = build_otlp_metric_exporter(otel_opts) + .context("Failed to start OTel metrics exporter")?; - let exporter: Arc = Arc::new(exporter); - core_runtime - .telemetry_mut() - .attach_late_init_metrics(exporter.clone()); + let exporter: Arc = Arc::new(exporter); + core_runtime + .telemetry_mut() + .attach_late_init_metrics(exporter.clone()); - (None, Some(exporter)) - } - None => (None, None), - }; + (None, Some(exporter), None) + } + Some(BridgeMetricsExporter::Buffer { + max_buffer_size, + use_seconds_for_durations, + }) => { + let metrics_call_buffer = + MetricsCallBuffer::new(max_buffer_size, use_seconds_for_durations); + + core_runtime + .telemetry_mut() + .attach_late_init_metrics(metrics_call_buffer.core_buffer.clone()); + + (None, None, Some(metrics_call_buffer)) + } + None => (None, None, None), + }; // Run the log exporter task, if needed. Created after Runtime since it needs Tokio handle. let log_exporter_task = if let BridgeLogExporter::Push { stream, receiver } = logging_options { @@ -130,6 +152,7 @@ pub fn runtime_new( log_exporter_task, metrics_exporter_task: prom_metrics_exporter_task.map(Arc::new), _otel_metrics_exporter: otel_metrics_exporter, + metrics_call_buffer, })) } @@ -143,6 +166,24 @@ pub fn runtime_shutdown(runtime: OpaqueInboundHandle) -> BridgeResult<( Ok(()) } +/// Retrieve buffered metrics from the runtime. +/// +/// This function drains the metrics buffer and returns all metric updates that have been +/// accumulated since the last call to this function. +#[js_function] +pub fn runtime_retrieve_buffered_metrics( + runtime: OpaqueInboundHandle, +) -> BridgeResult> { + let runtime = runtime.borrow()?; + let buffer = runtime.metrics_call_buffer.as_ref().ok_or_else(|| { + BridgeError::UnexpectedError( + "Attempting to retrieve buffered metrics of a runtime without buffer".into(), + ) + })?; + + Ok(buffer.retrieve()) +} + /// Drop will handle the cleanup impl MutableFinalize for Runtime {} @@ -226,6 +267,10 @@ impl RuntimeExt for Arc { pub enum BridgeMetricsExporter { Prometheus(CorePrometheusExporterOptions), Otel(CoreOtelCollectorOptions), + Buffer { + max_buffer_size: usize, + use_seconds_for_durations: bool, + }, } pub enum BridgeLogExporter { @@ -291,6 +336,7 @@ mod config { pub(super) enum MetricsExporterOptions { Prometheus(PrometheusMetricsExporterConfig), Otel(OtelMetricsExporterConfig), + Buffer(BufferedMetricsExporterConfig), } #[derive(Debug, Clone, TryFromJs)] @@ -315,6 +361,12 @@ mod config { protocol: StringEncoded, } + #[derive(Debug, Clone, TryFromJs)] + pub(super) struct BufferedMetricsExporterConfig { + max_buffer_size: usize, + use_seconds_for_durations: bool, + } + /// A private newtype so that we can implement `TryFromJs` on simple externally defined enums #[derive(Debug, Clone)] struct StringEncoded(T); @@ -387,6 +439,10 @@ mod config { Ok(super::BridgeMetricsExporter::Prometheus(prom.try_into()?)) } Self::Otel(otel) => Ok(super::BridgeMetricsExporter::Otel(otel.try_into()?)), + Self::Buffer(buffered) => Ok(super::BridgeMetricsExporter::Buffer { + max_buffer_size: buffered.max_buffer_size, + use_seconds_for_durations: buffered.use_seconds_for_durations, + }), } } } diff --git a/packages/core-bridge/ts/native.ts b/packages/core-bridge/ts/native.ts index ac8b3284b..b9f552be3 100644 --- a/packages/core-bridge/ts/native.ts +++ b/packages/core-bridge/ts/native.ts @@ -71,7 +71,11 @@ export type LogExporterOptions = receiver: (entries: JsonString[]) => void; }; -export type MetricExporterOptions = PrometheusMetricsExporterOptions | OtelMetricsExporterOptions | null; +export type MetricExporterOptions = + | PrometheusMetricsExporterOptions + | OtelMetricsExporterOptions + | BufferedMetricsExporterOptions + | null; export interface PrometheusMetricsExporterOptions { type: 'prometheus'; @@ -95,6 +99,12 @@ export interface OtelMetricsExporterOptions { protocol: 'http' | 'grpc'; } +export interface BufferedMetricsExporterOptions { + type: 'buffer'; + maxBufferSize: number; + useSecondsForDurations: boolean; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// // Client //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -525,3 +535,27 @@ export declare function setMetricGaugeF64Value( value: number, attrs: JsonString ): void; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Buffered Metrics +//////////////////////////////////////////////////////////////////////////////////////////////////// + +export declare function runtimeRetrieveBufferedMetrics(runtime: Runtime): BufferedMetricUpdate[]; + +export interface BufferedMetricUpdate { + metric: BufferedMetric; + value: number; + attributes: MetricAttributes; +} + +export interface BufferedMetric { + name: string; + description: string; + unit: string; + kind: BufferedMetricKind; + valueType: BufferedMetricValueType; +} + +export type BufferedMetricKind = 'counter' | 'histogram' | 'gauge'; + +export type BufferedMetricValueType = 'int' | 'float'; diff --git a/packages/test/src/test-ai-sdk.ts b/packages/test/src/test-ai-sdk.ts index 2a18568c4..152fc3e26 100644 --- a/packages/test/src/test-ai-sdk.ts +++ b/packages/test/src/test-ai-sdk.ts @@ -439,7 +439,7 @@ test('Telemetry', async (t) => { }); await otel.start(); const sinks: InjectedSinks = { - exporter: makeWorkflowExporter(traceExporter, staticResource), + exporter: makeWorkflowExporter(traceExporter, staticResource), // eslint-disable-line deprecation/deprecation }; const worker = await Worker.create({ diff --git a/packages/test/src/test-otel.ts b/packages/test/src/test-otel.ts index df908fa30..a51029879 100644 --- a/packages/test/src/test-otel.ts +++ b/packages/test/src/test-otel.ts @@ -40,7 +40,7 @@ import { } from '@temporalio/worker'; import { WorkflowInboundCallsInterceptor, WorkflowOutboundCallsInterceptor } from '@temporalio/workflow'; import * as activities from './activities'; -import { bundlerOptions, loadHistory, RUN_INTEGRATION_TESTS, TestWorkflowEnvironment, Worker } from './helpers'; +import { bundlerOptions, loadHistory, RUN_INTEGRATION_TESTS, Worker } from './helpers'; import * as workflows from './workflows'; import { createTestWorkflowBundle } from './helpers-integration'; @@ -81,7 +81,7 @@ async function withFakeGrpcServer( // The OTel exporter will try to flush metrics on drop, which may result in tons of ERROR // messages on the console if the server has had time to complete shutdown before then. // Delaying closing the server by 1 second is enough to avoid that situation, and doesn't - // need to be awaited, no that doesn't slow down tests. + // need to be awaited, so that doesn't slow down tests. setTimeout(() => { srv.close(); }, 1000).unref(); @@ -90,161 +90,6 @@ async function withFakeGrpcServer( }); } -async function withHttpServer( - fn: (port: number) => Promise, - requestListener?: (request: http.IncomingMessage) => void -): Promise { - return new Promise((resolve, reject) => { - const srv = http.createServer(); - srv.listen({ port: 0, host: '127.0.0.1' }, () => { - const addr = srv.address(); - if (typeof addr === 'string' || addr === null) { - throw new Error('Unexpected server address type'); - } - srv.on('request', async (req, res) => { - if (requestListener) await requestListener(req); - res.statusCode = 200; - res.end(); - }); - fn(addr.port) - .catch((e) => reject(e)) - .finally(() => { - resolve(); - - // The OTel exporter will try to flush metrics on drop, which may result in tons of ERROR - // messages on the console if the server has had time to complete shutdown before then. - // Delaying closing the server by 1 second is enough to avoid that situation, and doesn't - // need to be awaited, no that doesn't slow down tests. - setTimeout(() => { - srv.close(); - }, 1000).unref(); - }); - }); - }); -} - -test.serial('Runtime.install() throws meaningful error when passed invalid metrics.otel.url', async (t) => { - t.throws(() => Runtime.install({ telemetryOptions: { metrics: { otel: { url: ':invalid' } } } }), { - instanceOf: TypeError, - message: /metricsExporter.otel.url/, - }); -}); - -test.serial('Runtime.install() accepts metrics.otel.url without headers', async (t) => { - try { - Runtime.install({ telemetryOptions: { metrics: { otel: { url: 'http://127.0.0.1:1234' } } } }); - t.pass(); - } finally { - // Cleanup the runtime so that it doesn't interfere with other tests - await Runtime._instance?.shutdown(); - } -}); - -test.serial('Exporting OTEL metrics from Core works', async (t) => { - let resolveCapturedRequest = (_req: http2.Http2ServerRequest) => undefined as void; - const capturedRequest = new Promise((r) => (resolveCapturedRequest = r)); - try { - await withFakeGrpcServer(async (port: number) => { - Runtime.install({ - telemetryOptions: { - metrics: { - otel: { - url: `http://127.0.0.1:${port}`, - headers: { - 'x-test-header': 'test-value', - }, - metricsExportInterval: 10, - }, - }, - }, - }); - - const localEnv = await TestWorkflowEnvironment.createLocal(); - try { - const worker = await Worker.create({ - connection: localEnv.nativeConnection, - workflowsPath: require.resolve('./workflows'), - taskQueue: 'test-otel', - }); - const client = new WorkflowClient({ - connection: localEnv.connection, - }); - await worker.runUntil(async () => { - await client.execute(workflows.successString, { - taskQueue: 'test-otel', - workflowId: uuid4(), - }); - const req = await Promise.race([ - capturedRequest, - await new Promise((resolve) => setTimeout(() => resolve(undefined), 2000)), - ]); - t.truthy(req); - t.is(req?.url, '/opentelemetry.proto.collector.metrics.v1.MetricsService/Export'); - t.is(req?.headers['x-test-header'], 'test-value'); - }); - } finally { - await localEnv.teardown(); - } - }, resolveCapturedRequest); - } finally { - // Cleanup the runtime so that it doesn't interfere with other tests - await Runtime._instance?.shutdown(); - } -}); - -test.serial('Exporting OTEL metrics using OTLP/HTTP from Core works', async (t) => { - let resolveCapturedRequest = (_req: http.IncomingMessage) => undefined as void; - const capturedRequest = new Promise((r) => (resolveCapturedRequest = r)); - try { - await withHttpServer(async (port: number) => { - Runtime.install({ - telemetryOptions: { - metrics: { - otel: { - url: `http://127.0.0.1:${port}/v1/metrics`, - http: true, - headers: { - 'x-test-header': 'test-value', - }, - metricsExportInterval: 10, - }, - }, - }, - }); - - const localEnv = await TestWorkflowEnvironment.createLocal(); - try { - const worker = await Worker.create({ - connection: localEnv.nativeConnection, - workflowsPath: require.resolve('./workflows'), - taskQueue: 'test-otel', - }); - const client = new WorkflowClient({ - connection: localEnv.connection, - }); - await worker.runUntil(async () => { - await client.execute(workflows.successString, { - taskQueue: 'test-otel', - workflowId: uuid4(), - }); - const req = await Promise.race([ - capturedRequest, - await new Promise((resolve) => setTimeout(() => resolve(undefined), 2000)), - ]); - t.truthy(req); - t.is(req?.url, '/v1/metrics'); - t.is(req?.headers['x-test-header'], 'test-value'); - }); - } finally { - await localEnv.teardown(); - } - }, resolveCapturedRequest); - } finally { - // Cleanup the runtime so that it doesn't interfere with other tests - await Runtime._instance?.shutdown(); - } -}); - if (RUN_INTEGRATION_TESTS) { test.serial('Otel interceptor spans are connected and complete', async (t) => { Runtime.install({}); diff --git a/packages/test/src/test-runtime-buffered-metrics.ts b/packages/test/src/test-runtime-buffered-metrics.ts new file mode 100644 index 000000000..f5af8a693 --- /dev/null +++ b/packages/test/src/test-runtime-buffered-metrics.ts @@ -0,0 +1,298 @@ +import test from 'ava'; +import { MetricsBuffer, Runtime } from '@temporalio/worker'; + +// Asserts that: +// - Buffered metrics can be retrieved from Core +// - Metric parameters are properly reported in update events +// - A Metric object is reused across update events for the same metric +// - Metric update events contain the correct value +test.serial('Buffered Metrics - Exporting buffered metrics from Core works properly', async (t) => { + const buffer = new MetricsBuffer({ + maxBufferSize: 1000, + useSecondsForDurations: false, + }); + const runtime = Runtime.install({ + telemetryOptions: { + metrics: { + buffer, + }, + }, + }); + const meter = runtime.metricMeter; + + try { + // Counter (events 0-2) + const counter = meter.createCounter('my-counter', 'my-counter-unit', 'my-counter-description'); + counter.add(1); + counter.add(1); + counter.add(40); // 1+1+40 => 42 + + // Int Gauge (events 3-4) + const gaugeInt = meter.createGauge('my-int-gauge', 'int', 'my-int-gauge-unit', 'my-int-gauge-description'); + gaugeInt.set(1); + gaugeInt.set(40); + + // Float Gauge (events 5-7) + const gaugeFloat = meter.createGauge( + 'my-float-gauge', + 'float', + 'my-float-gauge-unit', + 'my-float-gauge-description' + ); + gaugeFloat.set(1.1); + gaugeFloat.set(1.1); + gaugeFloat.set(40.1); + + // Int Histogram (events 8-10) + const histogramInt = meter.createHistogram( + 'my-int-histogram', + 'int', + 'my-int-histogram-unit', + 'my-int-histogram-description' + ); + histogramInt.record(20); + histogramInt.record(200); + histogramInt.record(2000); + + // Float Histogram (events 11-13) + const histogramFloat = meter.createHistogram( + 'my-float-histogram', + 'float', + 'my-float-histogram-unit', + 'my-float-histogram-description' + ); + histogramFloat.record(0.02); + histogramFloat.record(0.07); + histogramFloat.record(0.99); + + const updatesIterator = buffer.retrieveUpdates(); + + // Metric events may include other metrics emitted by Core, which would be too + // flaky to test here. Hence we filter out all metrics that do not start with 'my-'. + const updates = Array.from(updatesIterator).filter((update) => update.metric.name.startsWith('my-')); + t.is(updates.length, 14); + + t.deepEqual(updates[0].metric, { + name: 'my-counter', + kind: 'counter', + valueType: 'int', + unit: 'my-counter-unit', + description: 'my-counter-description', + }); + t.is(updates[0].value, 1); + t.is(updates[1].metric, updates[0].metric); + t.is(updates[1].value, 1); + t.is(updates[2].metric, updates[0].metric); + t.is(updates[2].value, 40); + + t.deepEqual(updates[3].metric, { + name: 'my-int-gauge', + kind: 'gauge', + valueType: 'int', + unit: 'my-int-gauge-unit', + description: 'my-int-gauge-description', + }); + t.is(updates[3].value, 1); + t.is(updates[4].metric, updates[3].metric); + t.is(updates[4].value, 40); + + t.deepEqual(updates[5].metric, { + name: 'my-float-gauge', + kind: 'gauge', + valueType: 'float', + unit: 'my-float-gauge-unit', + description: 'my-float-gauge-description', + }); + t.is(updates[5].value, 1.1); + t.is(updates[6].metric, updates[5].metric); + t.is(updates[6].value, 1.1); + t.is(updates[7].metric, updates[5].metric); + t.is(updates[7].value, 40.1); + + t.deepEqual(updates[8].metric, { + name: 'my-int-histogram', + kind: 'histogram', + valueType: 'int', + unit: 'my-int-histogram-unit', + description: 'my-int-histogram-description', + }); + t.is(updates[8].value, 20); + t.is(updates[9].metric, updates[8].metric); + t.is(updates[9].value, 200); + t.is(updates[10].metric, updates[8].metric); + t.is(updates[10].value, 2000); + + t.deepEqual(updates[11].metric, { + name: 'my-float-histogram', + kind: 'histogram', + valueType: 'float', + unit: 'my-float-histogram-unit', + description: 'my-float-histogram-description', + }); + t.is(updates[11].value, 0.02); + t.is(updates[12].metric, updates[11].metric); + t.is(updates[12].value, 0.07); + t.is(updates[13].metric, updates[11].metric); + t.is(updates[13].value, 0.99); + } finally { + await runtime.shutdown(); + } +}); + +test.serial('Buffered Metrics - Metric attributes are properly reported', async (t) => { + const buffer = new MetricsBuffer({ + maxBufferSize: 1000, + useSecondsForDurations: false, + }); + const runtime = Runtime.install({ + telemetryOptions: { + metrics: { + buffer, + }, + }, + }); + const meter = runtime.metricMeter; + + try { + const counter = meter.createCounter('my-counter', 'my-counter-unit', 'my-counter-description'); + const counter2 = counter.withTags({ labelA: 'value-a', labelB: true, labelC: 123, labelD: 123.456 }); + + counter2.add(1); + counter2.add(2, { labelA: 'value-a2', labelE: 12.34 }); + counter2.add(3, { labelC: 'value-c2', labelE: 23.45 }); + + const updatesIterator = buffer.retrieveUpdates(); + + // Metric events may include other metrics emitted by Core, which would be too + // flaky to test here. Hence we filter out all metrics that do not start with 'my-'. + const updates = Array.from(updatesIterator).filter((update) => update.metric.name.startsWith('my-')); + t.is(updates.length, 3); + + t.is(updates[0].value, 1); + t.deepEqual(updates[0].attributes, { + labelA: 'value-a', + labelB: true, + labelC: 123, + labelD: 123.456, + }); + t.is(updates[1].value, 2); + t.deepEqual(updates[1].attributes, { + labelA: 'value-a2', + labelB: true, + labelC: 123, + labelD: 123.456, + labelE: 12.34, + }); + t.is(updates[2].value, 3); + t.deepEqual(updates[2].attributes, { + labelA: 'value-a', + labelB: true, + labelC: 'value-c2', + labelD: 123.456, + labelE: 23.45, + }); + } finally { + await runtime.shutdown(); + } +}); + +test.serial('Buffered Metrics - empty description and unit are reported as undefined', async (t) => { + const buffer = new MetricsBuffer({ + maxBufferSize: 1000, + useSecondsForDurations: false, + }); + const runtime = Runtime.install({ + telemetryOptions: { + metrics: { + buffer, + }, + }, + }); + const meter = runtime.metricMeter; + + try { + const counter = meter.createCounter('my-counter', undefined, undefined); + counter.add(1); + + // Metric events may include other metrics emitted by Core, which would be too + // flaky to test here. Hence we filter out all metrics that do not start with 'my-'. + const updatesIterator = buffer.retrieveUpdates(); + const updates = Array.from(updatesIterator).filter((update) => update.metric.name.startsWith('my-')); + t.is(updates.length, 1); + + t.deepEqual(updates[0].metric, { + name: 'my-counter', + kind: 'counter', + valueType: 'int', + unit: undefined, + description: undefined, + }); + t.is(updates[0].value, 1); + } finally { + await runtime.shutdown(); + } +}); + +test.serial('Buffered Metrics - MetricsBuffer does not lose metric events on runtime shutdown', async (t) => { + const buffer = new MetricsBuffer({ + maxBufferSize: 1000, + useSecondsForDurations: false, + }); + + { + const runtime = Runtime.install({ + telemetryOptions: { + metrics: { + buffer, + }, + }, + }); + const meter = runtime.metricMeter; + + try { + const counter = meter.createCounter('my-counter', undefined, undefined); + counter.add(1); + + const updatesIterator = buffer.retrieveUpdates(); + const updates = Array.from(updatesIterator).filter((update) => update.metric.name === 'my-counter'); + t.is(updates.length, 1); + t.is(updates[0].value, 1); + + // That metric event should not be lost; we'll retrieve it after the runtime is shut down. + counter.add(2); + } finally { + await runtime.shutdown(); + } + } + + { + // This will create a new runtime instance, reusing the previous RuntimeOptions. + // That notably means that the same MetricsBuffer instance will be reused. + // This is the behavior we want to test here. + const runtime = Runtime.instance(); + const meter = runtime.metricMeter; + + try { + const counter = meter.createCounter('my-counter', undefined, undefined); + counter.add(3); + + const updatesIterator = buffer.retrieveUpdates(); + const updates = Array.from(updatesIterator).filter((update) => update.metric.name === 'my-counter'); + t.is(updates.length, 2); + t.is(updates[0].value, 2); + t.is(updates[1].value, 3); + + // That metric event should not be lost; we'll retrieve it after the runtime is shut down. + counter.add(4); + } finally { + await runtime.shutdown(); + } + } + + { + const updatesIterator = buffer.retrieveUpdates(); + const updates = Array.from(updatesIterator).filter((update) => update.metric.name === 'my-counter'); + t.is(updates.length, 1); + t.is(updates[0].value, 4); + } +}); diff --git a/packages/test/src/test-runtime-otel.ts b/packages/test/src/test-runtime-otel.ts new file mode 100644 index 000000000..8ab9469de --- /dev/null +++ b/packages/test/src/test-runtime-otel.ts @@ -0,0 +1,209 @@ +import * as http from 'http'; +import * as http2 from 'http2'; +import test from 'ava'; +import { v4 as uuid4 } from 'uuid'; +import { WorkflowClient } from '@temporalio/client'; +import { Runtime } from '@temporalio/worker'; +import { TestWorkflowEnvironment, Worker } from './helpers'; +import * as workflows from './workflows'; + +async function withFakeGrpcServer( + fn: (port: number) => Promise, + requestListener?: (request: http2.Http2ServerRequest, response: http2.Http2ServerResponse) => void +): Promise { + return new Promise((resolve, reject) => { + const srv = http2.createServer(); + srv.listen({ port: 0, host: '127.0.0.1' }, () => { + const addr = srv.address(); + if (typeof addr === 'string' || addr === null) { + throw new Error('Unexpected server address type'); + } + srv.on('request', async (req, res) => { + if (requestListener) requestListener(req, res); + res.statusCode = 200; + res.addTrailers({ + 'grpc-status': '0', + 'grpc-message': 'OK', + }); + res.write( + // This is a raw gRPC response, of length 0 + new Uint8Array([ + // Frame Type: Data; Not Compressed + 0, + // Message Length: 0 + 0, 0, 0, 0, + ]) + ); + res.end(); + }); + fn(addr.port) + .catch((e) => reject(e)) + .finally(() => { + resolve(); + + // The OTel exporter will try to flush metrics on drop, which may result in tons of ERROR + // messages on the console if the server has had time to complete shutdown before then. + // Delaying closing the server by 1 second is enough to avoid that situation, and doesn't + // need to be awaited, so that doesn't slow down tests. + setTimeout(() => { + srv.close(); + }, 1000).unref(); + }); + }); + }); +} + +async function withHttpServer( + fn: (port: number) => Promise, + requestListener?: (request: http.IncomingMessage) => void +): Promise { + return new Promise((resolve, reject) => { + const srv = http.createServer(); + srv.listen({ port: 0, host: '127.0.0.1' }, () => { + const addr = srv.address(); + if (typeof addr === 'string' || addr === null) { + throw new Error('Unexpected server address type'); + } + srv.on('request', async (req, res) => { + if (requestListener) await requestListener(req); + res.statusCode = 200; + res.end(); + }); + fn(addr.port) + .catch((e) => reject(e)) + .finally(() => { + resolve(); + + // The OTel exporter will try to flush metrics on drop, which may result in tons of ERROR + // messages on the console if the server has had time to complete shutdown before then. + // Delaying closing the server by 1 second is enough to avoid that situation, and doesn't + // need to be awaited, so that doesn't slow down tests. + setTimeout(() => { + srv.close(); + }, 1000).unref(); + }); + }); + }); +} + +test.serial('Runtime.install() throws meaningful error when passed invalid metrics.otel.url', async (t) => { + t.throws(() => Runtime.install({ telemetryOptions: { metrics: { otel: { url: ':invalid' } } } }), { + instanceOf: TypeError, + message: /metricsExporter.otel.url/, + }); +}); + +test.serial('Runtime.install() accepts metrics.otel.url without headers', async (t) => { + try { + Runtime.install({ telemetryOptions: { metrics: { otel: { url: 'http://127.0.0.1:1234' } } } }); + t.pass(); + } finally { + // Cleanup the runtime so that it doesn't interfere with other tests + await Runtime._instance?.shutdown(); + } +}); + +test.serial('Exporting OTEL metrics from Core works', async (t) => { + let resolveCapturedRequest = (_req: http2.Http2ServerRequest) => undefined as void; + const capturedRequest = new Promise((r) => (resolveCapturedRequest = r)); + try { + await withFakeGrpcServer(async (port: number) => { + Runtime.install({ + telemetryOptions: { + metrics: { + otel: { + url: `http://127.0.0.1:${port}`, + headers: { + 'x-test-header': 'test-value', + }, + metricsExportInterval: 10, + }, + }, + }, + }); + + const localEnv = await TestWorkflowEnvironment.createLocal(); + try { + const worker = await Worker.create({ + connection: localEnv.nativeConnection, + workflowsPath: require.resolve('./workflows'), + taskQueue: 'test-otel', + }); + const client = new WorkflowClient({ + connection: localEnv.connection, + }); + await worker.runUntil(async () => { + await client.execute(workflows.successString, { + taskQueue: 'test-otel', + workflowId: uuid4(), + }); + const req = await Promise.race([ + capturedRequest, + await new Promise((resolve) => setTimeout(() => resolve(undefined), 2000)), + ]); + t.truthy(req); + t.is(req?.url, '/opentelemetry.proto.collector.metrics.v1.MetricsService/Export'); + t.is(req?.headers['x-test-header'], 'test-value'); + }); + } finally { + await localEnv.teardown(); + } + }, resolveCapturedRequest); + } finally { + // Cleanup the runtime so that it doesn't interfere with other tests + await Runtime._instance?.shutdown(); + } +}); + +test.serial('Exporting OTEL metrics using OTLP/HTTP from Core works', async (t) => { + let resolveCapturedRequest = (_req: http.IncomingMessage) => undefined as void; + const capturedRequest = new Promise((r) => (resolveCapturedRequest = r)); + try { + await withHttpServer(async (port: number) => { + Runtime.install({ + telemetryOptions: { + metrics: { + otel: { + url: `http://127.0.0.1:${port}/v1/metrics`, + http: true, + headers: { + 'x-test-header': 'test-value', + }, + metricsExportInterval: 10, + }, + }, + }, + }); + + const localEnv = await TestWorkflowEnvironment.createLocal(); + try { + const worker = await Worker.create({ + connection: localEnv.nativeConnection, + workflowsPath: require.resolve('./workflows'), + taskQueue: 'test-otel', + }); + const client = new WorkflowClient({ + connection: localEnv.connection, + }); + await worker.runUntil(async () => { + await client.execute(workflows.successString, { + taskQueue: 'test-otel', + workflowId: uuid4(), + }); + const req = await Promise.race([ + capturedRequest, + await new Promise((resolve) => setTimeout(() => resolve(undefined), 2000)), + ]); + t.truthy(req); + t.is(req?.url, '/v1/metrics'); + t.is(req?.headers['x-test-header'], 'test-value'); + }); + } finally { + await localEnv.teardown(); + } + }, resolveCapturedRequest); + } finally { + // Cleanup the runtime so that it doesn't interfere with other tests + await Runtime._instance?.shutdown(); + } +}); diff --git a/packages/test/src/test-prometheus.ts b/packages/test/src/test-runtime-prometheus.ts similarity index 100% rename from packages/test/src/test-prometheus.ts rename to packages/test/src/test-runtime-prometheus.ts diff --git a/packages/worker/src/index.ts b/packages/worker/src/index.ts index e8a72da9b..87f9a35d3 100644 --- a/packages/worker/src/index.ts +++ b/packages/worker/src/index.ts @@ -22,6 +22,7 @@ export { export * from './interceptors'; export { DefaultLogger, LogEntry, LogLevel, LogMetadata, LogTimestamp, Logger } from './logger'; export { History, Runtime } from './runtime'; +export { MetricsBuffer, MetricsBufferOptions, BufferedMetricUpdate } from './runtime-metrics'; export { RuntimeOptions, makeTelemetryFilterString, diff --git a/packages/worker/src/runtime-metrics.ts b/packages/worker/src/runtime-metrics.ts index bc9a7f0ea..cfb5aa070 100644 --- a/packages/worker/src/runtime-metrics.ts +++ b/packages/worker/src/runtime-metrics.ts @@ -1,4 +1,6 @@ import { + IllegalStateError, + Metric, MetricCounter, MetricGauge, MetricHistogram, @@ -7,7 +9,18 @@ import { NumericMetricValueType, } from '@temporalio/common'; import { native } from '@temporalio/core-bridge'; +import type { Runtime } from './runtime'; +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Metric Meter (aka Custom Metrics) +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * An implementation of the {@link MetricMeter} interface that pushes emitted metrics through + * the bridge, to be collected by whatever exporter is configured on the Core Runtime. + * + * @internal + */ export class RuntimeMetricMeter implements MetricMeter { public constructor(protected runtime: native.Runtime) {} @@ -59,6 +72,9 @@ export class RuntimeMetricMeter implements MetricMeter { } class RuntimeMetricCounter implements MetricCounter { + public readonly kind = 'counter'; + public readonly valueType = 'int'; + public constructor( private readonly native: native.MetricCounter, public readonly name: string, @@ -80,6 +96,7 @@ class RuntimeMetricCounter implements MetricCounter { } class RuntimeMetricHistogram implements MetricHistogram { + public readonly kind = 'histogram'; public readonly valueType = 'int'; public constructor( @@ -103,6 +120,7 @@ class RuntimeMetricHistogram implements MetricHistogram { } class RuntimeMetricHistogramF64 implements MetricHistogram { + public readonly kind = 'histogram'; public readonly valueType = 'float'; public constructor( @@ -126,6 +144,7 @@ class RuntimeMetricHistogramF64 implements MetricHistogram { } class RuntimeMetricGauge implements MetricGauge { + public readonly kind = 'gauge'; public readonly valueType = 'int'; public constructor( @@ -149,6 +168,7 @@ class RuntimeMetricGauge implements MetricGauge { } class RuntimeMetricGaugeF64 implements MetricGauge { + public readonly kind = 'gauge'; public readonly valueType = 'float'; public constructor( @@ -170,3 +190,175 @@ class RuntimeMetricGaugeF64 implements MetricGauge { throw new Error('withTags is not supported directly on RuntimeMetricGaugeF64'); } } + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Buffered Metrics (aka lang-side metrics exporter) +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * A buffer that can be set on {@link RuntimeOptions.telemetry.metricsExporter} to record + * metrics instead of ignoring/exporting them. + * + * It is important that the buffer size is set to a high number and that `retrieveUpdates` is + * called regularly to drain the buffer. If the buffer is full, metric updates will be dropped + * and an error will be logged. + * + * @experimental Buffered metrics is an experimental feature. APIs may be subject to change. + */ +export class MetricsBuffer { + public readonly maxBufferSize: number; + public readonly useSecondsForDurations: boolean; + + private runtime: Runtime | undefined = undefined; + private pendingUpdates: BufferedMetricUpdate[] | undefined = undefined; + + public constructor(options: MetricsBufferOptions = {}) { + this.maxBufferSize = options.maxBufferSize ?? 10000; + this.useSecondsForDurations = options.useSecondsForDurations ?? false; + } + + /** + * Bind the MetricsBuffer to the given runtime. + * + * @internal + * @hidden + */ + bind(runtime: Runtime): MetricsBuffer { + if (this.runtime !== undefined) { + throw new IllegalStateError('MetricsBuffer already bound to a runtime'); + } + this.runtime = runtime; + return this; + } + + /** + * Unbind the MetricsBuffer from the given runtime. + * + * @internal + * @hidden + */ + unbind(runtime: Runtime): void { + if (this.runtime !== undefined) { + if (this.runtime !== runtime) throw new IllegalStateError('MetricsBuffer is bound to a different runtime'); + + try { + // We proactively drain buffered metrics from the native side, and keep them in the + // pendingUpdates buffer until the user code calls retrieveUpdates(). Without this, + // we would lose metric events on runtime shutdown. + this.retrieveUpdatesInternal(); + } finally { + this.runtime = undefined; + } + } + } + + /** + * Retrieve buffered metric updates. + * + * This method drains the metrics buffer and returns all metric events that have accumulated + * since the last call to this method. This method should be called regularly when using + * buffered metrics to prevent buffer overflow. + * + * @returns Array of buffered metric updates, each containing the metric metadata, + * current value, and attributes + * @experimental Buffered metrics is an experimental feature. APIs may be subject to change. + */ + public retrieveUpdates(): ArrayIterator { + this.retrieveUpdatesInternal(); + + const updates = this.pendingUpdates ?? []; + this.pendingUpdates = undefined; + + // We return an iterator instead of an array in case we should, at some point in the future, + // need to apply per item transformation. Copying to an array would obviously be possible, the + // buffered metric array might be large, so avoiding the extra array allocation makes sense. + return updates.values(); + } + + /** + * Fetch buffered metric updates from the native side, storing them in the pendingUpdates buffer. + * + * @internal + * @hidden + */ + private retrieveUpdatesInternal(): void { + if (this.runtime === undefined) return; + try { + const updates = native.runtimeRetrieveBufferedMetrics(this.runtime.native); + if (updates.length > 0) { + if (this.pendingUpdates === undefined) { + this.pendingUpdates = updates; + } else { + this.pendingUpdates.push(...updates); + } + } + } catch (error) { + // Ignore errors on retrieving buffered metrics after the runtime has been shut down. + if (!(error instanceof IllegalStateError)) throw error; + } + } +} + +export interface MetricsBufferOptions { + /** + * Maximum number of metric events to buffer before dropping new events. + * + * The buffer accumulates metric updates from Core and should be drained regularly by calling + * {@link Runtime.retrieveBufferedMetrics}. If the buffer fills up, new metric updates will be + * dropped and an error will be logged. + * + * @default 10000 + */ + maxBufferSize?: number; + + /** + * If set to true, the exporter will use seconds for durations instead of milliseconds. + * + * @default false + */ + useSecondsForDurations?: boolean; +} + +/** + * A single update event on a metric, recorded by buffered metrics exporter. + * + * When the {@link Runtime} is configured to buffer metrics, user code must regularly call + * {@link MetricsBuffer.retrieveUpdates} to retrieve the buffered metric updates. Each update + * event will be represented as a single instance of this interface. + * + * @experimental Buffered metrics is an experimental feature. APIs may be subject to change. + */ +export interface BufferedMetricUpdate { + /** + * The metric being updated. + * + * For performance reasons, the SDK tries to re-use the same object across updates for the same + * metric. User code may take advantage of this, e.g. by attaching downstream metric references to + * as a supplementary property on the `Metric` object. Note that the SDK may sometimes miss + * deduplication opportunities, notably when a same metric is accessed from different execution + * contexts (e.g. from both activity code and workflow code). + */ + metric: Metric; + + /** + * Value for this update event. + * + * For counters this is a delta; for gauges and histograms this is the value itself. + */ + value: number; + + /** + * Attributes for this update event. + * + * For performance reasons, the SDK tries to re-use the same object across updates for the same + * attribute set. User code may take advantage of this, e.g. by attaching downstream attribute + * sets references as a supplementary, _non-enumerable_ property on the `MetricTags` object. Make + * sure however not to add, modify or delete any enumerable properties on the `MetricTags` object, + * as those changes would affect future update events using the same `MetricTags` object, as well + * as further events that extend that `MetricTags` object. + * + * Note that the SDK may miss deduplication opportunities, notably when a same set of attributes + * is recreated by the code emitting the metric updates. + */ + attributes: MetricTags; +} diff --git a/packages/worker/src/runtime-options.ts b/packages/worker/src/runtime-options.ts index 2d4a9cbc4..b178a4450 100644 --- a/packages/worker/src/runtime-options.ts +++ b/packages/worker/src/runtime-options.ts @@ -3,6 +3,7 @@ import { Logger, LogLevel } from '@temporalio/common'; import { Duration, msToNumber } from '@temporalio/common/lib/time'; import { DefaultLogger } from './logger'; import { NativeLogCollector } from './runtime-logger'; +import { MetricsBuffer } from './runtime-metrics'; /** * Options used to create a Temporal Runtime. @@ -214,6 +215,8 @@ export type MetricsExporterConfig = { /** * Tags to add to all metrics emitted by the worker. + * + * Note that this is not supported when the metrics are buffered. */ globalTags?: Record; @@ -223,7 +226,7 @@ export type MetricsExporterConfig = { * @default true */ attachServiceName?: boolean; -} & (PrometheusMetricsExporter | OtelCollectorExporter); +} & (PrometheusMetricsExporter | OtelCollectorExporter | BufferedMetricsExporter); /** * OpenTelemetry Collector options for exporting metrics or traces @@ -359,6 +362,15 @@ export interface PrometheusMetricsExporter { }; } +/** + * Buffered metrics exporter options + * + * @experimental Buffered metrics is an experimental feature. APIs may be subject to change. + */ +export interface BufferedMetricsExporter { + buffer: MetricsBuffer; +} + // Compile Options //////////////////////////////////////////////////////////////////////////////// /** @@ -369,6 +381,7 @@ export interface CompiledRuntimeOptions { shutdownSignals: NodeJS.Signals[]; runtimeOptions: native.RuntimeOptions; logger: Logger; + metricsBuffer: MetricsBuffer | undefined; } export function compileOptions(options: RuntimeOptions): CompiledRuntimeOptions { @@ -409,9 +422,16 @@ export function compileOptions(options: RuntimeOptions): CompiledRuntimeOptions histogramBucketOverrides: metrics.otel.histogramBucketOverrides ?? {}, globalTags: metrics.globalTags ?? {}, } satisfies native.MetricExporterOptions) - : null, + : metrics && isBufferedMetricsExporter(metrics) + ? ({ + type: 'buffer', + maxBufferSize: metrics.buffer.maxBufferSize ?? 10000, + useSecondsForDurations: metrics.buffer.useSecondsForDurations ?? false, + } satisfies native.MetricExporterOptions) + : null, workerHeartbeatIntervalMillis: heartbeatMillis === 0 ? null : heartbeatMillis, }, + metricsBuffer: metrics && isBufferedMetricsExporter(metrics) ? metrics.buffer : undefined, }; } @@ -490,6 +510,10 @@ function isPrometheusMetricsExporter(metrics: MetricsExporterConfig): metrics is return 'prometheus' in metrics && typeof metrics.prometheus === 'object'; } +function isBufferedMetricsExporter(metrics: MetricsExporterConfig): metrics is BufferedMetricsExporter { + return 'buffer' in metrics && typeof metrics.buffer === 'object'; +} + function isForwardingLogger(options: LogExporterConfig): boolean { return 'forward' in options && typeof options.forward === 'object'; } diff --git a/packages/worker/src/runtime.ts b/packages/worker/src/runtime.ts index e98227e68..d44a8ed82 100644 --- a/packages/worker/src/runtime.ts +++ b/packages/worker/src/runtime.ts @@ -8,7 +8,7 @@ import { temporal } from '@temporalio/proto'; import { History } from '@temporalio/common/lib/proto-utils'; import { MetricMeterWithComposedTags } from '@temporalio/common/lib/metrics'; import { isFlushableLogger } from './logger'; -import { RuntimeMetricMeter } from './runtime-metrics'; +import { RuntimeMetricMeter, MetricsBuffer } from './runtime-metrics'; import { toNativeClientOptions, NativeConnectionOptions } from './connection-options'; import { byteArrayToBuffer, toMB } from './utils'; import { CompiledRuntimeOptions, compileOptions, RuntimeOptions } from './runtime-options'; @@ -28,6 +28,13 @@ export class Runtime { /** The metric meter associated with this runtime. */ public readonly metricMeter: MetricMeter; + /** + * The metrics buffer associated with this runtime, if buffered metrics are enabled. + * + * @experimental Buffered metrics is an experimental feature. APIs may be subject to change. + */ + public readonly metricsBuffer: MetricsBuffer | undefined; + /** Track the number of pending creation calls into the tokio runtime to prevent shut down */ protected pendingCreations = 0; /** Track the registered native objects to automatically shutdown when all have been deregistered */ @@ -50,6 +57,7 @@ export class Runtime { public readonly options: CompiledRuntimeOptions ) { this.logger = options.logger; + this.metricsBuffer = options.metricsBuffer?.bind(this); this.metricMeter = options.runtimeOptions.metricsExporter ? MetricMeterWithComposedTags.compose(new RuntimeMetricMeter(this.native), {}, true) : noopMetricMeter; @@ -277,6 +285,10 @@ export class Runtime { try { if (Runtime._instance === this) delete Runtime._instance; (this as any).metricMeter = noopMetricMeter; + if (this.metricsBuffer !== undefined) { + this.metricsBuffer.unbind(this); + (this as any).metricsBuffer = undefined; + } this.teardownShutdownHook(); // FIXME(JWH): I think we no longer need this, but will have to thoroughly validate. native.runtimeShutdown(this.native); diff --git a/packages/workflow/src/metrics.ts b/packages/workflow/src/metrics.ts index b13819263..cf38b74cc 100644 --- a/packages/workflow/src/metrics.ts +++ b/packages/workflow/src/metrics.ts @@ -48,6 +48,9 @@ class WorkflowMetricMeterImpl implements MetricMeter { } class WorkflowMetricCounter implements MetricCounter { + public readonly kind = 'counter'; + public readonly valueType = 'int'; + constructor( public readonly name: string, public readonly unit: string | undefined, @@ -70,6 +73,8 @@ class WorkflowMetricCounter implements MetricCounter { } class WorkflowMetricHistogram implements MetricHistogram { + public readonly kind = 'histogram'; + constructor( public readonly name: string, public readonly valueType: NumericMetricValueType, @@ -93,6 +98,8 @@ class WorkflowMetricHistogram implements MetricHistogram { } class WorkflowMetricGauge implements MetricGauge { + public readonly kind = 'gauge'; + constructor( public readonly name: string, public readonly valueType: NumericMetricValueType,