From 98b2c56acf46ceeae0c015559cd62534b9f21c0c Mon Sep 17 00:00:00 2001 From: "marco.mengelkoch" Date: Tue, 25 Aug 2026 20:59:26 +0200 Subject: [PATCH 01/12] update mq-bridge, add crud, fortunes --- frameworks/mq-bridge/Cargo.lock | 1418 +++++++----------- frameworks/mq-bridge/Cargo.toml | 23 +- frameworks/mq-bridge/Dockerfile | 3 + frameworks/mq-bridge/askama.toml | 5 + frameworks/mq-bridge/meta.json | 6 +- frameworks/mq-bridge/src/main.rs | 747 ++++++--- frameworks/mq-bridge/templates/fortunes.html | 10 + 7 files changed, 1141 insertions(+), 1071 deletions(-) create mode 100644 frameworks/mq-bridge/askama.toml create mode 100644 frameworks/mq-bridge/templates/fortunes.html diff --git a/frameworks/mq-bridge/Cargo.lock b/frameworks/mq-bridge/Cargo.lock index 443cfb502..4f5763eb4 100644 --- a/frameworks/mq-bridge/Cargo.lock +++ b/frameworks/mq-bridge/Cargo.lock @@ -27,9 +27,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "amq-protocol" -version = "10.6.2" +version = "10.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eab68e8836c5812a01b34c5364d28db50bf686b442e902d9d93e4472318d86e" +checksum = "b63f30a81ad95c7a278080be6d993d5b3e971d93e1b00bd894067220fc756804" dependencies = [ "amq-protocol-tcp", "amq-protocol-types", @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "amq-protocol-tcp" -version = "10.6.2" +version = "10.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8689f976dbd9864922f4f53e01ad2b43700ed3eb1bb5667b260522f291434dae" +checksum = "2b1bcecdd743111f05c26294d26b887ba6b2e4789c27515aa48f0fe32066e96c" dependencies = [ "amq-protocol-uri", "async-rs", @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "amq-protocol-types" -version = "10.6.2" +version = "10.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27894e9e57d07f701251aeee3d2ab3d7d114bc830bf722d6626027eb55f3b222" +checksum = "8a268a50e97bd5d52292a8b96636f6436215def6f3d128fb8218318f5feb4c33" dependencies = [ "cookie-factory", "nom 8.0.0", @@ -66,9 +66,9 @@ dependencies = [ [[package]] name = "amq-protocol-uri" -version = "10.6.2" +version = "10.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64fd5ca63f1b8cba2309aaec8595483c36f3a671225d5ab9fe8265adb9213514" +checksum = "8a34581b010818ef3da6b5a853e94f6438b3903914baba77a15f7fb2c7ad8958" dependencies = [ "amq-protocol-types", "percent-encoding", @@ -77,19 +77,72 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arc-swap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" dependencies = [ "rustversion", ] +[[package]] +name = "askama" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf825125edd887a019d0a3a837dcc5499a68b0d034cc3eb594070c3e18addc" +dependencies = [ + "askama_macros", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1c7065972a130eafa84215f21352ae15b4a7393da48c1f5e103904490736738" +dependencies = [ + "askama_parser", + "basic-toml", + "glob", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn 2.0.119", +] + +[[package]] +name = "askama_macros" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e23b1d2c4bd39a41971f6124cef4cc6fd0540913ecb90919b69ab3bbe44ae1a" +dependencies = [ + "askama_derive", +] + +[[package]] +name = "askama_parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7db09fde9143e7ac4513358fb32ee32847125b63b18ea715afd487956da715da" +dependencies = [ + "rustc-hash", + "serde", + "serde_derive", + "unicode-ident", + "winnow", +] + [[package]] name = "asn1-rs" version = "0.7.2" @@ -114,7 +167,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] @@ -126,7 +179,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -217,13 +270,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] @@ -249,9 +302,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" dependencies = [ "aws-lc-sys", "zeroize", @@ -259,14 +312,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.41.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" dependencies = [ "cc", "cmake", "dunce", "fs_extra", + "pkg-config", ] [[package]] @@ -284,17 +338,32 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "base64ct" version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" dependencies = [ "serde_core", ] @@ -308,6 +377,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block-padding" version = "0.3.3" @@ -319,9 +397,9 @@ dependencies = [ [[package]] name = "blocking" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" +checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" dependencies = [ "async-channel", "async-task", @@ -344,9 +422,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" dependencies = [ "serde", ] @@ -362,9 +440,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.64" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "jobserver", @@ -380,13 +458,13 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "rand_core 0.10.1", + "rand_core", ] [[package]] @@ -395,7 +473,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "inout", ] @@ -408,13 +486,19 @@ dependencies = [ "cc", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "cms" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b77c319abfd5219629c45c34c89ba945ed3c5e49fcde9d16b6c3885f118a730" dependencies = [ - "const-oid", + "const-oid 0.9.6", "der", "spki", "x509-cert", @@ -422,9 +506,9 @@ dependencies = [ [[package]] name = "combine" -version = "4.6.7" +version = "4.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" dependencies = [ "bytes", "memchr", @@ -445,6 +529,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "cookie-factory" version = "0.3.3" @@ -512,9 +602,9 @@ checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "8498c871161e1742aaa9d52551b2d6ebdd4c3d45a3be423e3728f33b955be550" dependencies = [ "cfg-if", ] @@ -527,36 +617,36 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +checksum = "803d13fb3b09d88be9f4dbc29062c66b19bf7170867ceb746d2a8689bf6c7a26" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crypto-common" @@ -568,11 +658,43 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + +[[package]] +name = "dashmap" +version = "6.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" [[package]] name = "der" @@ -580,7 +702,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid", + "const-oid 0.9.6", "der_derive", "flagset", "pem-rfc7468", @@ -609,7 +731,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -633,21 +755,32 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", + "block-buffer 0.10.4", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid 0.10.2", + "crypto-common 0.2.2", + "ctutils", +] + [[package]] name = "displaydoc" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] @@ -664,9 +797,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "either" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" dependencies = [ "serde", ] @@ -689,22 +822,20 @@ dependencies = [ [[package]] name = "etcetera" -version = "0.8.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96" dependencies = [ "cfg-if", - "home", - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] name = "event-listener" -version = "5.4.1" +version = "5.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" dependencies = [ - "concurrent-queue", "parking", "pin-project-lite", ] @@ -721,24 +852,24 @@ dependencies = [ [[package]] name = "fast-uuid-v7" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07a7bb9c4e64a101eeec4ff43c3974178e3dd2bff832fc2c2d6edeaa14c449e5" +checksum = "dc759201eb9b09178fb2174087a451d19fd46a8b8b4f5f6103de83b9f5949f52" dependencies = [ - "rand 0.9.4", + "rand", ] [[package]] name = "fastrand" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" [[package]] name = "flagset" @@ -756,17 +887,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" -dependencies = [ - "futures-core", - "futures-sink", - "spin", -] - [[package]] name = "flume" version = "0.12.0" @@ -786,9 +906,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "form_urlencoded" @@ -807,9 +927,9 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "futures" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -822,9 +942,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -832,15 +952,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -860,9 +980,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-lite" @@ -879,13 +999,13 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] @@ -901,21 +1021,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -951,35 +1071,27 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", - "r-efi 5.3.0", - "wasip2", + "r-efi", + "rand_core", ] [[package]] -name = "getrandom" -version = "0.4.2" +name = "glob" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" -dependencies = [ - "cfg-if", - "libc", - "r-efi 6.0.0", - "rand_core 0.10.1", - "wasip2", - "wasip3", -] +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "h2" -version = "0.4.14" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" dependencies = [ "atomic-waker", "bytes", @@ -996,9 +1108,15 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", @@ -1013,11 +1131,11 @@ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "hashlink" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.16.1", ] [[package]] @@ -1048,7 +1166,7 @@ dependencies = [ "idna", "ipnet", "jni", - "rand 0.10.1", + "rand", "thiserror", "tinyvec", "tokio", @@ -1068,7 +1186,7 @@ dependencies = [ "jni", "once_cell", "prefix-trie", - "rand 0.10.1", + "rand", "ring", "thiserror", "tinyvec", @@ -1093,7 +1211,7 @@ dependencies = [ "ndk-context", "once_cell", "parking_lot", - "rand 0.10.1", + "rand", "resolv-conf", "smallvec", "system-configuration", @@ -1104,11 +1222,11 @@ dependencies = [ [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ - "hmac", + "hmac 0.13.0", ] [[package]] @@ -1117,23 +1235,23 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] -name = "home" -version = "0.5.12" +name = "hmac" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "windows-sys 0.61.2", + "digest 0.11.3", ] [[package]] name = "http" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -1141,9 +1259,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -1151,9 +1269,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -1167,13 +1285,15 @@ name = "httparena-mqbridge" version = "0.1.0" dependencies = [ "anyhow", + "askama", "bytes", + "dashmap", "flate2", + "mimalloc", "mq-bridge", "rustls", "serde", "serde_json", - "sqlx", "tokio", ] @@ -1189,11 +1309,20 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" dependencies = [ "atomic-waker", "bytes", @@ -1250,9 +1379,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" dependencies = [ "displaydoc", "potential_utf", @@ -1264,9 +1393,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" dependencies = [ "displaydoc", "litemap", @@ -1277,9 +1406,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1291,16 +1420,17 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" dependencies = [ + "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", @@ -1311,15 +1441,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" [[package]] name = "icu_provider" -version = "2.2.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", @@ -1330,12 +1460,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "idna" version = "1.1.0" @@ -1365,8 +1489,6 @@ checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", "hashbrown 0.17.1", - "serde", - "serde_core", ] [[package]] @@ -1394,9 +1516,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" dependencies = [ "serde", ] @@ -1434,7 +1556,7 @@ dependencies = [ "quote", "rustc_version", "simd_cesu8", - "syn", + "syn 2.0.119", ] [[package]] @@ -1453,24 +1575,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.102" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ "cfg-if", "futures-util", @@ -1489,7 +1611,7 @@ dependencies = [ "backon", "cfg-if", "event-listener", - "flume 0.12.0", + "flume", "futures-core", "futures-io", "tracing", @@ -1500,38 +1622,20 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" - -[[package]] -name = "libm" -version = "0.2.16" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] -name = "libredox" -version = "0.1.17" +name = "libmimalloc-sys" +version = "0.1.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" +checksum = "6a45a52f43e1c16f667ccfe4dd8c85b7f7c204fd5e3bf46c5b0db9a5c3c0b8e9" dependencies = [ - "bitflags", - "libc", - "plain", - "redox_syscall 0.8.1", + "cc", ] [[package]] @@ -1540,15 +1644,16 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ + "cc", "pkg-config", "vcpkg", ] [[package]] name = "litemap" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "lock_api" @@ -1561,25 +1666,43 @@ dependencies = [ [[package]] name = "log" -version = "0.4.32" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "lz4_flex" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" +checksum = "ecbdfe44b1bd960b68170b417450a628c43f7cf56bb3c5317e61cb230ee7f226" +dependencies = [ + "twox-hash", +] [[package]] name = "md-5" -version = "0.10.6" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" dependencies = [ "cfg-if", - "digest", + "digest 0.11.3", ] [[package]] name = "memchr" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "mimalloc" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d4139bb28d14ad1facf21d5eb8825051b326e172d216b39f6d31df53cc97862" +dependencies = [ + "libmimalloc-sys", +] [[package]] name = "minimal-lexical" @@ -1599,9 +1722,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", @@ -1610,9 +1733,9 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.15" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957228ad12042ee839f93c8f257b62b4c0ab5eaae1d4fa60de53b27c9d7c5046" +checksum = "4293f18e7567a1caf3c584855554377025c65e0aa445344d04171f5ad63d19b9" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -1627,14 +1750,14 @@ dependencies = [ [[package]] name = "mq-bridge" -version = "0.2.21" -source = "git+https://github.com/marcomq/mq-bridge?tag=v0.2.21#a47a8bd9320444072a9768161f7f1503f087fdfb" +version = "0.4.7" +source = "git+https://github.com/marcomq/mq-bridge?tag=v0.4.7#366ac4e5fe0ded589a00c7203045dab9c90d0391" dependencies = [ "anyhow", "arc-swap", "async-channel", "async-trait", - "base64", + "base64 0.23.1", "bytes", "fast-uuid-v7", "flate2", @@ -1646,19 +1769,25 @@ dependencies = [ "hyper-rustls", "hyper-util", "lapin", + "lz4_flex", "once_cell", - "rand 0.10.1", + "rand", "rmp-serde", "rustls", "rustls-pemfile", "serde", "serde_json", + "sha2 0.11.0", + "sqlx", "thiserror", "tokio", "tokio-rustls", + "tokio-util", "tracing", + "url", "uuid", - "webpki-roots 1.0.7", + "webpki-roots", + "zstd", ] [[package]] @@ -1688,28 +1817,12 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-bigint-dig" -version = "0.8.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ - "lazy_static", - "libm", "num-integer", - "num-iter", "num-traits", - "rand 0.8.6", - "smallvec", - "zeroize", ] [[package]] @@ -1720,21 +1833,10 @@ checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ - "autocfg", - "num-integer", "num-traits", ] @@ -1745,7 +1847,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -1779,19 +1880,19 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffb9bf5222606eb712d3bb30e01bc9420545b00859970897e70c682353a034f2" dependencies = [ - "base64", + "base64 0.22.1", "cbc", "cms", "der", "des", "hex", - "hmac", + "hmac 0.12.1", "pkcs12", "pkcs5", - "rand 0.10.1", + "rand", "rc2", - "sha1", - "sha2", + "sha1 0.10.7", + "sha2 0.10.9", "thiserror", "x509-parser", ] @@ -1820,7 +1921,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link", ] @@ -1831,8 +1932,8 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest", - "hmac", + "digest 0.10.7", + "hmac 0.12.1", ] [[package]] @@ -1867,17 +1968,6 @@ dependencies = [ "futures-io", ] -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - [[package]] name = "pkcs12" version = "0.1.0" @@ -1885,9 +1975,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "695b3df3d3cc1015f12d70235e35b6b79befc5fa7a9b95b951eab1dd07c9efc2" dependencies = [ "cms", - "const-oid", + "const-oid 0.9.6", "der", - "digest", + "digest 0.10.7", "spki", "x509-cert", "zeroize", @@ -1904,43 +1994,27 @@ dependencies = [ "der", "pbkdf2", "scrypt", - "sha2", - "spki", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", + "sha2 0.10.9", "spki", ] [[package]] name = "pkg-config" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" - -[[package]] -name = "plain" -version = "0.2.3" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "potential_utf" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ "zerovec", ] @@ -1951,15 +2025,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - [[package]] name = "prefix-trie" version = "0.8.4" @@ -1971,40 +2036,24 @@ dependencies = [ "num-traits", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - [[package]] name = "r-efi" version = "6.0.0" @@ -2013,72 +2062,13 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.5", -] - -[[package]] -name = "rand" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" -dependencies = [ - "chacha20", - "getrandom 0.4.2", - "rand_core 0.10.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", + "chacha20", + "getrandom 0.4.3", + "rand_core", ] [[package]] @@ -2105,15 +2095,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "redox_syscall" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7" -dependencies = [ - "bitflags", -] - [[package]] name = "resolv-conf" version = "0.7.6" @@ -2154,24 +2135,10 @@ dependencies = [ ] [[package]] -name = "rsa" -version = "0.9.10" +name = "rustc-hash" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" -dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "signature", - "spki", - "subtle", - "zeroize", -] +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -2193,9 +2160,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ "aws-lc-rs", "log", @@ -2209,9 +2176,9 @@ dependencies = [ [[package]] name = "rustls-connector" -version = "0.23.6" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7664e32b0ffbec386bdf1d7cbca51a89551a90d3278f135186cd6cb3cfa889c" +checksum = "1babecfcc65b139b812e74bcc7f9ec7b4e00db659fd42d99567b7e77f0c714c6" dependencies = [ "futures-io", "futures-rustls", @@ -2246,9 +2213,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ "zeroize", ] @@ -2282,9 +2249,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "aws-lc-rs", "ring", @@ -2294,15 +2261,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "salsa20" @@ -2345,7 +2306,7 @@ checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" dependencies = [ "pbkdf2", "salsa20", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -2379,9 +2340,9 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -2389,29 +2350,29 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -2421,26 +2382,25 @@ dependencies = [ ] [[package]] -name = "serde_urlencoded" -version = "0.7.1" +name = "sha1" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", ] [[package]] name = "sha1" -version = "0.10.6" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", - "digest", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -2451,7 +2411,18 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -2470,27 +2441,17 @@ dependencies = [ "libc", ] -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest", - "rand_core 0.6.4", -] - [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] name = "simd_cesu8" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" dependencies = [ "rustc_version", "simdutf8", @@ -2519,9 +2480,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.61.2", @@ -2529,9 +2490,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] @@ -2548,9 +2509,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +checksum = "378620ccc25c62c89d8be1c819e76a88d59bdcc3304733330788948e619bfd71" dependencies = [ "sqlx-core", "sqlx-macros", @@ -2561,12 +2522,13 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +checksum = "05b44e85bf579a8eeb4ceaa77a3a523baf2bf0e9bac7e40f405d537b5d2d5ccb" dependencies = [ - "base64", + "base64 0.22.1", "bytes", + "cfg-if", "crc", "crossbeam-queue", "either", @@ -2575,114 +2537,98 @@ dependencies = [ "futures-intrusive", "futures-io", "futures-util", - "hashbrown 0.15.5", + "hashbrown 0.16.1", "hashlink", "indexmap", "log", "memchr", - "once_cell", "percent-encoding", "rustls", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "thiserror", "tokio", "tokio-stream", "tracing", "url", - "webpki-roots 0.26.11", + "webpki-roots", ] [[package]] name = "sqlx-macros" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +checksum = "bd2b84f2bc39a5705ef27ec785a11c934a41bbd4a24941e257927cddc26b60bf" dependencies = [ "proc-macro2", "quote", "sqlx-core", "sqlx-macros-core", - "syn", + "syn 2.0.119", ] [[package]] name = "sqlx-macros-core" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +checksum = "fb8d96de5fdc85a5c4ec813432b523ec637e80ba98f046555f75f7908ddac7c3" dependencies = [ + "cfg-if", "dotenvy", "either", "heck", "hex", - "once_cell", "proc-macro2", "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "sqlx-core", "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn", + "syn 2.0.119", + "thiserror", "tokio", "url", ] [[package]] name = "sqlx-mysql" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +checksum = "90b8020fe17c5f2c245bfa2505d7ef59c5604839527c740266ad2214acebea27" dependencies = [ - "atoi", - "base64", "bitflags", "byteorder", "bytes", "crc", - "digest", + "digest 0.11.3", "dotenvy", "either", - "futures-channel", "futures-core", - "futures-io", "futures-util", "generic-array", - "hex", - "hkdf", - "hmac", - "itoa", "log", - "md-5", - "memchr", - "once_cell", "percent-encoding", - "rand 0.8.6", - "rsa", "serde", - "sha1", - "sha2", - "smallvec", + "sha1 0.11.0", + "sha2 0.11.0", "sqlx-core", - "stringprep", "thiserror", "tracing", - "whoami", ] [[package]] name = "sqlx-postgres" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +checksum = "87a2bdd6e83f6b3ea525ca9fee568030508b58355a43d0b2c1674d5f79dcd65e" dependencies = [ "atoi", - "base64", + "base64 0.22.1", "bitflags", "byteorder", "crc", @@ -2693,17 +2639,15 @@ dependencies = [ "futures-util", "hex", "hkdf", - "hmac", - "home", + "hmac 0.13.0", "itoa", "log", "md-5", "memchr", - "once_cell", - "rand 0.8.6", + "rand", "serde", "serde_json", - "sha2", + "sha2 0.11.0", "smallvec", "sqlx-core", "stringprep", @@ -2714,12 +2658,13 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +checksum = "488e99c397a62007e4229aec669a179816339afc6d2620ca6fa420dbee2e982c" dependencies = [ "atoi", - "flume 0.11.1", + "flume", + "form_urlencoded", "futures-channel", "futures-core", "futures-executor", @@ -2729,7 +2674,6 @@ dependencies = [ "log", "percent-encoding", "serde", - "serde_urlencoded", "sqlx-core", "thiserror", "tracing", @@ -2761,9 +2705,20 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" dependencies = [ "proc-macro2", "quote", @@ -2778,7 +2733,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2823,29 +2778,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] name = "time" -version = "0.3.49" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711a53c2d47bbd818258c498c8dbfe186a2526c631495cfe7e078567f86b8469" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", "num-conv", @@ -2863,9 +2818,9 @@ checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.29" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c652a3727a9cbb9a02f707f530b618ce00d0ccd762009c8c23bd191df3c17d" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" dependencies = [ "num-conv", "time-core", @@ -2873,9 +2828,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", "zerovec", @@ -2883,9 +2838,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" dependencies = [ "tinyvec_macros", ] @@ -2898,9 +2853,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.3" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", @@ -2914,13 +2869,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] @@ -2935,9 +2890,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" dependencies = [ "futures-core", "pin-project-lite", @@ -2946,13 +2901,14 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-sink", + "libc", "pin-project-lite", "tokio", ] @@ -2983,7 +2939,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -3001,6 +2957,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "twox-hash" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8464ec13c3691491391d9fce00f6416c9a48e46972f72d7865688be2080192c9" + [[package]] name = "typenum" version = "1.20.1" @@ -3034,12 +2996,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "untrusted" version = "0.9.0" @@ -3066,11 +3022,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.23.3" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" +checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "wasm-bindgen", ] @@ -3112,35 +3068,11 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasip2" -version = "1.0.4+wasi-0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", -] - -[[package]] -name = "wasite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" - [[package]] name = "wasm-bindgen" -version = "0.2.125" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -3151,9 +3083,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.125" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3161,96 +3093,49 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.125" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.125" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", -] - [[package]] name = "webpki-root-certs" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" dependencies = [ "rustls-pki-types", ] [[package]] name = "webpki-roots" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" -dependencies = [ - "webpki-roots 1.0.7", -] - -[[package]] -name = "webpki-roots" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" dependencies = [ "rustls-pki-types", ] [[package]] name = "whoami" -version = "1.6.1" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" -dependencies = [ - "libredox", - "wasite", -] +checksum = "626c4bac6755d76ffc12cb01b2eac751db1996b9e0041de9aa02c8c211ddc82c" [[package]] name = "widestring" @@ -3302,22 +3187,13 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -3329,67 +3205,34 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -3402,48 +3245,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -3451,104 +3270,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" +name = "winnow" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", + "memchr", ] [[package]] name = "writeable" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] name = "x509-cert" @@ -3556,7 +3290,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94" dependencies = [ - "const-oid", + "const-oid 0.9.6", "der", "spki", ] @@ -3597,30 +3331,10 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] -[[package]] -name = "zerocopy" -version = "0.8.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "zerofrom" version = "0.1.8" @@ -3638,7 +3352,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", "synstructure", ] @@ -3650,9 +3364,9 @@ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", "yoke", @@ -3661,9 +3375,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ "yoke", "zerofrom", @@ -3672,17 +3386,45 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.16+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/frameworks/mq-bridge/Cargo.toml b/frameworks/mq-bridge/Cargo.toml index bd1095c84..9a022e696 100644 --- a/frameworks/mq-bridge/Cargo.toml +++ b/frameworks/mq-bridge/Cargo.toml @@ -6,8 +6,7 @@ # in via a pinned git reference. hyper-util's auto connection builder serves both # HTTP/1.1 and HTTP/2 prior-knowledge (h2c) on the plaintext port; the same # builder runs behind the TLS listener, where the library now advertises ALPN -# `h2`. Tracks the `dev` branch to benchmark unreleased code; pin to a `tag` or -# exact `rev` for reproducible benchmarks. +# `h2`. Pinned to a released `tag` so benchmarks are reproducible. [package] name = "httparena-mqbridge" version = "0.1.0" @@ -19,8 +18,10 @@ name = "httparena-mqbridge" path = "src/main.rs" [dependencies] -# `rustls-ring` selects the ring crypto provider for the TLS (8443) listener. -mq-bridge = { git = "https://github.com/marcomq/mq-bridge", tag = "v0.2.21", default-features = false, features = ["http", "rustls-ring"] } +# `rustls-ring` selects the ring crypto provider for the TLS (8443) listener; +# `sqlx` pulls in the library's re-exported sqlx (`mq_bridge::sqlx`) for the +# async-db and crud profiles, keeping one sqlx version in the graph. +mq-bridge = { git = "https://github.com/marcomq/mq-bridge", tag = "v0.4.7", default-features = false, features = ["http", "rustls-ring", "sqlx"] } tokio = { version = "1", features = ["macros", "rt-multi-thread", "fs"] } serde = { version = "1", features = ["derive"] } serde_json = "1" @@ -28,14 +29,20 @@ anyhow = "1" # Zero-copy bodies + pre-gzip for the in-memory static/json caches. bytes = "1" flate2 = "1" +# Sharded concurrent map behind the crud profile's cache-aside read path. +dashmap = "6" +# Template engine for the fortunes profile: compile-time, auto-escaping, and +# the template lives in its own file, as the profile's standard-mode rules require. +askama = "0.16" +# Process-wide allocator. Every request allocates (JSON body, message metadata), +# and the default glibc malloc is the weakest part of that path under this much +# concurrency. +mimalloc = { version = "0.1", default-features = false } # Install the process-default rustls crypto provider before the TLS endpoint. rustls = { version = "0.23", default-features = false, features = ["ring"] } -# Async-db profile: own a Postgres pool in the handler (HttpArena seeds an -# `items` table and passes DATABASE_URL). -sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio-rustls", "postgres", "json"] } [profile.release] opt-level = 3 -lto = "thin" +lto = "fat" codegen-units = 1 panic = "abort" diff --git a/frameworks/mq-bridge/Dockerfile b/frameworks/mq-bridge/Dockerfile index 4b50e9ebd..4d38eaa61 100644 --- a/frameworks/mq-bridge/Dockerfile +++ b/frameworks/mq-bridge/Dockerfile @@ -6,6 +6,9 @@ COPY Cargo.toml . RUN mkdir src && echo "fn main() {}" > src/main.rs && \ cargo build --release && \ rm -rf src target/release/httparena-mqbridge* target/release/deps/httparena_mqbridge* +# askama compiles `templates/` at build time, steered by askama.toml. +COPY askama.toml . +COPY templates ./templates COPY src ./src RUN RUSTFLAGS="-C target-cpu=native" cargo build --release diff --git a/frameworks/mq-bridge/askama.toml b/frameworks/mq-bridge/askama.toml new file mode 100644 index 000000000..fd9ebc197 --- /dev/null +++ b/frameworks/mq-bridge/askama.toml @@ -0,0 +1,5 @@ +# Askama's built-in HTML escaper emits numeric entities (`<`), but the +# fortunes validator greps for the named form. See `NamedHtmlEscaper`. +[[escaper]] +path = "crate::NamedHtmlEscaper" +extensions = ["html"] diff --git a/frameworks/mq-bridge/meta.json b/frameworks/mq-bridge/meta.json index f7297601a..f9aa0558f 100644 --- a/frameworks/mq-bridge/meta.json +++ b/frameworks/mq-bridge/meta.json @@ -5,12 +5,12 @@ "mode": "standard", "completeness": { "routing": false, - "middleware": false, + "middleware": true, "request": true, "response": true }, "engine": "mq-bridge", - "description": "mq-bridge async message-bridging library run as an HTTP server. A single catch-all http->response route dispatches on request metadata and replies through mq-bridge's inline-response fast path; hyper-util's auto connection builder serves HTTP/1.1 and HTTP/2 prior-knowledge (h2c) on the cleartext port (8080) and HTTP/2-over-TLS (ALPN h2) on 8443. Postgres via sqlx for async-db, dataset read from /data/dataset.json, static assets from /data/static, gzip negotiated by the library's Accept-Encoding-gated response compression.", + "description": "mq-bridge async message-bridging library run as an HTTP server. A single catch-all http->response route dispatches on request metadata and replies through mq-bridge's inline-response fast path; hyper-util's auto connection builder serves HTTP/1.1 and HTTP/2 prior-knowledge (h2c) on the cleartext port (8080) and HTTP/2-over-TLS (ALPN h2) on 8443. Postgres via the library's re-exported sqlx for async-db and crud (in-process cache-aside, 200 ms TTL), fortunes rendered per request with the Askama template engine, dataset read from /data/dataset.json, static assets from /data/static, response compression negotiated per request by the library from Accept-Encoding (zstd > gzip > lz4).", "repo": "https://github.com/marcomq/mq-bridge", "enabled": true, "tests": [ @@ -22,6 +22,8 @@ "json-tls", "upload", "async-db", + "crud", + "fortunes", "api-4", "api-16", "baseline-h2", diff --git a/frameworks/mq-bridge/src/main.rs b/frameworks/mq-bridge/src/main.rs index bc3a1a419..e58dcb8d7 100644 --- a/frameworks/mq-bridge/src/main.rs +++ b/frameworks/mq-bridge/src/main.rs @@ -1,60 +1,62 @@ -//! HttpArena core server for mq-bridge (Rust). +//! HttpArena entry for mq-bridge (Rust). //! -//! Serves the HTTP/1.1 + cleartext-HTTP/2 (h2c) profiles on `0.0.0.0:8080` -//! through a single catch-all `http -> response` route that dispatches on the -//! request's `http_method` / `http_path` / `http_query` metadata. hyper-util's -//! auto connection builder (used by mq-bridge's HTTP server) negotiates both -//! HTTP/1.1 and HTTP/2 prior-knowledge on the plaintext port, so one binary -//! covers the cleartext profiles. +//! One catch-all `http -> response` route per listener, dispatching on the +//! request's `http_method` / `http_path` / `http_query` metadata and replying +//! through mq-bridge's inline-response fast path. //! -//! Endpoints (per HttpArena's reference contract) -//! ---------------------------------------------- -//! * `GET /pipeline` -> `ok` (baseline/pipelined/limited-conn) -//! * `GET /baseline11?a=&b=` -> `a+b` (baseline) -//! * `POST /baseline11?a=&b=` + body int -> `a+b+body` -//! * `GET /baseline2?a=&b=` -> `a+b` (baseline-h2/-h2c) -//! * `GET /json/{count}?m=` -> processed dataset JSON (json/json-comp/json-tls/json-h2c) -//! * `POST /upload` + body -> received byte count (upload) -//! * `GET /async-db?min=&max=&limit=` -> Postgres `items` rows (async-db) -//! * `GET /static/{file}` -> file from /data/static (static) +//! | Endpoint | Reply | Profiles | +//! |---|---|---| +//! | `GET /pipeline` | `ok` | baseline, pipelined, limited-conn | +//! | `GET /baseline11?a=&b=` | `a+b` | baseline | +//! | `POST /baseline11?a=&b=` + body | `a+b+body` | baseline | +//! | `GET /baseline2?a=&b=` | `a+b` | baseline-h2, baseline-h2c | +//! | `GET /json/{count}?m=` | processed dataset | json, json-comp, json-tls, json-h2c | +//! | `POST /upload` + body | byte count | upload | +//! | `GET /async-db?min=&max=&limit=` | `items` rows | async-db | +//! | `GET /static/{file}` | cached asset | static, static-h2 | +//! | `GET /crud/items?category=&page=&limit=` | paginated list | crud | +//! | `GET /crud/items/{id}` | cached item | crud | +//! | `POST /crud/items` + JSON | 201 + upserted item | crud | +//! | `PUT /crud/items/{id}` + JSON | updated item | crud | +//! | `GET /fortunes` | rendered HTML table | fortunes | //! -//! Harness-provided inputs: the dataset is read from `/data/dataset.json` -//! (`DATASET_PATH` overrides), static assets from `/data/static` -//! (`STATIC_DIR`), and Postgres from `DATABASE_URL`. Missing DB is non-fatal: -//! `/async-db` then returns an empty result so the cleartext profiles still run. +//! Listeners: 8080 HTTP/1.1 + h2c (auto), 8082 h2c-only, 8443 h2-over-TLS, +//! 8081 HTTP/1.1-over-TLS. TLS ports bind only when certs are mounted. //! -//! `json-comp` is handled by mq-bridge's response compression -//! (`compression_enabled`): bodies above the threshold are gzip-encoded when the -//! client advertises `Accept-Encoding: gzip`, and sent identity otherwise — so -//! the same `/json` handler serves both the `json` and `json-comp` profiles. -//! -//! `json-tls` reuses that same `/json` handler over HTTP/1.1 + TLS on `8081` -//! (ALPN `http/1.1` only), alongside the HTTP/2-over-TLS listener on `8443`. A -//! cleartext HTTP/2-only (`h2c`) listener on `8082` serves the `baseline-h2c` and -//! `json-h2c` profiles from the same handlers. +//! Harness inputs: `DATASET_PATH`, `STATIC_DIR`, `DATABASE_URL`, +//! `DATABASE_MAX_CONN`. A missing database is non-fatal — the DB-backed +//! endpoints degrade rather than blocking the cleartext profiles. + +#[global_allocator] +static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; +use askama::Template; use bytes::Bytes; +use dashmap::DashMap; use mq_bridge::endpoints::http::{guess_content_type, HttpRequestExt, HTTP_STATUS_CODE}; use mq_bridge::models::{Endpoint, EndpointType, HttpConfig, HttpServerProtocol, TlsConfig}; +use mq_bridge::sqlx::postgres::{PgPoolOptions, PgRow}; +use mq_bridge::sqlx::types::Json; +use mq_bridge::sqlx::{self, PgPool, Row}; use mq_bridge::{CanonicalMessage, Handled, HandlerError, Route}; use serde::{Deserialize, Serialize}; -use sqlx::postgres::PgPoolOptions; -use sqlx::{PgPool, Row}; +use serde_json::value::RawValue; use std::collections::HashMap; use std::path::{Component, Path, PathBuf}; use std::sync::Arc; +use std::time::{Duration, Instant}; const SERVER: &str = "mq-bridge"; -// ---------- dataset (json profile) ---------- +// ---------- models ---------- -#[derive(Deserialize, Clone)] +#[derive(Deserialize)] struct Rating { score: i64, count: i64, } -#[derive(Deserialize, Clone)] +#[derive(Deserialize)] struct DatasetItem { id: i64, name: String, @@ -66,6 +68,12 @@ struct DatasetItem { rating: Rating, } +#[derive(Serialize)] +struct RatingOut { + score: i64, + count: i64, +} + #[derive(Serialize)] struct ProcessedItem<'a> { id: i64, @@ -80,27 +88,69 @@ struct ProcessedItem<'a> { } #[derive(Serialize)] -struct RatingOut { - score: i64, - count: i64, +struct JsonResponse<'a> { + items: Vec>, + count: usize, } +/// One `items` row, borrowed from the sqlx row buffer for the duration of the +/// response. `/async-db` and `/crud` specify the same item shape. #[derive(Serialize)] -struct JsonResponse<'a> { - items: Vec>, +struct DbItem<'a> { + id: i32, + name: &'a str, + category: &'a str, + price: i32, + quantity: i32, + active: bool, + tags: &'a RawValue, + rating: RatingOut, +} + +#[derive(Serialize)] +struct DbResponse<'a> { count: usize, + items: Vec>, +} + +#[derive(Serialize)] +struct CrudListResponse<'a> { + items: Vec>, + total: usize, + page: i64, + limit: i64, +} + +#[derive(Deserialize)] +struct CrudCreate { + id: i32, + name: String, + category: String, + price: i32, + quantity: i32, +} + +/// Optional fields so a partial `PUT` leaves the rest of the row alone; the SQL +/// COALESCEs each bind against the current value. +#[derive(Deserialize)] +struct CrudUpdate { + name: Option, + category: Option, + price: Option, + quantity: Option, } struct AppState { dataset: Vec, - /// Static assets read once at startup, with a pre-gzipped variant ready to - /// serve — no per-request filesystem read or allocation. static_cache: HashMap, + crud_cache: CrudCache, pool: Option, } -/// A response body cached in both identity and gzip form. The gzip variant is -/// only kept when it actually shrinks the body. +// ---------- caches ---------- + +/// A static asset in identity and gzip form, built once at startup. The gzip +/// variant is kept only when it actually shrinks the body. struct CachedBody { plain: Bytes, gzip: Option, @@ -111,56 +161,77 @@ impl CachedBody { fn build(bytes: Vec, content_type: &'static str) -> Self { let plain = Bytes::from(bytes); let compressed = gzip(&plain); - let gzip = (compressed.len() < plain.len()).then_some(compressed); Self { + gzip: (compressed.len() < plain.len()).then_some(compressed), plain, - gzip, content_type, } } - /// Build a reply, serving the pre-gzipped variant when the client accepts it. - /// `content-encoding: gzip` is set on the reply; the mq-bridge HTTP layer - /// honors it and skips its own compression pass. - fn into_message(&self, want_gzip: bool) -> CanonicalMessage { - let (body, encoding) = match (want_gzip, &self.gzip) { - (true, Some(g)) => (g.clone(), Some("gzip")), - _ => (self.plain.clone(), None), - }; - let mut msg = CanonicalMessage::new_bytes(body, None) - .with_metadata_kv("content-type", self.content_type) - .with_metadata_kv("Server", SERVER); - if let Some(encoding) = encoding { - msg = msg.with_metadata_kv("content-encoding", encoding); + /// Setting `content-encoding` tells the mq-bridge HTTP layer the body is + /// already encoded, so it skips its own compression pass. + fn to_message(&self, want_gzip: bool) -> CanonicalMessage { + match (want_gzip, &self.gzip) { + (true, Some(g)) => reply_bytes(g.clone(), self.content_type) + .with_metadata_kv("content-encoding", "gzip"), + _ => reply_bytes(self.plain.clone(), self.content_type), } - msg } } +/// Cache-aside store behind `GET /crud/items/{id}`, holding the rendered body +/// so a hit skips both the query and the serialization. +/// +/// Expiry is lazy and absolute: an entry is tested only when read, and the next +/// miss overwrites it. Nothing sweeps or refreshes in the background — which is +/// what the profile asks for — and the key space is bounded by the id range. +#[derive(Default)] +struct CrudCache { + entries: DashMap, +} + +const CRUD_TTL: Duration = Duration::from_millis(200); + +impl CrudCache { + fn get(&self, id: i32) -> Option { + let entry = self.entries.get(&id)?; + let (stored_at, body) = entry.value(); + (stored_at.elapsed() < CRUD_TTL).then(|| body.clone()) + } + + fn put(&self, id: i32, body: Bytes) { + self.entries.insert(id, (Instant::now(), body)); + } + + fn invalidate(&self, id: i32) { + self.entries.remove(&id); + } +} + +/// Runs once per file at startup, never on the request path, so it pays for the +/// maximum level: the smaller body is pure win on every subsequent request. fn gzip(data: &[u8]) -> Bytes { use flate2::{write::GzEncoder, Compression}; use std::io::Write; - let mut encoder = GzEncoder::new(Vec::new(), Compression::fast()); + let mut encoder = GzEncoder::new(Vec::new(), Compression::best()); encoder.write_all(data).expect("gzip write"); Bytes::from(encoder.finish().expect("gzip finish")) } fn load_static(dir: &Path) -> HashMap { - let mut cache = HashMap::new(); let Ok(entries) = std::fs::read_dir(dir) else { - return cache; + return HashMap::new(); }; - for entry in entries.flatten() { - if entry.file_type().map(|ft| !ft.is_file()).unwrap_or(true) { - continue; - } - let name = entry.file_name().to_string_lossy().into_owned(); - if let Ok(bytes) = std::fs::read(entry.path()) { + entries + .flatten() + .filter(|e| e.file_type().is_ok_and(|ft| ft.is_file())) + .filter_map(|e| { + let name = e.file_name().to_string_lossy().into_owned(); + let bytes = std::fs::read(e.path()).ok()?; let content_type = guess_content_type(&name); - cache.insert(name, CachedBody::build(bytes, content_type)); - } - } - cache + Some((name, CachedBody::build(bytes, content_type))) + }) + .collect() } fn load_dataset() -> Vec { @@ -171,31 +242,42 @@ fn load_dataset() -> Vec { .unwrap_or_default() } -// ---------- helpers ---------- +// ---------- replies ---------- -fn reply(body: Vec, content_type: &str) -> CanonicalMessage { - CanonicalMessage::new(body, None) +fn reply_bytes(body: Bytes, content_type: &str) -> CanonicalMessage { + CanonicalMessage::new_bytes(body, None) .with_metadata_kv("content-type", content_type) .with_metadata_kv("Server", SERVER) } fn text(body: String) -> CanonicalMessage { - reply(body.into_bytes(), "text/plain") + reply_bytes(Bytes::from(body), "text/plain") } fn json(body: Vec) -> CanonicalMessage { - reply(body, "application/json") + reply_bytes(Bytes::from(body), "application/json") +} + +fn status(code: u16, body: &str) -> CanonicalMessage { + text(body.to_string()).with_metadata_kv(HTTP_STATUS_CODE, code.to_string()) } -fn status(status: u16, body: &str) -> CanonicalMessage { - text(body.to_string()).with_metadata_kv(HTTP_STATUS_CODE, status.to_string()) +fn unavailable() -> CanonicalMessage { + status(503, "Service Unavailable") } -// ---------- handlers ---------- +fn not_found() -> CanonicalMessage { + status(404, "Not Found") +} + +// ---------- json profile ---------- -fn build_json(dataset: &[DatasetItem], count: usize, m: i64) -> Vec { - let count = count.min(dataset.len()); - let items: Vec = dataset[..count] +/// Serialized fresh per request — no response caching. The library compresses +/// it per request when the client advertises an encoding (see `make_http`), so +/// `json` and `json-comp` measure real serialization and compression work. +fn serve_json(state: &AppState, count: usize, m: i64) -> CanonicalMessage { + let count = count.min(state.dataset.len()); + let items: Vec = state.dataset[..count] .iter() .map(|d| ProcessedItem { id: d.id, @@ -212,170 +294,371 @@ fn build_json(dataset: &[DatasetItem], count: usize, m: i64) -> Vec { total: d.price * d.quantity * m, }) .collect(); - serde_json::to_vec(&JsonResponse { count, items }).unwrap_or_default() + json(serde_json::to_vec(&JsonResponse { count, items }).unwrap_or_default()) +} + +// ---------- database ---------- + +macro_rules! item_cols { + () => { + "id, name, category, price, quantity, active, tags, rating_score, rating_count" + }; +} + +/// Borrows straight into the serializer: no `serde_json::Value` tree, and +/// `tags` (jsonb) is re-emitted verbatim instead of being parsed into a +/// `Vec` and re-serialized. Positional access skips sqlx's per-field +/// name lookup; every query below selects `item_cols!()` in this order. +fn row_to_item(row: &PgRow) -> DbItem<'_> { + DbItem { + id: row.get(0), + name: row.get(1), + category: row.get(2), + price: row.get(3), + quantity: row.get(4), + active: row.get(5), + tags: row.get::, _>(6).0, + rating: RatingOut { + score: row.get::(7) as i64, + count: row.get::(8) as i64, + }, + } +} + +async fn async_db(state: &AppState, msg: &CanonicalMessage) -> CanonicalMessage { + const SQL: &str = concat!( + "SELECT ", + item_cols!(), + " FROM items WHERE price BETWEEN $1 AND $2 LIMIT $3" + ); + const EMPTY: &[u8] = br#"{"items":[],"count":0}"#; + + let Some(pool) = state.pool.as_ref() else { + return json(EMPTY.to_vec()); + }; + let rows = sqlx::query(SQL) + .bind(msg.query_int("min").unwrap_or(10) as i32) + .bind(msg.query_int("max").unwrap_or(50) as i32) + .bind(msg.query_int("limit").unwrap_or(50).clamp(1, 50)) + .fetch_all(pool) + .await; + let Ok(rows) = rows else { + return json(EMPTY.to_vec()); + }; + + let items: Vec = rows.iter().map(row_to_item).collect(); + json( + serde_json::to_vec(&DbResponse { + count: items.len(), + items, + }) + .unwrap_or_default(), + ) } -async fn async_db(pool: &PgPool, msg: &CanonicalMessage) -> CanonicalMessage { - let min = msg.query_int("min").unwrap_or(10) as i32; - let max = msg.query_int("max").unwrap_or(50) as i32; - let limit = msg.query_int("limit").unwrap_or(50).clamp(1, 50); +// ---------- crud profile ---------- +// +// The harness also offers a Redis sidecar, but that is for multi-process +// runtimes; this server is one tokio runtime sharing a heap, so the cache-aside +// above is in-process. - let rows = sqlx::query( - "SELECT id, name, category, price, quantity, active, tags, rating_score, rating_count \ - FROM items WHERE price BETWEEN $1 AND $2 LIMIT $3", +const CRUD_ITEM: &str = "/crud/items/"; + +fn crud_id(path: &str) -> Option { + path[CRUD_ITEM.len()..].parse().ok() +} + +/// One query, no `SELECT COUNT(*)`: `total` reports the rows in this response, +/// which is what the profile asks for — the full-filter count was dropped from +/// the spec because it dominated Postgres CPU under concurrent writes. +async fn crud_list(state: &AppState, msg: &CanonicalMessage) -> CanonicalMessage { + const SQL: &str = concat!( + "SELECT ", + item_cols!(), + " FROM items WHERE category = $1 ORDER BY id LIMIT $2 OFFSET $3" + ); + + let Some(pool) = state.pool.as_ref() else { + return unavailable(); + }; + let page = msg.query_int("page").unwrap_or(1).max(1); + let limit = msg.query_int("limit").unwrap_or(10).clamp(1, 50); + let rows = sqlx::query(SQL) + .bind(msg.query_param("category").unwrap_or("electronics")) + .bind(limit as i32) + .bind(((page - 1) * limit) as i32) + .fetch_all(pool) + .await + .unwrap_or_default(); + + let items: Vec = rows.iter().map(row_to_item).collect(); + json( + serde_json::to_vec(&CrudListResponse { + total: items.len(), + items, + page, + limit, + }) + .unwrap_or_default(), ) - .bind(min) - .bind(max) - .bind(limit) - .fetch_all(pool) - .await; - - let rows = match rows { - Ok(r) => r, - Err(_) => return json(br#"{"items":[],"count":0}"#.to_vec()), +} + +async fn crud_get(state: &AppState, id: i32) -> CanonicalMessage { + const SQL: &str = concat!("SELECT ", item_cols!(), " FROM items WHERE id = $1"); + + if let Some(body) = state.crud_cache.get(id) { + return reply_bytes(body, "application/json").with_metadata_kv("X-Cache", "HIT"); + } + let Some(pool) = state.pool.as_ref() else { + return unavailable(); + }; + let row = match sqlx::query(SQL).bind(id).fetch_optional(pool).await { + Ok(Some(row)) => row, + Ok(None) => return not_found(), + Err(_) => return status(500, "Internal Server Error"), + }; + let body = Bytes::from(serde_json::to_vec(&row_to_item(&row)).unwrap_or_default()); + state.crud_cache.put(id, body.clone()); + reply_bytes(body, "application/json").with_metadata_kv("X-Cache", "MISS") +} + +/// `active` / `tags` / `rating_*` are NOT NULL with no default and the create +/// body carries none of them, so a new row seeds them; a conflict updates only +/// the four fields the body actually sends. +async fn crud_create(state: &AppState, payload: &[u8]) -> CanonicalMessage { + const SQL: &str = concat!( + "INSERT INTO items (", + item_cols!(), + ") \ + VALUES ($1, $2, $3, $4, $5, true, '[]'::jsonb, 0, 0) \ + ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, category = EXCLUDED.category, \ + price = EXCLUDED.price, quantity = EXCLUDED.quantity RETURNING ", + item_cols!() + ); + + let Some(pool) = state.pool.as_ref() else { + return unavailable(); + }; + let Ok(item) = serde_json::from_slice::(payload) else { + return status(400, "Bad Request"); }; + let row = sqlx::query(SQL) + .bind(item.id) + .bind(&item.name) + .bind(&item.category) + .bind(item.price) + .bind(item.quantity) + .fetch_one(pool) + .await; + match row { + Ok(row) => { + // The upsert may have replaced a row someone already read. + state.crud_cache.invalidate(item.id); + json(serde_json::to_vec(&row_to_item(&row)).unwrap_or_default()) + .with_metadata_kv(HTTP_STATUS_CODE, "201") + } + Err(_) => status(500, "Internal Server Error"), + } +} + +async fn crud_update(state: &AppState, id: i32, payload: &[u8]) -> CanonicalMessage { + const SQL: &str = concat!( + "UPDATE items SET name = COALESCE($2, name), category = COALESCE($3, category), \ + price = COALESCE($4, price), quantity = COALESCE($5, quantity) \ + WHERE id = $1 RETURNING ", + item_cols!() + ); + + let Some(pool) = state.pool.as_ref() else { + return unavailable(); + }; + let Ok(update) = serde_json::from_slice::(payload) else { + return status(400, "Bad Request"); + }; + let row = sqlx::query(SQL) + .bind(id) + .bind(update.name.as_deref()) + .bind(update.category.as_deref()) + .bind(update.price) + .bind(update.quantity) + .fetch_optional(pool) + .await; + match row { + Ok(Some(row)) => { + state.crud_cache.invalidate(id); + json(serde_json::to_vec(&row_to_item(&row)).unwrap_or_default()) + } + Ok(None) => not_found(), + Err(_) => status(500, "Internal Server Error"), + } +} + +// ---------- fortunes profile ---------- + +/// Named-entity HTML escaper, selected for `.html` templates by `askama.toml`. +/// +/// Askama's built-in escaper emits numeric entities (`<`), but the profile's +/// validator greps the body for the literal `<script>`, so correctly +/// escaped output would still be rejected. +#[derive(Copy, Clone)] +pub struct NamedHtmlEscaper; + +impl askama::filters::Escaper for NamedHtmlEscaper { + fn write_escaped_str(&self, mut dest: W, s: &str) -> std::fmt::Result { + let mut last = 0; + for (i, b) in s.bytes().enumerate() { + let replacement = match b { + b'<' => "<", + b'>' => ">", + b'&' => "&", + b'"' => """, + b'\'' => "'", + _ => continue, + }; + dest.write_str(&s[last..i])?; + dest.write_str(replacement)?; + last = i + 1; + } + dest.write_str(&s[last..]) + } +} + +/// Borrowed from the sqlx rows, so rendering 201 rows allocates the page and +/// nothing else. The runtime row's `&'static str` coerces into the same slot. +struct Fortune<'a> { + id: i32, + message: &'a str, +} - let items: Vec = rows +#[derive(Template)] +#[template(path = "fortunes.html")] +struct FortunesTemplate<'a> { + fortunes: Vec>, +} + +/// Query, append the runtime row in memory, sort by ordinal byte order (never +/// locale-aware — that reorders per runtime), then render per request. +async fn fortunes(state: &AppState) -> CanonicalMessage { + let Some(pool) = state.pool.as_ref() else { + return unavailable(); + }; + let Ok(rows) = sqlx::query("SELECT id, message FROM fortune") + .fetch_all(pool) + .await + else { + return status(500, "Internal Server Error"); + }; + + let mut fortunes: Vec = rows .iter() - .map(|row| { - // Positional column access (by SELECT order) avoids sqlx's per-field - // name->ordinal lookup; columns match the query above. - serde_json::json!({ - "id": row.get::(0), - "name": row.get::<&str, _>(1), - "category": row.get::<&str, _>(2), - "price": row.get::(3), - "quantity": row.get::(4), - "active": row.get::(5), - "tags": row.get::(6), - "rating": { - "score": row.get::(7), - "count": row.get::(8), - } - }) + .map(|row| Fortune { + id: row.get(0), + message: row.get(1), }) .collect(); - let body = serde_json::json!({ "count": items.len(), "items": items }); - json(serde_json::to_vec(&body).unwrap_or_default()) + fortunes.push(Fortune { + id: 0, + message: "Additional fortune added at request time.", + }); + fortunes.sort_by(|a, b| a.message.as_bytes().cmp(b.message.as_bytes())); + + match (FortunesTemplate { fortunes }).render() { + Ok(html) => reply_bytes(Bytes::from(html), "text/html; charset=utf-8"), + Err(_) => status(500, "Internal Server Error"), + } } +// ---------- static ---------- + fn serve_static(state: &AppState, name: &str, want_gzip: bool) -> CanonicalMessage { - // Reject path traversal: the filename must be a single normal component. - let candidate = Path::new(name); - let mut comps = candidate.components(); + // Reject traversal: the filename must be a single normal component. + let mut comps = Path::new(name).components(); let safe = matches!(comps.next(), Some(Component::Normal(_))) && comps.next().is_none(); - if !safe || name.is_empty() { - return status(404, "Not Found"); + if !safe { + return not_found(); } match state.static_cache.get(name) { - Some(cached) => cached.into_message(want_gzip), - None => status(404, "Not Found"), + Some(cached) => cached.to_message(want_gzip), + None => not_found(), } } -/// Serve `/json/{count}?m=`, serializing the body fresh on every request (no -/// response caching). The library compresses it per request when the client -/// advertises `Accept-Encoding: gzip` (see `make_http`), so `json` and -/// `json-comp` measure real serialization + compression work. -fn serve_json(state: &AppState, count: usize, m: i64) -> CanonicalMessage { - json(build_json(&state.dataset, count, m)) -} +// ---------- dispatch ---------- async fn handle(state: Arc, msg: CanonicalMessage) -> Result { - let want_gzip = msg.accepts_gzip(); - let out = match (msg.http_method(), msg.http_path()) { ("GET", "/pipeline") => text("ok".to_string()), ("GET", "/baseline11") | ("GET", "/baseline2") => { - let sum = msg.query_int("a").unwrap_or(0) + msg.query_int("b").unwrap_or(0); - text(sum.to_string()) + text((msg.query_int("a").unwrap_or(0) + msg.query_int("b").unwrap_or(0)).to_string()) } ("POST", "/baseline11") => { - let mut sum = msg.query_int("a").unwrap_or(0) + msg.query_int("b").unwrap_or(0); - if let Ok(s) = std::str::from_utf8(&msg.payload) { - if let Ok(n) = s.trim().parse::() { - sum += n; - } - } + let body = std::str::from_utf8(&msg.payload) + .ok() + .and_then(|s| s.trim().parse::().ok()) + .unwrap_or(0); + let sum = msg.query_int("a").unwrap_or(0) + msg.query_int("b").unwrap_or(0) + body; text(sum.to_string()) } ("POST", "/upload") => text(msg.payload.len().to_string()), - ("GET", "/async-db") => match &state.pool { - Some(pool) => async_db(pool, &msg).await, - None => json(br#"{"items":[],"count":0}"#.to_vec()), + ("GET", "/async-db") => async_db(&state, &msg).await, + ("GET", "/fortunes") => fortunes(&state).await, + ("GET", "/crud/items") => crud_list(&state, &msg).await, + ("POST", "/crud/items") => crud_create(&state, &msg.payload).await, + ("GET", p) if p.starts_with(CRUD_ITEM) => match crud_id(p) { + Some(id) => crud_get(&state, id).await, + None => not_found(), + }, + ("PUT", p) if p.starts_with(CRUD_ITEM) => match crud_id(p) { + Some(id) => crud_update(&state, id, &msg.payload).await, + None => not_found(), }, ("GET", p) if p.starts_with("/json/") => { - let count: usize = p["/json/".len()..].parse().unwrap_or(0); - let m = msg.query_int("m").unwrap_or(1); - serve_json(&state, count, m) + let count = p["/json/".len()..].parse().unwrap_or(0); + serve_json(&state, count, msg.query_int("m").unwrap_or(1)) } ("GET", p) if p.starts_with("/static/") => { - serve_static(&state, &p["/static/".len()..], want_gzip) + serve_static(&state, &p["/static/".len()..], msg.accepts_gzip()) } - _ => status(404, "Not Found"), + _ => not_found(), }; - Ok(Handled::Publish(out)) } +// ---------- setup ---------- + #[tokio::main] async fn main() -> anyhow::Result<()> { - let listen = std::env::var("MQB_LISTEN").unwrap_or_else(|_| "0.0.0.0:8080".to_string()); - let static_dir = std::env::var("STATIC_DIR").unwrap_or_else(|_| "/data/static".to_string()); - - let pool = match std::env::var("DATABASE_URL") { - Ok(url) if !url.is_empty() => { - let max = std::env::var("DATABASE_MAX_CONN") - .ok() - .and_then(|v| v.parse().ok()) - .unwrap_or(256); - match PgPoolOptions::new().max_connections(max).connect(&url).await { - Ok(pool) => Some(pool), - Err(e) => { - eprintln!("Postgres connection failed ({e}); /async-db returns empty"); - None - } - } - } - _ => None, - }; - let state = Arc::new(AppState { dataset: load_dataset(), - static_cache: load_static(&PathBuf::from(static_dir)), - pool, + static_cache: load_static(&PathBuf::from( + std::env::var("STATIC_DIR").unwrap_or_else(|_| "/data/static".to_string()), + )), + crud_cache: CrudCache::default(), + pool: connect_pool().await, }); - // Plaintext HTTP/1.1 + h2c on 8080. - let plaintext = build_route(make_http(listen, None), state.clone()); - let mut handles = vec![plaintext.run("httparena").await?]; + let listen = env_addr("MQB_LISTEN", 8080); + let mut handles = vec![ + route(make_http(listen, None), &state) + .run("httparena") + .await?, + ]; - // HTTP/2 cleartext (prior-knowledge) on 8082 (baseline-h2c / json-h2c), using - // the same `/baseline2` and `/json` handlers. `Http2Only` makes the port - // refuse HTTP/1.1, satisfying the h2c-only anti-cheat (a dual-serving port is - // rejected). Cleartext, so no certs are needed. - let h2c_listen = std::env::var("MQB_H2C_LISTEN").unwrap_or_else(|_| "0.0.0.0:8082".to_string()); - let h2c = make_http(h2c_listen, None).with_server_protocol(HttpServerProtocol::Http2Only); - handles.push(build_route(h2c, state.clone()).run("httparena-h2c").await?); + // `Http2Only` makes 8082 refuse HTTP/1.1, satisfying the h2c-only + // anti-cheat — a dual-serving port is rejected. + let h2c = make_http(env_addr("MQB_H2C_LISTEN", 8082), None) + .with_server_protocol(HttpServerProtocol::Http2Only); + handles.push(route(h2c, &state).run("httparena-h2c").await?); - // TLS listeners, only when the harness has mounted certs — a local - // plaintext-only run still works. if let Some(tls) = tls_config() { - // HTTP/2 over TLS on 8443 (baseline-h2 / static-h2): ALPN advertises `h2`. - let tls_listen = - std::env::var("MQB_TLS_LISTEN").unwrap_or_else(|_| "0.0.0.0:8443".to_string()); - let tls_route = build_route(make_http(tls_listen, Some(tls.clone())), state.clone()); - handles.push(tls_route.run("httparena-tls").await?); - - // JSON over HTTP/1.1 + TLS on 8081 (json-tls): the same `/json` handler, - // but the port advertises ALPN `http/1.1` only so the wrk load generator - // negotiates HTTP/1.1 rather than upgrading to h2. - let h1tls_listen = - std::env::var("MQB_H1TLS_LISTEN").unwrap_or_else(|_| "0.0.0.0:8081".to_string()); - let h1tls = make_http(h1tls_listen, Some(tls)) + let h2 = make_http(env_addr("MQB_TLS_LISTEN", 8443), Some(tls.clone())); + handles.push(route(h2, &state).run("httparena-tls").await?); + + // ALPN `http/1.1` only, so the json-tls load generator negotiates + // HTTP/1.1 rather than upgrading to h2. + let h1 = make_http(env_addr("MQB_H1TLS_LISTEN", 8081), Some(tls)) .with_server_protocol(HttpServerProtocol::Http1Only); - let h1tls_route = build_route(h1tls, state.clone()); - handles.push(h1tls_route.run("httparena-json-tls").await?); + handles.push(route(h1, &state).run("httparena-json-tls").await?); } for handle in handles { @@ -384,10 +667,34 @@ async fn main() -> anyhow::Result<()> { Ok(()) } -/// Build the TLS config for the 8443 listener from `TLS_CERT` / `TLS_KEY`, -/// installing the process-default rustls crypto provider as a side effect. -/// Returns `None` (and logs) when the certs aren't present, so plaintext-only -/// runs are unaffected. +fn env_addr(var: &str, default_port: u16) -> String { + std::env::var(var).unwrap_or_else(|_| format!("0.0.0.0:{default_port}")) +} + +/// Pool size comes from `DATABASE_MAX_CONN`, as the async-db profile requires. +/// A failure is logged, not fatal: the DB-backed endpoints then degrade. +async fn connect_pool() -> Option { + let url = std::env::var("DATABASE_URL") + .ok() + .filter(|u| !u.is_empty())?; + let max = std::env::var("DATABASE_MAX_CONN") + .ok() + .and_then(|v| v.parse().ok()) + .unwrap_or(256); + match PgPoolOptions::new() + .max_connections(max) + .connect(&url) + .await + { + Ok(pool) => Some(pool), + Err(e) => { + eprintln!("Postgres connection failed ({e}); DB endpoints degrade"); + None + } + } +} + +/// `None` (and a log) when certs aren't mounted, so a plaintext-only run works. fn tls_config() -> Option { let cert = std::env::var("TLS_CERT").unwrap_or_else(|_| "/certs/server.crt".to_string()); let key = std::env::var("TLS_KEY").unwrap_or_else(|_| "/certs/server.key".to_string()); @@ -397,9 +704,7 @@ fn tls_config() -> Option { } // rustls needs a process-default crypto provider before any TLS endpoint. if let Err(provider) = rustls::crypto::ring::default_provider().install_default() { - eprintln!( - "rustls ring crypto provider was not installed; a process default is already set (attempted provider: {provider:?})" - ); + eprintln!("rustls ring provider not installed; a default is already set ({provider:?})"); } let mut tls = TlsConfig::new(); tls.required = true; @@ -408,17 +713,14 @@ fn tls_config() -> Option { Some(tls) } -/// Shared HTTP listener config; `tls` set => HTTPS (ALPN h2) on the TLS port. fn make_http(listen: String, tls: Option) -> HttpConfig { let mut http = HttpConfig::new(listen).with_inline_response_fast_path(true); http.concurrency_limit = Some(65_536); http.internal_buffer_size = Some(16_384); - // Static assets are pre-gzipped once at startup (see CachedBody) and the reply - // carries `content-encoding: gzip` when the client accepts it — the library - // honors that and skips re-compressing them. Dynamic `/json` responses are - // serialized fresh per request (no response caching) and compressed by the - // library's per-request gzip when the client advertises Accept-Encoding. - http.compression_enabled = true; + // The library negotiates the codec per request (zstd > gzip > lz4), so zstd + // is used whenever a client offers it. The HttpArena generators send only + // `Accept-Encoding: gzip, br`, so the measured path here is gzip. + http.compression_enabled = Some(true); http.compression_threshold_bytes = Some(256); if let Some(tls) = tls { http.tls = tls; @@ -426,12 +728,11 @@ fn make_http(listen: String, tls: Option) -> HttpConfig { http } -/// Builds the catch-all `http -> response` route bound to `http`, dispatching -/// every request through the shared `AppState` handler. -fn build_route(http: HttpConfig, state: Arc) -> Route { - let input = Endpoint::new(EndpointType::Http(http)); - let output = Endpoint::new_response(); - // The HTTP inline-response fast path (see `make_http`) handles each request - // directly, so the route's batch size is left at the library default. - Route::new(input, output).with_handler(move |msg| handle(state.clone(), msg)) +fn route(http: HttpConfig, state: &Arc) -> Route { + let state = state.clone(); + Route::new( + Endpoint::new(EndpointType::Http(http)), + Endpoint::new_response(), + ) + .with_handler(move |msg| handle(state.clone(), msg)) } diff --git a/frameworks/mq-bridge/templates/fortunes.html b/frameworks/mq-bridge/templates/fortunes.html new file mode 100644 index 000000000..f0b19c159 --- /dev/null +++ b/frameworks/mq-bridge/templates/fortunes.html @@ -0,0 +1,10 @@ + + +Fortunes + + + +{% for f in fortunes %} +{% endfor %}
idmessage
{{ f.id }}{{ f.message }}
+ + From 7712fe04dc3f63e21781c2054d9ce71250b9fa6a Mon Sep 17 00:00:00 2001 From: "marco.mengelkoch" Date: Tue, 25 Aug 2026 21:28:45 +0200 Subject: [PATCH 02/12] add static + static-tls --- frameworks/mq-bridge/meta.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frameworks/mq-bridge/meta.json b/frameworks/mq-bridge/meta.json index f9aa0558f..b04457712 100644 --- a/frameworks/mq-bridge/meta.json +++ b/frameworks/mq-bridge/meta.json @@ -21,6 +21,8 @@ "json-comp", "json-tls", "upload", + "static", + "static-tls", "async-db", "crud", "fortunes", From 75e14b6944fdd23a11428338661c17c2f393bc00 Mon Sep 17 00:00:00 2001 From: "marco.mengelkoch" Date: Tue, 25 Aug 2026 21:29:04 +0200 Subject: [PATCH 03/12] add static + static-tls --- frameworks/mq-bridge/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/mq-bridge/src/main.rs b/frameworks/mq-bridge/src/main.rs index e58dcb8d7..32bd841b9 100644 --- a/frameworks/mq-bridge/src/main.rs +++ b/frameworks/mq-bridge/src/main.rs @@ -13,7 +13,7 @@ //! | `GET /json/{count}?m=` | processed dataset | json, json-comp, json-tls, json-h2c | //! | `POST /upload` + body | byte count | upload | //! | `GET /async-db?min=&max=&limit=` | `items` rows | async-db | -//! | `GET /static/{file}` | cached asset | static, static-h2 | +//! | `GET /static/{file}` | cached asset | static, static-tls, static-h2 | //! | `GET /crud/items?category=&page=&limit=` | paginated list | crud | //! | `GET /crud/items/{id}` | cached item | crud | //! | `POST /crud/items` + JSON | 201 + upserted item | crud | From f7b4c4ae07a25af3079ac507f47f4c20778c2d7e Mon Sep 17 00:00:00 2001 From: "marco.mengelkoch" Date: Tue, 25 Aug 2026 22:01:40 +0200 Subject: [PATCH 04/12] fix static / static-tls --- frameworks/mq-bridge/Cargo.lock | 1 - frameworks/mq-bridge/Cargo.toml | 3 +- frameworks/mq-bridge/src/main.rs | 83 +++++++------------------------- 3 files changed, 19 insertions(+), 68 deletions(-) diff --git a/frameworks/mq-bridge/Cargo.lock b/frameworks/mq-bridge/Cargo.lock index 4f5763eb4..531d7e98b 100644 --- a/frameworks/mq-bridge/Cargo.lock +++ b/frameworks/mq-bridge/Cargo.lock @@ -1288,7 +1288,6 @@ dependencies = [ "askama", "bytes", "dashmap", - "flate2", "mimalloc", "mq-bridge", "rustls", diff --git a/frameworks/mq-bridge/Cargo.toml b/frameworks/mq-bridge/Cargo.toml index 9a022e696..5b861696c 100644 --- a/frameworks/mq-bridge/Cargo.toml +++ b/frameworks/mq-bridge/Cargo.toml @@ -26,9 +26,8 @@ tokio = { version = "1", features = ["macros", "rt-multi-thread", "fs"] } serde = { version = "1", features = ["derive"] } serde_json = "1" anyhow = "1" -# Zero-copy bodies + pre-gzip for the in-memory static/json caches. +# Zero-copy response bodies. bytes = "1" -flate2 = "1" # Sharded concurrent map behind the crud profile's cache-aside read path. dashmap = "6" # Template engine for the fortunes profile: compile-time, auto-escaping, and diff --git a/frameworks/mq-bridge/src/main.rs b/frameworks/mq-bridge/src/main.rs index 32bd841b9..a6cc82360 100644 --- a/frameworks/mq-bridge/src/main.rs +++ b/frameworks/mq-bridge/src/main.rs @@ -41,7 +41,6 @@ use mq_bridge::sqlx::{self, PgPool, Row}; use mq_bridge::{CanonicalMessage, Handled, HandlerError, Route}; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue; -use std::collections::HashMap; use std::path::{Component, Path, PathBuf}; use std::sync::Arc; use std::time::{Duration, Instant}; @@ -142,43 +141,13 @@ struct CrudUpdate { struct AppState { dataset: Vec, - static_cache: HashMap, + static_dir: PathBuf, crud_cache: CrudCache, pool: Option, } // ---------- caches ---------- -/// A static asset in identity and gzip form, built once at startup. The gzip -/// variant is kept only when it actually shrinks the body. -struct CachedBody { - plain: Bytes, - gzip: Option, - content_type: &'static str, -} - -impl CachedBody { - fn build(bytes: Vec, content_type: &'static str) -> Self { - let plain = Bytes::from(bytes); - let compressed = gzip(&plain); - Self { - gzip: (compressed.len() < plain.len()).then_some(compressed), - plain, - content_type, - } - } - - /// Setting `content-encoding` tells the mq-bridge HTTP layer the body is - /// already encoded, so it skips its own compression pass. - fn to_message(&self, want_gzip: bool) -> CanonicalMessage { - match (want_gzip, &self.gzip) { - (true, Some(g)) => reply_bytes(g.clone(), self.content_type) - .with_metadata_kv("content-encoding", "gzip"), - _ => reply_bytes(self.plain.clone(), self.content_type), - } - } -} - /// Cache-aside store behind `GET /crud/items/{id}`, holding the rendered body /// so a hit skips both the query and the serialization. /// @@ -208,32 +177,6 @@ impl CrudCache { } } -/// Runs once per file at startup, never on the request path, so it pays for the -/// maximum level: the smaller body is pure win on every subsequent request. -fn gzip(data: &[u8]) -> Bytes { - use flate2::{write::GzEncoder, Compression}; - use std::io::Write; - let mut encoder = GzEncoder::new(Vec::new(), Compression::best()); - encoder.write_all(data).expect("gzip write"); - Bytes::from(encoder.finish().expect("gzip finish")) -} - -fn load_static(dir: &Path) -> HashMap { - let Ok(entries) = std::fs::read_dir(dir) else { - return HashMap::new(); - }; - entries - .flatten() - .filter(|e| e.file_type().is_ok_and(|ft| ft.is_file())) - .filter_map(|e| { - let name = e.file_name().to_string_lossy().into_owned(); - let bytes = std::fs::read(e.path()).ok()?; - let content_type = guess_content_type(&name); - Some((name, CachedBody::build(bytes, content_type))) - }) - .collect() -} - fn load_dataset() -> Vec { let path = std::env::var("DATASET_PATH").unwrap_or_else(|_| "/data/dataset.json".to_string()); std::fs::read_to_string(&path) @@ -570,16 +513,26 @@ async fn fortunes(state: &AppState) -> CanonicalMessage { // ---------- static ---------- -fn serve_static(state: &AppState, name: &str, want_gzip: bool) -> CanonicalMessage { +async fn serve_static(state: &AppState, name: &str, want_gzip: bool) -> CanonicalMessage { // Reject traversal: the filename must be a single normal component. let mut comps = Path::new(name).components(); let safe = matches!(comps.next(), Some(Component::Normal(_))) && comps.next().is_none(); if !safe { return not_found(); } - match state.static_cache.get(name) { - Some(cached) => cached.to_message(want_gzip), - None => not_found(), + let path = state.static_dir.join(name); + let content_type = guess_content_type(name); + if want_gzip { + let mut gzip_path = path.as_os_str().to_os_string(); + gzip_path.push(".gz"); + if let Ok(bytes) = tokio::fs::read(gzip_path).await { + return reply_bytes(Bytes::from(bytes), content_type) + .with_metadata_kv("content-encoding", "gzip"); + } + } + match tokio::fs::read(path).await { + Ok(bytes) => reply_bytes(Bytes::from(bytes), content_type), + Err(_) => not_found(), } } @@ -617,7 +570,7 @@ async fn handle(state: Arc, msg: CanonicalMessage) -> Result { - serve_static(&state, &p["/static/".len()..], msg.accepts_gzip()) + serve_static(&state, &p["/static/".len()..], msg.accepts_gzip()).await } _ => not_found(), }; @@ -630,9 +583,9 @@ async fn handle(state: Arc, msg: CanonicalMessage) -> Result anyhow::Result<()> { let state = Arc::new(AppState { dataset: load_dataset(), - static_cache: load_static(&PathBuf::from( + static_dir: PathBuf::from( std::env::var("STATIC_DIR").unwrap_or_else(|_| "/data/static".to_string()), - )), + ), crud_cache: CrudCache::default(), pool: connect_pool().await, }); From 86e23f52418fcbc9d5aa2cf8628e87b748fde95e Mon Sep 17 00:00:00 2001 From: "marco.mengelkoch" Date: Wed, 26 Aug 2026 08:11:50 +0200 Subject: [PATCH 05/12] increase ttl to 1s --- frameworks/mq-bridge/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/mq-bridge/src/main.rs b/frameworks/mq-bridge/src/main.rs index a6cc82360..2c8e6c5ff 100644 --- a/frameworks/mq-bridge/src/main.rs +++ b/frameworks/mq-bridge/src/main.rs @@ -159,7 +159,7 @@ struct CrudCache { entries: DashMap, } -const CRUD_TTL: Duration = Duration::from_millis(200); +const CRUD_TTL: Duration = Duration::from_secs(1); impl CrudCache { fn get(&self, id: i32) -> Option { From 42faa8faaac785a5bf561d91a6f98fbf7aef9127 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Aug 2026 07:29:38 +0000 Subject: [PATCH 06/12] Benchmark results: mq-bridge [skip ci] --- site/data/frameworks.json | 4 +- site/data/results/mq-bridge.json | 561 ++++++++++++------- site/static/logs/crud/4096/mq-bridge.log | 0 site/static/logs/fortunes/1024/mq-bridge.log | 0 4 files changed, 359 insertions(+), 206 deletions(-) create mode 100644 site/static/logs/crud/4096/mq-bridge.log create mode 100644 site/static/logs/fortunes/1024/mq-bridge.log diff --git a/site/data/frameworks.json b/site/data/frameworks.json index bf3427d12..a0d312aaa 100644 --- a/site/data/frameworks.json +++ b/site/data/frameworks.json @@ -1111,14 +1111,14 @@ }, "mq-bridge": { "dir": "mq-bridge", - "description": "mq-bridge async message-bridging library run as an HTTP server. A single catch-all http->response route dispatches on request metadata and replies through mq-bridge's inline-response fast path; hyper-util's auto connection builder serves HTTP/1.1 and HTTP/2 prior-knowledge (h2c) on the cleartext port (8080) and HTTP/2-over-TLS (ALPN h2) on 8443. Postgres via sqlx for async-db, dataset read from /data/dataset.json, static assets from /data/static, gzip negotiated by the library's Accept-Encoding-gated response compression.", + "description": "mq-bridge async message-bridging library run as an HTTP server. A single catch-all http->response route dispatches on request metadata and replies through mq-bridge's inline-response fast path; hyper-util's auto connection builder serves HTTP/1.1 and HTTP/2 prior-knowledge (h2c) on the cleartext port (8080) and HTTP/2-over-TLS (ALPN h2) on 8443. Postgres via the library's re-exported sqlx for async-db and crud (in-process cache-aside, 200 ms TTL), fortunes rendered per request with the Askama template engine, dataset read from /data/dataset.json, static assets from /data/static, response compression negotiated per request by the library from Accept-Encoding (zstd > gzip > lz4).", "repo": "https://github.com/marcomq/mq-bridge", "type": "emerging", "engine": "mq-bridge", "mode": "standard", "completeness": { "routing": false, - "middleware": false, + "middleware": true, "request": true, "response": true }, diff --git a/site/data/results/mq-bridge.json b/site/data/results/mq-bridge.json index 9ecd5b806..bd0090889 100644 --- a/site/data/results/mq-bridge.json +++ b/site/data/results/mq-bridge.json @@ -4,71 +4,71 @@ "api-16-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 91454, - "avg_latency": "9.51ms", - "p99_latency": "36.20ms", - "cpu": "1482.6%", - "memory": "102MiB", + "rps": 168093, + "avg_latency": "4.16ms", + "p99_latency": "18.00ms", + "cpu": "1604.9%", + "memory": "134MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "466.12MB/s", - "input_bw": "5.15MB/s", - "reconnects": 274111, - "status_2xx": 1371815, + "bandwidth": "859.26MB/s", + "input_bw": "9.46MB/s", + "reconnects": 503943, + "status_2xx": 2521407, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_baseline": 513699, - "tpl_json": 515068, + "tpl_baseline": 945486, + "tpl_json": 945931, "tpl_db": 0, "tpl_upload": 0, "tpl_static": 0, - "tpl_async_db": 343048 + "tpl_async_db": 629990 }, "api-4-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 29538, - "avg_latency": "7.33ms", - "p99_latency": "24.70ms", - "cpu": "394.2%", - "memory": "46MiB", + "rps": 51760, + "avg_latency": "3.35ms", + "p99_latency": "12.40ms", + "cpu": "398.4%", + "memory": "67MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "150.54MB/s", - "input_bw": "1.66MB/s", - "reconnects": 88593, - "status_2xx": 443071, + "bandwidth": "264.60MB/s", + "input_bw": "2.91MB/s", + "reconnects": 155244, + "status_2xx": 776403, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "tpl_baseline": 165934, - "tpl_json": 166174, + "tpl_baseline": 291083, + "tpl_json": 291058, "tpl_db": 0, "tpl_upload": 0, "tpl_static": 0, - "tpl_async_db": 110963 + "tpl_async_db": 194262 }, "async-db-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 114746, - "avg_latency": "8.36ms", - "p99_latency": "11.20ms", - "cpu": "4705.5%", - "memory": "132MiB", + "rps": 138329, + "avg_latency": "6.85ms", + "p99_latency": "8.78ms", + "cpu": "3068.7%", + "memory": "284MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "445.64MB/s", - "input_bw": "7.66MB/s", - "reconnects": 45864, - "status_2xx": 1147461, + "bandwidth": "542.07MB/s", + "input_bw": "9.23MB/s", + "reconnects": 54998, + "status_2xx": 1383298, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -76,19 +76,19 @@ "baseline-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 1176223, - "avg_latency": "3.48ms", - "p99_latency": "6.85ms", - "cpu": "4448.1%", - "memory": "181MiB", + "rps": 1216437, + "avg_latency": "3.38ms", + "p99_latency": "6.54ms", + "cpu": "4162.0%", + "memory": "277MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "192.89MB/s", - "input_bw": "90.86MB/s", + "bandwidth": "199.48MB/s", + "input_bw": "93.97MB/s", "reconnects": 0, - "status_2xx": 5881116, + "status_2xx": 6082189, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -96,19 +96,19 @@ "baseline-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 1078632, - "avg_latency": "474us", - "p99_latency": "1.34ms", - "cpu": "3984.0%", - "memory": "98MiB", + "rps": 1142335, + "avg_latency": "447us", + "p99_latency": "1.29ms", + "cpu": "3568.8%", + "memory": "166MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "176.89MB/s", - "input_bw": "83.32MB/s", + "bandwidth": "187.33MB/s", + "input_bw": "88.24MB/s", "reconnects": 0, - "status_2xx": 5393162, + "status_2xx": 5711678, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -116,18 +116,18 @@ "baseline-h2-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 514296, - "avg_latency": "184.38ms", - "p99_latency": "600.98ms", - "cpu": "4417.1%", - "memory": "789MiB", + "rps": 626895, + "avg_latency": "151.49ms", + "p99_latency": "536.83ms", + "cpu": "5072.7%", + "memory": "795MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "26.09MB/s", + "bandwidth": "31.77MB/s", "reconnects": 0, - "status_2xx": 2602341, + "status_2xx": 3165824, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -135,18 +135,18 @@ "baseline-h2-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 542860, - "avg_latency": "46.38ms", - "p99_latency": "208.61ms", - "cpu": "4250.3%", - "memory": "293MiB", + "rps": 714077, + "avg_latency": "35.21ms", + "p99_latency": "144.68ms", + "cpu": "4992.7%", + "memory": "491MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "27.28MB/s", + "bandwidth": "36.07MB/s", "reconnects": 0, - "status_2xx": 2725162, + "status_2xx": 3591809, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -154,18 +154,18 @@ "baseline-h2c-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 500237, - "avg_latency": "196.13ms", - "p99_latency": "663.00ms", - "cpu": "4422.9%", - "memory": "830MiB", + "rps": 642012, + "avg_latency": "149.46ms", + "p99_latency": "581.43ms", + "cpu": "5210.3%", + "memory": "936MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "25.40MB/s", + "bandwidth": "32.75MB/s", "reconnects": 0, - "status_2xx": 2531200, + "status_2xx": 3261422, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -173,18 +173,18 @@ "baseline-h2c-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 564793, - "avg_latency": "44.45ms", - "p99_latency": "169.29ms", - "cpu": "4389.1%", - "memory": "261MiB", + "rps": 702590, + "avg_latency": "35.79ms", + "p99_latency": "147.97ms", + "cpu": "5092.4%", + "memory": "467MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "28.43MB/s", + "bandwidth": "35.52MB/s", "reconnects": 0, - "status_2xx": 2840912, + "status_2xx": 3534028, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -192,18 +192,38 @@ "baseline-h2c-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 450670, - "avg_latency": "743.95ms", - "p99_latency": "3.24s", - "cpu": "4569.9%", - "memory": "2.5GiB", + "rps": 554752, + "avg_latency": "603.61ms", + "p99_latency": "2.93s", + "cpu": "5278.9%", + "memory": "3.3GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "23.10MB/s", + "bandwidth": "28.53MB/s", "reconnects": 0, - "status_2xx": 2298422, + "status_2xx": 2829240, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "crud-4096": { + "framework": "mq-bridge", + "language": "Rust", + "rps": 382023, + "avg_latency": "10.63ms", + "p99_latency": "38.40ms", + "cpu": "3297.4%", + "memory": "508MiB", + "connections": 4096, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "168.33MB/s", + "input_bw": "32.79MB/s", + "reconnects": 26761, + "status_2xx": 5730348, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -322,22 +342,41 @@ "status_4xx": 0, "status_5xx": 0 }, + "fortunes-1024": { + "framework": "mq-bridge", + "language": "Rust", + "rps": 132635, + "avg_latency": "6.31ms", + "p99_latency": "8.85ms", + "cpu": "4697.6%", + "memory": "395MiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "3.10GB/s", + "reconnects": 0, + "status_2xx": 663175, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, "json-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 891396, - "avg_latency": "4.26ms", + "rps": 939937, + "avg_latency": "4.04ms", "p99_latency": "18.80ms", - "cpu": "5883.7%", - "memory": "264MiB", + "cpu": "5900.4%", + "memory": "292MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.07GB/s", - "input_bw": "42.51MB/s", - "reconnects": 176556, - "status_2xx": 4456982, + "bandwidth": "3.24GB/s", + "input_bw": "44.82MB/s", + "reconnects": 186043, + "status_2xx": 4699687, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -345,19 +384,19 @@ "json-comp-16384": { "framework": "mq-bridge", "language": "Rust", - "rps": 384511, - "avg_latency": "42.13ms", - "p99_latency": "149.30ms", - "cpu": "5992.7%", - "memory": "732MiB", + "rps": 551578, + "avg_latency": "29.44ms", + "p99_latency": "61.40ms", + "cpu": "6248.3%", + "memory": "1.3GiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "677.40MB/s", - "input_bw": "28.60MB/s", - "reconnects": 67205, - "status_2xx": 1922558, + "bandwidth": "971.63MB/s", + "input_bw": "41.03MB/s", + "reconnects": 99551, + "status_2xx": 2757893, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -365,19 +404,19 @@ "json-comp-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 407543, - "avg_latency": "10.03ms", - "p99_latency": "36.70ms", - "cpu": "6041.0%", - "memory": "237MiB", + "rps": 569243, + "avg_latency": "7.17ms", + "p99_latency": "22.00ms", + "cpu": "6354.4%", + "memory": "589MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "717.93MB/s", - "input_bw": "30.32MB/s", - "reconnects": 79901, - "status_2xx": 2037716, + "bandwidth": "1002.72MB/s", + "input_bw": "42.34MB/s", + "reconnects": 112175, + "status_2xx": 2846218, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -385,19 +424,19 @@ "json-comp-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 78928, - "avg_latency": "6.49ms", - "p99_latency": "16.60ms", - "cpu": "5866.3%", - "memory": "78MiB", + "rps": 521368, + "avg_latency": "967us", + "p99_latency": "2.54ms", + "cpu": "5899.4%", + "memory": "414MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "139.03MB/s", - "input_bw": "5.87MB/s", - "reconnects": 15728, - "status_2xx": 394643, + "bandwidth": "918.43MB/s", + "input_bw": "38.78MB/s", + "reconnects": 104360, + "status_2xx": 2606840, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -405,18 +444,18 @@ "json-h2c-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 511497, - "avg_latency": "61.75ms", - "p99_latency": "194.77ms", - "cpu": "3241.8%", - "memory": "377MiB", + "rps": 731185, + "avg_latency": "43.26ms", + "p99_latency": "137.09ms", + "cpu": "4568.2%", + "memory": "511MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.72GB/s", + "bandwidth": "2.46GB/s", "reconnects": 0, - "status_2xx": 2588178, + "status_2xx": 3692486, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -424,18 +463,18 @@ "json-h2c-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 469575, - "avg_latency": "255.40ms", - "p99_latency": "1.10s", - "cpu": "3159.7%", - "memory": "1.1GiB", + "rps": 668274, + "avg_latency": "181.16ms", + "p99_latency": "736.29ms", + "cpu": "4496.0%", + "memory": "1.6GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.59GB/s", + "bandwidth": "2.27GB/s", "reconnects": 0, - "status_2xx": 2394837, + "status_2xx": 3414882, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -443,18 +482,18 @@ "json-tls-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 942048, - "avg_latency": "4.51ms", - "p99_latency": "64.56ms", - "cpu": "5595.1%", - "memory": "246MiB", + "rps": 974750, + "avg_latency": "4.44ms", + "p99_latency": "92.11ms", + "cpu": "5404.2%", + "memory": "364MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.24GB", + "bandwidth": "3.36GB", "reconnects": 0, - "status_2xx": 4804691, + "status_2xx": 4971176, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -462,19 +501,19 @@ "limited-conn-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 713952, - "avg_latency": "5.73ms", - "p99_latency": "24.10ms", - "cpu": "5350.7%", - "memory": "258MiB", + "rps": 723987, + "avg_latency": "5.66ms", + "p99_latency": "25.20ms", + "cpu": "6188.2%", + "memory": "279MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "117.08MB/s", - "input_bw": "55.15MB/s", - "reconnects": 356013, - "status_2xx": 3569763, + "bandwidth": "118.73MB/s", + "input_bw": "55.93MB/s", + "reconnects": 360596, + "status_2xx": 3619939, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -482,19 +521,19 @@ "limited-conn-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 716090, - "avg_latency": "706us", - "p99_latency": "1.87ms", - "cpu": "4500.2%", - "memory": "81MiB", + "rps": 748943, + "avg_latency": "675us", + "p99_latency": "1.64ms", + "cpu": "4583.3%", + "memory": "172MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "117.43MB/s", - "input_bw": "55.32MB/s", - "reconnects": 358063, - "status_2xx": 3580454, + "bandwidth": "122.82MB/s", + "input_bw": "57.85MB/s", + "reconnects": 374506, + "status_2xx": 3744719, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -502,18 +541,18 @@ "pipelined-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 4998403, - "avg_latency": "13.09ms", - "p99_latency": "46.70ms", - "cpu": "6501.1%", - "memory": "168MiB", + "rps": 5492012, + "avg_latency": "11.93ms", + "p99_latency": "39.80ms", + "cpu": "6360.6%", + "memory": "284MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "819.65MB/s", + "bandwidth": "900.57MB/s", "reconnects": 0, - "status_2xx": 24992016, + "status_2xx": 27460064, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -521,18 +560,75 @@ "pipelined-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 4931049, - "avg_latency": "1.66ms", - "p99_latency": "3.70ms", - "cpu": "6226.0%", - "memory": "50MiB", + "rps": 5306921, + "avg_latency": "1.54ms", + "p99_latency": "3.49ms", + "cpu": "6301.4%", + "memory": "140MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "808.64MB/s", + "bandwidth": "870.22MB/s", + "reconnects": 0, + "status_2xx": 26534608, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-1024": { + "framework": "mq-bridge", + "language": "Rust", + "rps": 106365, + "avg_latency": "9.99ms", + "p99_latency": "58.74ms", + "cpu": "3808.9%", + "memory": "2.8GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "1.82GB", + "reconnects": 0, + "status_2xx": 542382, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-4096": { + "framework": "mq-bridge", + "language": "Rust", + "rps": 108451, + "avg_latency": "39.68ms", + "p99_latency": "269.47ms", + "cpu": "5103.9%", + "memory": "4.1GiB", + "connections": 4096, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "1.86GB", + "reconnects": 0, + "status_2xx": 553054, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-6800": { + "framework": "mq-bridge", + "language": "Rust", + "rps": 107464, + "avg_latency": "63.91ms", + "p99_latency": "314.77ms", + "cpu": "4617.1%", + "memory": "4.4GiB", + "connections": 6800, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "1.84GB", "reconnects": 0, - "status_2xx": 24655248, + "status_2xx": 548144, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -540,18 +636,18 @@ "static-h2-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 246138, - "avg_latency": "126.28ms", - "p99_latency": "430.54ms", - "cpu": "3659.5%", - "memory": "351MiB", + "rps": 100028, + "avg_latency": "306.44ms", + "p99_latency": "830.61ms", + "cpu": "3888.6%", + "memory": "3.3GiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "6.02GB/s", + "bandwidth": "1.72GB/s", "reconnects": 0, - "status_2xx": 1245462, + "status_2xx": 506145, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -559,18 +655,75 @@ "static-h2-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 340393, - "avg_latency": "23.50ms", - "p99_latency": "158.80ms", - "cpu": "5654.5%", - "memory": "149MiB", + "rps": 111859, + "avg_latency": "71.70ms", + "p99_latency": "449.74ms", + "cpu": "3504.1%", + "memory": "2.1GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "8.26GB/s", + "bandwidth": "1.91GB/s", + "reconnects": 0, + "status_2xx": 561535, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-tls-1024": { + "framework": "mq-bridge", + "language": "Rust", + "rps": 106850, + "avg_latency": "9.89ms", + "p99_latency": "60.96ms", + "cpu": "5227.0%", + "memory": "3.6GiB", + "connections": 1024, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "1.83GB", "reconnects": 0, - "status_2xx": 1712180, + "status_2xx": 544958, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-tls-4096": { + "framework": "mq-bridge", + "language": "Rust", + "rps": 114819, + "avg_latency": "37.68ms", + "p99_latency": "256.29ms", + "cpu": "3233.6%", + "memory": "3.9GiB", + "connections": 4096, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "1.97GB", + "reconnects": 0, + "status_2xx": 585504, + "status_3xx": 0, + "status_4xx": 0, + "status_5xx": 0 + }, + "static-tls-6800": { + "framework": "mq-bridge", + "language": "Rust", + "rps": 105516, + "avg_latency": "64.48ms", + "p99_latency": "366.07ms", + "cpu": "3996.8%", + "memory": "3.5GiB", + "connections": 6800, + "threads": 64, + "duration": "5s", + "pipeline": 1, + "bandwidth": "1.81GB", + "reconnects": 0, + "status_2xx": 537736, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -578,19 +731,19 @@ "upload-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 1471, - "avg_latency": "167.77ms", - "p99_latency": "1.03s", - "cpu": "4773.8%", - "memory": "4.8GiB", + "rps": 1530, + "avg_latency": "161.98ms", + "p99_latency": "910.40ms", + "cpu": "6213.6%", + "memory": "4.9GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "254.57KB/s", - "input_bw": "11.67GB/s", - "reconnects": 1433, - "status_2xx": 7358, + "bandwidth": "264.84KB/s", + "input_bw": "12.14GB/s", + "reconnects": 1507, + "status_2xx": 7652, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -598,19 +751,19 @@ "upload-32": { "framework": "mq-bridge", "language": "Rust", - "rps": 1404, - "avg_latency": "22.76ms", - "p99_latency": "81.10ms", - "cpu": "2924.9%", - "memory": "1.6GiB", + "rps": 1398, + "avg_latency": "22.87ms", + "p99_latency": "78.60ms", + "cpu": "2820.7%", + "memory": "1.4GiB", "connections": 32, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "242.95KB/s", - "input_bw": "11.14GB/s", - "reconnects": 1405, - "status_2xx": 7022, + "bandwidth": "241.86KB/s", + "input_bw": "11.09GB/s", + "reconnects": 1396, + "status_2xx": 6990, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 diff --git a/site/static/logs/crud/4096/mq-bridge.log b/site/static/logs/crud/4096/mq-bridge.log new file mode 100644 index 000000000..e69de29bb diff --git a/site/static/logs/fortunes/1024/mq-bridge.log b/site/static/logs/fortunes/1024/mq-bridge.log new file mode 100644 index 000000000..e69de29bb From e7dc9935d6d1590067389ad65eff022f6f492f50 Mon Sep 17 00:00:00 2001 From: "marco.mengelkoch" Date: Wed, 26 Aug 2026 16:27:55 +0200 Subject: [PATCH 07/12] remove mimalloc --- frameworks/mq-bridge/Cargo.lock | 19 ------------------- frameworks/mq-bridge/Cargo.toml | 4 ---- frameworks/mq-bridge/src/main.rs | 3 --- 3 files changed, 26 deletions(-) diff --git a/frameworks/mq-bridge/Cargo.lock b/frameworks/mq-bridge/Cargo.lock index 531d7e98b..72d83eb27 100644 --- a/frameworks/mq-bridge/Cargo.lock +++ b/frameworks/mq-bridge/Cargo.lock @@ -1288,7 +1288,6 @@ dependencies = [ "askama", "bytes", "dashmap", - "mimalloc", "mq-bridge", "rustls", "serde", @@ -1628,15 +1627,6 @@ version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" -[[package]] -name = "libmimalloc-sys" -version = "0.1.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a45a52f43e1c16f667ccfe4dd8c85b7f7c204fd5e3bf46c5b0db9a5c3c0b8e9" -dependencies = [ - "cc", -] - [[package]] name = "libsqlite3-sys" version = "0.30.1" @@ -1694,15 +1684,6 @@ version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" -[[package]] -name = "mimalloc" -version = "0.1.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d4139bb28d14ad1facf21d5eb8825051b326e172d216b39f6d31df53cc97862" -dependencies = [ - "libmimalloc-sys", -] - [[package]] name = "minimal-lexical" version = "0.2.1" diff --git a/frameworks/mq-bridge/Cargo.toml b/frameworks/mq-bridge/Cargo.toml index 5b861696c..a76c79d9a 100644 --- a/frameworks/mq-bridge/Cargo.toml +++ b/frameworks/mq-bridge/Cargo.toml @@ -33,10 +33,6 @@ dashmap = "6" # Template engine for the fortunes profile: compile-time, auto-escaping, and # the template lives in its own file, as the profile's standard-mode rules require. askama = "0.16" -# Process-wide allocator. Every request allocates (JSON body, message metadata), -# and the default glibc malloc is the weakest part of that path under this much -# concurrency. -mimalloc = { version = "0.1", default-features = false } # Install the process-default rustls crypto provider before the TLS endpoint. rustls = { version = "0.23", default-features = false, features = ["ring"] } diff --git a/frameworks/mq-bridge/src/main.rs b/frameworks/mq-bridge/src/main.rs index 2c8e6c5ff..fd25d6e47 100644 --- a/frameworks/mq-bridge/src/main.rs +++ b/frameworks/mq-bridge/src/main.rs @@ -27,9 +27,6 @@ //! `DATABASE_MAX_CONN`. A missing database is non-fatal — the DB-backed //! endpoints degrade rather than blocking the cleartext profiles. -#[global_allocator] -static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc; - use askama::Template; use bytes::Bytes; use dashmap::DashMap; From 071a6dac44db7769b820d497b4c19dfd67a55cd8 Mon Sep 17 00:00:00 2001 From: "marco.mengelkoch" Date: Wed, 26 Aug 2026 21:55:59 +0200 Subject: [PATCH 08/12] after review --- frameworks/mq-bridge/meta.json | 2 +- frameworks/mq-bridge/src/main.rs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frameworks/mq-bridge/meta.json b/frameworks/mq-bridge/meta.json index 00d518bc0..62edc9522 100644 --- a/frameworks/mq-bridge/meta.json +++ b/frameworks/mq-bridge/meta.json @@ -10,7 +10,7 @@ "response": true }, "engine": "mq-bridge", - "description": "mq-bridge async message-bridging library run as an HTTP server. A single catch-all http->response route dispatches on request metadata and replies through mq-bridge's inline-response fast path; hyper-util's auto connection builder serves HTTP/1.1 and HTTP/2 prior-knowledge (h2c) on the cleartext port (8080) and HTTP/2-over-TLS (ALPN h2) on 8443. Postgres via the library's re-exported sqlx for async-db and crud (in-process cache-aside, 200 ms TTL), fortunes rendered per request with the Askama template engine, dataset read from /data/dataset.json, static assets from /data/static, response compression negotiated per request by the library from Accept-Encoding (zstd > gzip > lz4).", + "description": "mq-bridge async message-bridging library run as an HTTP server. A single catch-all http->response route dispatches on request metadata and replies through mq-bridge's inline-response fast path; hyper-util's auto connection builder serves HTTP/1.1 and HTTP/2 prior-knowledge (h2c) on the cleartext port (8080) and HTTP/2-over-TLS (ALPN h2) on 8443. Postgres via the library's re-exported sqlx for async-db and crud (in-process cache-aside, one-second TTL), fortunes rendered per request with the Askama template engine, dataset read from /data/dataset.json, static assets from /data/static, response compression negotiated per request by the library from Accept-Encoding (zstd > gzip > lz4).", "repo": "https://github.com/marcomq/mq-bridge", "enabled": true, "tests": [ diff --git a/frameworks/mq-bridge/src/main.rs b/frameworks/mq-bridge/src/main.rs index fd25d6e47..79ff156a4 100644 --- a/frameworks/mq-bridge/src/main.rs +++ b/frameworks/mq-bridge/src/main.rs @@ -323,13 +323,16 @@ async fn crud_list(state: &AppState, msg: &CanonicalMessage) -> CanonicalMessage }; let page = msg.query_int("page").unwrap_or(1).max(1); let limit = msg.query_int("limit").unwrap_or(10).clamp(1, 50); - let rows = sqlx::query(SQL) + let rows = match sqlx::query(SQL) .bind(msg.query_param("category").unwrap_or("electronics")) .bind(limit as i32) .bind(((page - 1) * limit) as i32) .fetch_all(pool) .await - .unwrap_or_default(); + { + Ok(rows) => rows, + Err(_) => return status(500, "Internal Server Error"), + }; let items: Vec = rows.iter().map(row_to_item).collect(); json( From 93b73828e630dcdfb738320f5cba8012a7892cd9 Mon Sep 17 00:00:00 2001 From: "marco.mengelkoch" Date: Wed, 26 Aug 2026 22:08:50 +0200 Subject: [PATCH 09/12] remove api - as from remote --- frameworks/mq-bridge/meta.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/frameworks/mq-bridge/meta.json b/frameworks/mq-bridge/meta.json index 2535197f5..280d005cf 100644 --- a/frameworks/mq-bridge/meta.json +++ b/frameworks/mq-bridge/meta.json @@ -26,8 +26,6 @@ "async-db", "crud", "fortunes", - "api-4", - "api-16", "baseline-h2", "static-h2", "baseline-h2c", From e68ca89a896fb141ad3bd9d38a7b8d870834fe8d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Aug 2026 20:37:40 +0000 Subject: [PATCH 10/12] Benchmark results: mq-bridge [skip ci] --- site/data/frameworks.json | 2 +- site/data/results/mq-bridge.json | 492 +++++++++++++++---------------- 2 files changed, 247 insertions(+), 247 deletions(-) diff --git a/site/data/frameworks.json b/site/data/frameworks.json index a0d312aaa..28c7ac427 100644 --- a/site/data/frameworks.json +++ b/site/data/frameworks.json @@ -1111,7 +1111,7 @@ }, "mq-bridge": { "dir": "mq-bridge", - "description": "mq-bridge async message-bridging library run as an HTTP server. A single catch-all http->response route dispatches on request metadata and replies through mq-bridge's inline-response fast path; hyper-util's auto connection builder serves HTTP/1.1 and HTTP/2 prior-knowledge (h2c) on the cleartext port (8080) and HTTP/2-over-TLS (ALPN h2) on 8443. Postgres via the library's re-exported sqlx for async-db and crud (in-process cache-aside, 200 ms TTL), fortunes rendered per request with the Askama template engine, dataset read from /data/dataset.json, static assets from /data/static, response compression negotiated per request by the library from Accept-Encoding (zstd > gzip > lz4).", + "description": "mq-bridge async message-bridging library run as an HTTP server. A single catch-all http->response route dispatches on request metadata and replies through mq-bridge's inline-response fast path; hyper-util's auto connection builder serves HTTP/1.1 and HTTP/2 prior-knowledge (h2c) on the cleartext port (8080) and HTTP/2-over-TLS (ALPN h2) on 8443. Postgres via the library's re-exported sqlx for async-db and crud (in-process cache-aside, one-second TTL), fortunes rendered per request with the Askama template engine, dataset read from /data/dataset.json, static assets from /data/static, response compression negotiated per request by the library from Accept-Encoding (zstd > gzip > lz4).", "repo": "https://github.com/marcomq/mq-bridge", "type": "emerging", "engine": "mq-bridge", diff --git a/site/data/results/mq-bridge.json b/site/data/results/mq-bridge.json index 06afd9d7c..a5a41acfb 100644 --- a/site/data/results/mq-bridge.json +++ b/site/data/results/mq-bridge.json @@ -56,19 +56,19 @@ "async-db-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 138329, - "avg_latency": "6.85ms", - "p99_latency": "8.78ms", - "cpu": "3068.7%", - "memory": "284MiB", + "rps": 132128, + "avg_latency": "7.25ms", + "p99_latency": "9.26ms", + "cpu": "3317.2%", + "memory": "160MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "542.07MB/s", - "input_bw": "9.23MB/s", - "reconnects": 54998, - "status_2xx": 1383298, + "bandwidth": "517.53MB/s", + "input_bw": "8.82MB/s", + "reconnects": 52696, + "status_2xx": 1321284, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -76,19 +76,19 @@ "baseline-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 1216437, - "avg_latency": "3.38ms", - "p99_latency": "6.54ms", - "cpu": "4162.0%", - "memory": "277MiB", + "rps": 1152115, + "avg_latency": "3.57ms", + "p99_latency": "6.91ms", + "cpu": "4342.4%", + "memory": "176MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "199.48MB/s", - "input_bw": "93.97MB/s", + "bandwidth": "188.93MB/s", + "input_bw": "89.00MB/s", "reconnects": 0, - "status_2xx": 6082189, + "status_2xx": 5760575, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -96,19 +96,19 @@ "baseline-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 1142335, - "avg_latency": "447us", + "rps": 1082086, + "avg_latency": "472us", "p99_latency": "1.29ms", - "cpu": "3568.8%", - "memory": "166MiB", + "cpu": "3934.6%", + "memory": "74MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "187.33MB/s", - "input_bw": "88.24MB/s", + "bandwidth": "177.45MB/s", + "input_bw": "83.59MB/s", "reconnects": 0, - "status_2xx": 5711678, + "status_2xx": 5410432, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -116,18 +116,18 @@ "baseline-h2-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 626895, - "avg_latency": "151.49ms", - "p99_latency": "536.83ms", - "cpu": "5072.7%", - "memory": "795MiB", + "rps": 569836, + "avg_latency": "168.47ms", + "p99_latency": "572.61ms", + "cpu": "4803.4%", + "memory": "784MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "31.77MB/s", + "bandwidth": "28.99MB/s", "reconnects": 0, - "status_2xx": 3165824, + "status_2xx": 2883372, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -135,18 +135,18 @@ "baseline-h2-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 714077, - "avg_latency": "35.21ms", - "p99_latency": "144.68ms", - "cpu": "4992.7%", - "memory": "491MiB", + "rps": 668991, + "avg_latency": "37.44ms", + "p99_latency": "137.22ms", + "cpu": "4715.8%", + "memory": "285MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "36.07MB/s", + "bandwidth": "33.81MB/s", "reconnects": 0, - "status_2xx": 3591809, + "status_2xx": 3371715, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -154,18 +154,18 @@ "baseline-h2c-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 642012, - "avg_latency": "149.46ms", - "p99_latency": "581.43ms", - "cpu": "5210.3%", - "memory": "936MiB", + "rps": 587000, + "avg_latency": "166.72ms", + "p99_latency": "585.02ms", + "cpu": "4775.4%", + "memory": "888MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "32.75MB/s", + "bandwidth": "29.85MB/s", "reconnects": 0, - "status_2xx": 3261422, + "status_2xx": 2970225, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -173,18 +173,18 @@ "baseline-h2c-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 702590, - "avg_latency": "35.79ms", - "p99_latency": "147.97ms", - "cpu": "5092.4%", - "memory": "467MiB", + "rps": 678862, + "avg_latency": "37.41ms", + "p99_latency": "146.04ms", + "cpu": "4718.0%", + "memory": "270MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "35.52MB/s", + "bandwidth": "34.27MB/s", "reconnects": 0, - "status_2xx": 3534028, + "status_2xx": 3414679, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -192,18 +192,18 @@ "baseline-h2c-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 554752, - "avg_latency": "603.61ms", - "p99_latency": "2.93s", - "cpu": "5278.9%", - "memory": "3.3GiB", + "rps": 518792, + "avg_latency": "657.03ms", + "p99_latency": "3.03s", + "cpu": "4694.0%", + "memory": "2.4GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "28.53MB/s", + "bandwidth": "26.64MB/s", "reconnects": 0, - "status_2xx": 2829240, + "status_2xx": 2645842, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -211,19 +211,19 @@ "crud-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 382023, - "avg_latency": "10.63ms", - "p99_latency": "38.40ms", - "cpu": "3297.4%", - "memory": "508MiB", + "rps": 384404, + "avg_latency": "10.58ms", + "p99_latency": "38.90ms", + "cpu": "3426.3%", + "memory": "416MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "168.33MB/s", - "input_bw": "32.79MB/s", - "reconnects": 26761, - "status_2xx": 5730348, + "bandwidth": "169.40MB/s", + "input_bw": "32.99MB/s", + "reconnects": 26953, + "status_2xx": 5766071, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -345,18 +345,18 @@ "fortunes-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 132635, - "avg_latency": "6.31ms", - "p99_latency": "8.85ms", - "cpu": "4697.6%", - "memory": "395MiB", + "rps": 124692, + "avg_latency": "6.88ms", + "p99_latency": "9.10ms", + "cpu": "5089.7%", + "memory": "174MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.10GB/s", + "bandwidth": "2.91GB/s", "reconnects": 0, - "status_2xx": 663175, + "status_2xx": 623462, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -364,19 +364,19 @@ "json-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 939937, - "avg_latency": "4.04ms", - "p99_latency": "18.80ms", - "cpu": "5900.4%", - "memory": "292MiB", + "rps": 906592, + "avg_latency": "4.18ms", + "p99_latency": "17.90ms", + "cpu": "5788.4%", + "memory": "263MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.24GB/s", - "input_bw": "44.82MB/s", - "reconnects": 186043, - "status_2xx": 4699687, + "bandwidth": "3.12GB/s", + "input_bw": "43.23MB/s", + "reconnects": 179718, + "status_2xx": 4532961, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -384,19 +384,19 @@ "json-comp-16384": { "framework": "mq-bridge", "language": "Rust", - "rps": 551578, - "avg_latency": "29.44ms", - "p99_latency": "61.40ms", - "cpu": "6248.3%", - "memory": "1.3GiB", + "rps": 347039, + "avg_latency": "46.75ms", + "p99_latency": "159.30ms", + "cpu": "5775.1%", + "memory": "737MiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "971.63MB/s", - "input_bw": "41.03MB/s", - "reconnects": 99551, - "status_2xx": 2757893, + "bandwidth": "611.28MB/s", + "input_bw": "25.82MB/s", + "reconnects": 63500, + "status_2xx": 1735197, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -404,19 +404,19 @@ "json-comp-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 569243, - "avg_latency": "7.17ms", - "p99_latency": "22.00ms", - "cpu": "6354.4%", - "memory": "589MiB", + "rps": 326720, + "avg_latency": "12.49ms", + "p99_latency": "51.40ms", + "cpu": "5543.5%", + "memory": "231MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1002.72MB/s", - "input_bw": "42.34MB/s", - "reconnects": 112175, - "status_2xx": 2846218, + "bandwidth": "575.49MB/s", + "input_bw": "24.30MB/s", + "reconnects": 63596, + "status_2xx": 1633604, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -424,19 +424,19 @@ "json-comp-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 521368, - "avg_latency": "967us", - "p99_latency": "2.54ms", - "cpu": "5899.4%", - "memory": "414MiB", + "rps": 66406, + "avg_latency": "7.71ms", + "p99_latency": "19.20ms", + "cpu": "5741.0%", + "memory": "74MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "918.43MB/s", - "input_bw": "38.78MB/s", - "reconnects": 104360, - "status_2xx": 2606840, + "bandwidth": "116.97MB/s", + "input_bw": "4.94MB/s", + "reconnects": 13187, + "status_2xx": 332032, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -444,18 +444,18 @@ "json-h2c-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 731185, - "avg_latency": "43.26ms", - "p99_latency": "137.09ms", - "cpu": "4568.2%", - "memory": "511MiB", + "rps": 635574, + "avg_latency": "50.01ms", + "p99_latency": "160.64ms", + "cpu": "4187.3%", + "memory": "436MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.46GB/s", + "bandwidth": "2.13GB/s", "reconnects": 0, - "status_2xx": 3692486, + "status_2xx": 3209649, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -463,18 +463,18 @@ "json-h2c-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 668274, - "avg_latency": "181.16ms", - "p99_latency": "736.29ms", - "cpu": "4496.0%", - "memory": "1.6GiB", + "rps": 565062, + "avg_latency": "215.52ms", + "p99_latency": "940.11ms", + "cpu": "3956.5%", + "memory": "1.2GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.27GB/s", + "bandwidth": "1.91GB/s", "reconnects": 0, - "status_2xx": 3414882, + "status_2xx": 2870519, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -482,18 +482,18 @@ "json-tls-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 974750, - "avg_latency": "4.44ms", - "p99_latency": "92.11ms", - "cpu": "5404.2%", - "memory": "364MiB", + "rps": 940587, + "avg_latency": "4.50ms", + "p99_latency": "62.00ms", + "cpu": "5456.6%", + "memory": "250MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.36GB", + "bandwidth": "3.24GB", "reconnects": 0, - "status_2xx": 4971176, + "status_2xx": 4797585, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -501,43 +501,43 @@ "latency-1m-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 997593, - "avg_latency": "764.6us", - "p99_latency": "2925.0us", - "cpu": "3161.6%", - "memory": "88MiB", + "rps": 997869, + "avg_latency": "725.3us", + "p99_latency": "2663.0us", + "cpu": "3215.6%", + "memory": "78MiB", "connections": 1024, "threads": 64, "duration": "20s", "pipeline": 1, - "bandwidth": "170.59MB/s", + "bandwidth": "170.64MB/s", "reconnects": 0, - "status_2xx": 19955531, + "status_2xx": 19961109, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "cpu_usec": 591362508, - "cpu_per_req_us": 29.634, + "cpu_usec": 603341913, + "cpu_per_req_us": 30.2259, "target_rate": 1000000, - "rate_ratio": 0.9976, - "p99_9_latency": "22408.0us" + "rate_ratio": 0.9979, + "p99_9_latency": "17832.0us" }, "limited-conn-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 723987, - "avg_latency": "5.66ms", - "p99_latency": "25.20ms", - "cpu": "6188.2%", - "memory": "279MiB", + "rps": 714481, + "avg_latency": "5.72ms", + "p99_latency": "24.20ms", + "cpu": "5513.4%", + "memory": "246MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "118.73MB/s", - "input_bw": "55.93MB/s", - "reconnects": 360596, - "status_2xx": 3619939, + "bandwidth": "117.17MB/s", + "input_bw": "55.19MB/s", + "reconnects": 356122, + "status_2xx": 3572406, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -545,19 +545,19 @@ "limited-conn-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 748943, - "avg_latency": "675us", - "p99_latency": "1.64ms", - "cpu": "4583.3%", - "memory": "172MiB", + "rps": 713166, + "avg_latency": "709us", + "p99_latency": "1.85ms", + "cpu": "4609.2%", + "memory": "82MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "122.82MB/s", - "input_bw": "57.85MB/s", - "reconnects": 374506, - "status_2xx": 3744719, + "bandwidth": "116.95MB/s", + "input_bw": "55.09MB/s", + "reconnects": 356573, + "status_2xx": 3565830, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -565,18 +565,18 @@ "pipelined-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 5492012, - "avg_latency": "11.93ms", - "p99_latency": "39.80ms", - "cpu": "6360.6%", - "memory": "284MiB", + "rps": 5354118, + "avg_latency": "12.21ms", + "p99_latency": "39.90ms", + "cpu": "6497.3%", + "memory": "166MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "900.57MB/s", + "bandwidth": "877.98MB/s", "reconnects": 0, - "status_2xx": 27460064, + "status_2xx": 26770592, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -584,18 +584,18 @@ "pipelined-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 5306921, - "avg_latency": "1.54ms", - "p99_latency": "3.49ms", - "cpu": "6301.4%", - "memory": "140MiB", + "rps": 5359744, + "avg_latency": "1.53ms", + "p99_latency": "3.35ms", + "cpu": "6312.1%", + "memory": "43MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "870.22MB/s", + "bandwidth": "878.90MB/s", "reconnects": 0, - "status_2xx": 26534608, + "status_2xx": 26798720, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -603,18 +603,18 @@ "static-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 106365, - "avg_latency": "9.99ms", - "p99_latency": "58.74ms", - "cpu": "3808.9%", - "memory": "2.8GiB", + "rps": 109171, + "avg_latency": "9.79ms", + "p99_latency": "64.51ms", + "cpu": "4471.5%", + "memory": "307MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.82GB", + "bandwidth": "1.87GB", "reconnects": 0, - "status_2xx": 542382, + "status_2xx": 554613, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -622,18 +622,18 @@ "static-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 108451, - "avg_latency": "39.68ms", - "p99_latency": "269.47ms", - "cpu": "5103.9%", - "memory": "4.1GiB", + "rps": 105865, + "avg_latency": "40.95ms", + "p99_latency": "261.58ms", + "cpu": "4443.1%", + "memory": "757MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.86GB", + "bandwidth": "1.81GB", "reconnects": 0, - "status_2xx": 553054, + "status_2xx": 539928, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -641,18 +641,18 @@ "static-6800": { "framework": "mq-bridge", "language": "Rust", - "rps": 107464, - "avg_latency": "63.91ms", - "p99_latency": "314.77ms", - "cpu": "4617.1%", - "memory": "4.4GiB", + "rps": 113450, + "avg_latency": "60.29ms", + "p99_latency": "298.90ms", + "cpu": "4180.3%", + "memory": "1.2GiB", "connections": 6800, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.84GB", + "bandwidth": "1.94GB", "reconnects": 0, - "status_2xx": 548144, + "status_2xx": 578589, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -660,18 +660,18 @@ "static-h2-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 100028, - "avg_latency": "306.44ms", - "p99_latency": "830.61ms", - "cpu": "3888.6%", - "memory": "3.3GiB", + "rps": 99402, + "avg_latency": "309.38ms", + "p99_latency": "826.32ms", + "cpu": "3027.7%", + "memory": "973MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.72GB/s", + "bandwidth": "1.71GB/s", "reconnects": 0, - "status_2xx": 506145, + "status_2xx": 502975, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -679,18 +679,18 @@ "static-h2-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 111859, - "avg_latency": "71.70ms", - "p99_latency": "449.74ms", - "cpu": "3504.1%", - "memory": "2.1GiB", + "rps": 102215, + "avg_latency": "78.33ms", + "p99_latency": "443.39ms", + "cpu": "3005.7%", + "memory": "272MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.91GB/s", + "bandwidth": "1.75GB/s", "reconnects": 0, - "status_2xx": 561535, + "status_2xx": 514142, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -698,18 +698,18 @@ "static-tls-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 106850, - "avg_latency": "9.89ms", - "p99_latency": "60.96ms", - "cpu": "5227.0%", - "memory": "3.6GiB", + "rps": 107025, + "avg_latency": "10.02ms", + "p99_latency": "67.37ms", + "cpu": "3209.9%", + "memory": "303MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, "bandwidth": "1.83GB", "reconnects": 0, - "status_2xx": 544958, + "status_2xx": 544126, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -717,18 +717,18 @@ "static-tls-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 114819, - "avg_latency": "37.68ms", - "p99_latency": "256.29ms", - "cpu": "3233.6%", - "memory": "3.9GiB", + "rps": 112247, + "avg_latency": "38.11ms", + "p99_latency": "277.15ms", + "cpu": "5738.1%", + "memory": "772MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.97GB", + "bandwidth": "1.92GB", "reconnects": 0, - "status_2xx": 585504, + "status_2xx": 572265, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -736,18 +736,18 @@ "static-tls-6800": { "framework": "mq-bridge", "language": "Rust", - "rps": 105516, - "avg_latency": "64.48ms", - "p99_latency": "366.07ms", - "cpu": "3996.8%", - "memory": "3.5GiB", + "rps": 105811, + "avg_latency": "64.07ms", + "p99_latency": "329.73ms", + "cpu": "3848.2%", + "memory": "1.1GiB", "connections": 6800, "threads": 64, "duration": "5s", "pipeline": 1, "bandwidth": "1.81GB", "reconnects": 0, - "status_2xx": 537736, + "status_2xx": 539546, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -755,19 +755,19 @@ "upload-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 1530, - "avg_latency": "161.98ms", - "p99_latency": "910.40ms", - "cpu": "6213.6%", - "memory": "4.9GiB", + "rps": 1501, + "avg_latency": "164.66ms", + "p99_latency": "959.00ms", + "cpu": "5514.6%", + "memory": "5.1GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "264.84KB/s", - "input_bw": "12.14GB/s", - "reconnects": 1507, - "status_2xx": 7652, + "bandwidth": "259.73KB/s", + "input_bw": "11.91GB/s", + "reconnects": 1470, + "status_2xx": 7506, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -775,19 +775,19 @@ "upload-32": { "framework": "mq-bridge", "language": "Rust", - "rps": 1398, + "rps": 1399, "avg_latency": "22.87ms", - "p99_latency": "78.60ms", - "cpu": "2820.7%", - "memory": "1.4GiB", + "p99_latency": "80.40ms", + "cpu": "2710.7%", + "memory": "1.5GiB", "connections": 32, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "241.86KB/s", - "input_bw": "11.09GB/s", - "reconnects": 1396, - "status_2xx": 6990, + "bandwidth": "242.08KB/s", + "input_bw": "11.10GB/s", + "reconnects": 1399, + "status_2xx": 6997, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 From a80a965e2210eaa8f8c02bc01250c974b28975c4 Mon Sep 17 00:00:00 2001 From: "marco.mengelkoch" Date: Fri, 28 Aug 2026 08:49:52 +0200 Subject: [PATCH 11/12] upgrade mq-bridge, bump version --- frameworks/mq-bridge/Cargo.lock | 6 +++--- frameworks/mq-bridge/Cargo.toml | 4 ++-- frameworks/mq-bridge/src/main.rs | 9 ++++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/frameworks/mq-bridge/Cargo.lock b/frameworks/mq-bridge/Cargo.lock index 72d83eb27..c9e416b72 100644 --- a/frameworks/mq-bridge/Cargo.lock +++ b/frameworks/mq-bridge/Cargo.lock @@ -1282,7 +1282,7 @@ dependencies = [ [[package]] name = "httparena-mqbridge" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "askama", @@ -1730,8 +1730,8 @@ dependencies = [ [[package]] name = "mq-bridge" -version = "0.4.7" -source = "git+https://github.com/marcomq/mq-bridge?tag=v0.4.7#366ac4e5fe0ded589a00c7203045dab9c90d0391" +version = "0.4.8" +source = "git+https://github.com/marcomq/mq-bridge?tag=v0.4.8#9351bce6f6333b7eb6463c3b18d0ad955e722260" dependencies = [ "anyhow", "arc-swap", diff --git a/frameworks/mq-bridge/Cargo.toml b/frameworks/mq-bridge/Cargo.toml index a76c79d9a..8532bf32d 100644 --- a/frameworks/mq-bridge/Cargo.toml +++ b/frameworks/mq-bridge/Cargo.toml @@ -9,7 +9,7 @@ # `h2`. Pinned to a released `tag` so benchmarks are reproducible. [package] name = "httparena-mqbridge" -version = "0.1.0" +version = "0.1.1" edition = "2021" publish = false @@ -21,7 +21,7 @@ path = "src/main.rs" # `rustls-ring` selects the ring crypto provider for the TLS (8443) listener; # `sqlx` pulls in the library's re-exported sqlx (`mq_bridge::sqlx`) for the # async-db and crud profiles, keeping one sqlx version in the graph. -mq-bridge = { git = "https://github.com/marcomq/mq-bridge", tag = "v0.4.7", default-features = false, features = ["http", "rustls-ring", "sqlx"] } +mq-bridge = { git = "https://github.com/marcomq/mq-bridge", tag = "v0.4.8", default-features = false, features = ["http", "rustls-ring", "sqlx"] } tokio = { version = "1", features = ["macros", "rt-multi-thread", "fs"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/frameworks/mq-bridge/src/main.rs b/frameworks/mq-bridge/src/main.rs index 79ff156a4..f8244d060 100644 --- a/frameworks/mq-bridge/src/main.rs +++ b/frameworks/mq-bridge/src/main.rs @@ -323,10 +323,17 @@ async fn crud_list(state: &AppState, msg: &CanonicalMessage) -> CanonicalMessage }; let page = msg.query_int("page").unwrap_or(1).max(1); let limit = msg.query_int("limit").unwrap_or(10).clamp(1, 50); + // `page` is unbounded client input: the product overflows before the cast. + let Some(offset) = (page - 1) + .checked_mul(limit) + .and_then(|o| i32::try_from(o).ok()) + else { + return status(400, "Bad Request"); + }; let rows = match sqlx::query(SQL) .bind(msg.query_param("category").unwrap_or("electronics")) .bind(limit as i32) - .bind(((page - 1) * limit) as i32) + .bind(offset) .fetch_all(pool) .await { From 7bcfa54fbd9e8ba133a00c0e0be01fb29b4129da Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 28 Aug 2026 07:34:05 +0000 Subject: [PATCH 12/12] Benchmark results: mq-bridge [skip ci] --- site/data/results/mq-bridge.json | 492 +++++++++++++++---------------- 1 file changed, 246 insertions(+), 246 deletions(-) diff --git a/site/data/results/mq-bridge.json b/site/data/results/mq-bridge.json index a5a41acfb..63f9e3318 100644 --- a/site/data/results/mq-bridge.json +++ b/site/data/results/mq-bridge.json @@ -56,19 +56,19 @@ "async-db-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 132128, - "avg_latency": "7.25ms", - "p99_latency": "9.26ms", - "cpu": "3317.2%", - "memory": "160MiB", + "rps": 134125, + "avg_latency": "7.09ms", + "p99_latency": "9.06ms", + "cpu": "3285.3%", + "memory": "161MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "517.53MB/s", - "input_bw": "8.82MB/s", - "reconnects": 52696, - "status_2xx": 1321284, + "bandwidth": "525.65MB/s", + "input_bw": "8.95MB/s", + "reconnects": 53290, + "status_2xx": 1341255, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -76,19 +76,19 @@ "baseline-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 1152115, - "avg_latency": "3.57ms", - "p99_latency": "6.91ms", - "cpu": "4342.4%", - "memory": "176MiB", + "rps": 1157017, + "avg_latency": "3.54ms", + "p99_latency": "6.80ms", + "cpu": "4293.0%", + "memory": "171MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "188.93MB/s", - "input_bw": "89.00MB/s", + "bandwidth": "189.73MB/s", + "input_bw": "89.38MB/s", "reconnects": 0, - "status_2xx": 5760575, + "status_2xx": 5785085, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -96,19 +96,19 @@ "baseline-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 1082086, - "avg_latency": "472us", - "p99_latency": "1.29ms", - "cpu": "3934.6%", - "memory": "74MiB", + "rps": 1080203, + "avg_latency": "473us", + "p99_latency": "1.33ms", + "cpu": "3978.1%", + "memory": "80MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "177.45MB/s", - "input_bw": "83.59MB/s", + "bandwidth": "177.15MB/s", + "input_bw": "83.44MB/s", "reconnects": 0, - "status_2xx": 5410432, + "status_2xx": 5401017, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -116,18 +116,18 @@ "baseline-h2-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 569836, - "avg_latency": "168.47ms", - "p99_latency": "572.61ms", - "cpu": "4803.4%", - "memory": "784MiB", + "rps": 596063, + "avg_latency": "158.01ms", + "p99_latency": "559.95ms", + "cpu": "4737.5%", + "memory": "800MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "28.99MB/s", + "bandwidth": "30.36MB/s", "reconnects": 0, - "status_2xx": 2883372, + "status_2xx": 3016082, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -135,18 +135,18 @@ "baseline-h2-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 668991, - "avg_latency": "37.44ms", - "p99_latency": "137.22ms", - "cpu": "4715.8%", - "memory": "285MiB", + "rps": 672775, + "avg_latency": "37.15ms", + "p99_latency": "139.93ms", + "cpu": "4696.2%", + "memory": "271MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "33.81MB/s", + "bandwidth": "34.07MB/s", "reconnects": 0, - "status_2xx": 3371715, + "status_2xx": 3384061, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -154,18 +154,18 @@ "baseline-h2c-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 587000, - "avg_latency": "166.72ms", - "p99_latency": "585.02ms", - "cpu": "4775.4%", - "memory": "888MiB", + "rps": 596716, + "avg_latency": "163.76ms", + "p99_latency": "568.52ms", + "cpu": "4822.3%", + "memory": "910MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "29.85MB/s", + "bandwidth": "30.35MB/s", "reconnects": 0, - "status_2xx": 2970225, + "status_2xx": 3013419, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -173,18 +173,18 @@ "baseline-h2c-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 678862, - "avg_latency": "37.41ms", - "p99_latency": "146.04ms", - "cpu": "4718.0%", - "memory": "270MiB", + "rps": 659355, + "avg_latency": "38.24ms", + "p99_latency": "138.87ms", + "cpu": "4720.3%", + "memory": "266MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "34.27MB/s", + "bandwidth": "33.37MB/s", "reconnects": 0, - "status_2xx": 3414679, + "status_2xx": 3316557, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -192,18 +192,18 @@ "baseline-h2c-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 518792, - "avg_latency": "657.03ms", - "p99_latency": "3.03s", - "cpu": "4694.0%", + "rps": 541124, + "avg_latency": "626.89ms", + "p99_latency": "3.08s", + "cpu": "4705.9%", "memory": "2.4GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "26.64MB/s", + "bandwidth": "27.82MB/s", "reconnects": 0, - "status_2xx": 2645842, + "status_2xx": 2754323, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -211,19 +211,19 @@ "crud-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 384404, - "avg_latency": "10.58ms", - "p99_latency": "38.90ms", - "cpu": "3426.3%", - "memory": "416MiB", + "rps": 384620, + "avg_latency": "10.55ms", + "p99_latency": "39.30ms", + "cpu": "3416.0%", + "memory": "410MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "169.40MB/s", - "input_bw": "32.99MB/s", - "reconnects": 26953, - "status_2xx": 5766071, + "bandwidth": "169.54MB/s", + "input_bw": "33.01MB/s", + "reconnects": 26938, + "status_2xx": 5769308, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -345,18 +345,18 @@ "fortunes-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 124692, - "avg_latency": "6.88ms", - "p99_latency": "9.10ms", - "cpu": "5089.7%", - "memory": "174MiB", + "rps": 124919, + "avg_latency": "6.85ms", + "p99_latency": "9.21ms", + "cpu": "5143.2%", + "memory": "171MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.91GB/s", + "bandwidth": "2.92GB/s", "reconnects": 0, - "status_2xx": 623462, + "status_2xx": 624598, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -364,19 +364,19 @@ "json-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 906592, - "avg_latency": "4.18ms", - "p99_latency": "17.90ms", - "cpu": "5788.4%", - "memory": "263MiB", + "rps": 912220, + "avg_latency": "4.15ms", + "p99_latency": "17.40ms", + "cpu": "6019.7%", + "memory": "249MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "3.12GB/s", - "input_bw": "43.23MB/s", - "reconnects": 179718, - "status_2xx": 4532961, + "bandwidth": "3.14GB/s", + "input_bw": "43.50MB/s", + "reconnects": 180591, + "status_2xx": 4561100, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -384,19 +384,19 @@ "json-comp-16384": { "framework": "mq-bridge", "language": "Rust", - "rps": 347039, - "avg_latency": "46.75ms", - "p99_latency": "159.30ms", - "cpu": "5775.1%", - "memory": "737MiB", + "rps": 377580, + "avg_latency": "42.78ms", + "p99_latency": "82.30ms", + "cpu": "6566.3%", + "memory": "770MiB", "connections": 16384, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "611.28MB/s", - "input_bw": "25.82MB/s", - "reconnects": 63500, - "status_2xx": 1735197, + "bandwidth": "520.57MB/s", + "input_bw": "28.09MB/s", + "reconnects": 65623, + "status_2xx": 1887902, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -404,19 +404,19 @@ "json-comp-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 326720, - "avg_latency": "12.49ms", - "p99_latency": "51.40ms", - "cpu": "5543.5%", - "memory": "231MiB", + "rps": 385765, + "avg_latency": "10.60ms", + "p99_latency": "32.70ms", + "cpu": "6522.1%", + "memory": "257MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "575.49MB/s", - "input_bw": "24.30MB/s", - "reconnects": 63596, - "status_2xx": 1633604, + "bandwidth": "531.86MB/s", + "input_bw": "28.70MB/s", + "reconnects": 75421, + "status_2xx": 1928827, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -424,19 +424,19 @@ "json-comp-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 66406, - "avg_latency": "7.71ms", - "p99_latency": "19.20ms", - "cpu": "5741.0%", - "memory": "74MiB", + "rps": 373005, + "avg_latency": "1.37ms", + "p99_latency": "3.32ms", + "cpu": "6046.3%", + "memory": "87MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "116.97MB/s", - "input_bw": "4.94MB/s", - "reconnects": 13187, - "status_2xx": 332032, + "bandwidth": "514.22MB/s", + "input_bw": "27.75MB/s", + "reconnects": 74585, + "status_2xx": 1865025, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -444,18 +444,18 @@ "json-h2c-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 635574, - "avg_latency": "50.01ms", - "p99_latency": "160.64ms", - "cpu": "4187.3%", - "memory": "436MiB", + "rps": 620625, + "avg_latency": "50.71ms", + "p99_latency": "166.87ms", + "cpu": "4124.3%", + "memory": "387MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "2.13GB/s", + "bandwidth": "2.09GB/s", "reconnects": 0, - "status_2xx": 3209649, + "status_2xx": 3146572, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -463,18 +463,18 @@ "json-h2c-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 565062, - "avg_latency": "215.52ms", - "p99_latency": "940.11ms", - "cpu": "3956.5%", - "memory": "1.2GiB", + "rps": 565675, + "avg_latency": "213.23ms", + "p99_latency": "837.74ms", + "cpu": "4061.2%", + "memory": "1.1GiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.91GB/s", + "bandwidth": "1.92GB/s", "reconnects": 0, - "status_2xx": 2870519, + "status_2xx": 2884945, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -482,18 +482,18 @@ "json-tls-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 940587, - "avg_latency": "4.50ms", - "p99_latency": "62.00ms", - "cpu": "5456.6%", - "memory": "250MiB", + "rps": 941923, + "avg_latency": "4.53ms", + "p99_latency": "56.50ms", + "cpu": "5530.7%", + "memory": "251MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, "bandwidth": "3.24GB", "reconnects": 0, - "status_2xx": 4797585, + "status_2xx": 4802535, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -501,43 +501,43 @@ "latency-1m-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 997869, - "avg_latency": "725.3us", - "p99_latency": "2663.0us", - "cpu": "3215.6%", - "memory": "78MiB", + "rps": 997486, + "avg_latency": "727.7us", + "p99_latency": "2659.0us", + "cpu": "3190.0%", + "memory": "86MiB", "connections": 1024, "threads": 64, "duration": "20s", "pipeline": 1, - "bandwidth": "170.64MB/s", + "bandwidth": "170.57MB/s", "reconnects": 0, - "status_2xx": 19961109, + "status_2xx": 19953430, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0, - "cpu_usec": 603341913, - "cpu_per_req_us": 30.2259, + "cpu_usec": 595320557, + "cpu_per_req_us": 29.8355, "target_rate": 1000000, - "rate_ratio": 0.9979, - "p99_9_latency": "17832.0us" + "rate_ratio": 0.9975, + "p99_9_latency": "15756.0us" }, "limited-conn-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 714481, - "avg_latency": "5.72ms", - "p99_latency": "24.20ms", - "cpu": "5513.4%", - "memory": "246MiB", + "rps": 719836, + "avg_latency": "5.68ms", + "p99_latency": "23.80ms", + "cpu": "5455.0%", + "memory": "245MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "117.17MB/s", - "input_bw": "55.19MB/s", - "reconnects": 356122, - "status_2xx": 3572406, + "bandwidth": "118.05MB/s", + "input_bw": "55.61MB/s", + "reconnects": 359508, + "status_2xx": 3599180, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -545,19 +545,19 @@ "limited-conn-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 713166, - "avg_latency": "709us", - "p99_latency": "1.85ms", - "cpu": "4609.2%", - "memory": "82MiB", + "rps": 711518, + "avg_latency": "711us", + "p99_latency": "1.86ms", + "cpu": "4467.3%", + "memory": "81MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "116.95MB/s", - "input_bw": "55.09MB/s", - "reconnects": 356573, - "status_2xx": 3565830, + "bandwidth": "116.68MB/s", + "input_bw": "54.96MB/s", + "reconnects": 355735, + "status_2xx": 3557591, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -565,18 +565,18 @@ "pipelined-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 5354118, - "avg_latency": "12.21ms", - "p99_latency": "39.90ms", - "cpu": "6497.3%", - "memory": "166MiB", + "rps": 5455296, + "avg_latency": "12.01ms", + "p99_latency": "38.90ms", + "cpu": "6306.0%", + "memory": "173MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "877.98MB/s", + "bandwidth": "894.58MB/s", "reconnects": 0, - "status_2xx": 26770592, + "status_2xx": 27276480, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -584,18 +584,18 @@ "pipelined-512": { "framework": "mq-bridge", "language": "Rust", - "rps": 5359744, - "avg_latency": "1.53ms", - "p99_latency": "3.35ms", - "cpu": "6312.1%", - "memory": "43MiB", + "rps": 5128608, + "avg_latency": "1.60ms", + "p99_latency": "3.55ms", + "cpu": "6287.0%", + "memory": "44MiB", "connections": 512, "threads": 64, "duration": "5s", "pipeline": 16, - "bandwidth": "878.90MB/s", + "bandwidth": "841.03MB/s", "reconnects": 0, - "status_2xx": 26798720, + "status_2xx": 25643040, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -603,18 +603,18 @@ "static-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 109171, - "avg_latency": "9.79ms", - "p99_latency": "64.51ms", - "cpu": "4471.5%", - "memory": "307MiB", + "rps": 115280, + "avg_latency": "9.28ms", + "p99_latency": "57.93ms", + "cpu": "3969.8%", + "memory": "297MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.87GB", + "bandwidth": "1.97GB", "reconnects": 0, - "status_2xx": 554613, + "status_2xx": 587849, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -622,18 +622,18 @@ "static-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 105865, - "avg_latency": "40.95ms", - "p99_latency": "261.58ms", - "cpu": "4443.1%", - "memory": "757MiB", + "rps": 112015, + "avg_latency": "38.33ms", + "p99_latency": "255.83ms", + "cpu": "5453.8%", + "memory": "756MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.81GB", + "bandwidth": "1.92GB", "reconnects": 0, - "status_2xx": 539928, + "status_2xx": 571334, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -641,18 +641,18 @@ "static-6800": { "framework": "mq-bridge", "language": "Rust", - "rps": 113450, - "avg_latency": "60.29ms", - "p99_latency": "298.90ms", - "cpu": "4180.3%", - "memory": "1.2GiB", + "rps": 114785, + "avg_latency": "59.56ms", + "p99_latency": "309.32ms", + "cpu": "5168.0%", + "memory": "1.1GiB", "connections": 6800, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.94GB", + "bandwidth": "1.97GB", "reconnects": 0, - "status_2xx": 578589, + "status_2xx": 585879, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -660,18 +660,18 @@ "static-h2-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 99402, - "avg_latency": "309.38ms", - "p99_latency": "826.32ms", - "cpu": "3027.7%", - "memory": "973MiB", + "rps": 97656, + "avg_latency": "314.51ms", + "p99_latency": "859.29ms", + "cpu": "3504.2%", + "memory": "966MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.71GB/s", + "bandwidth": "1.68GB/s", "reconnects": 0, - "status_2xx": 502975, + "status_2xx": 494144, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -679,18 +679,18 @@ "static-h2-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 102215, - "avg_latency": "78.33ms", - "p99_latency": "443.39ms", - "cpu": "3005.7%", - "memory": "272MiB", + "rps": 102096, + "avg_latency": "78.39ms", + "p99_latency": "443.82ms", + "cpu": "3544.2%", + "memory": "302MiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, "bandwidth": "1.75GB/s", "reconnects": 0, - "status_2xx": 514142, + "status_2xx": 513543, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -698,18 +698,18 @@ "static-tls-1024": { "framework": "mq-bridge", "language": "Rust", - "rps": 107025, - "avg_latency": "10.02ms", - "p99_latency": "67.37ms", - "cpu": "3209.9%", - "memory": "303MiB", + "rps": 103599, + "avg_latency": "10.27ms", + "p99_latency": "66.65ms", + "cpu": "3869.2%", + "memory": "291MiB", "connections": 1024, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.83GB", + "bandwidth": "1.77GB", "reconnects": 0, - "status_2xx": 544126, + "status_2xx": 528327, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -717,18 +717,18 @@ "static-tls-4096": { "framework": "mq-bridge", "language": "Rust", - "rps": 112247, - "avg_latency": "38.11ms", - "p99_latency": "277.15ms", - "cpu": "5738.1%", - "memory": "772MiB", + "rps": 102505, + "avg_latency": "41.66ms", + "p99_latency": "270.23ms", + "cpu": "4723.1%", + "memory": "722MiB", "connections": 4096, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.92GB", + "bandwidth": "1.76GB", "reconnects": 0, - "status_2xx": 572265, + "status_2xx": 522865, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -736,18 +736,18 @@ "static-tls-6800": { "framework": "mq-bridge", "language": "Rust", - "rps": 105811, - "avg_latency": "64.07ms", - "p99_latency": "329.73ms", - "cpu": "3848.2%", - "memory": "1.1GiB", + "rps": 58544, + "avg_latency": "114.26ms", + "p99_latency": "514.71ms", + "cpu": "2032.7%", + "memory": "1.0GiB", "connections": 6800, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "1.81GB", + "bandwidth": "1.00GB", "reconnects": 0, - "status_2xx": 539546, + "status_2xx": 298505, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -755,19 +755,19 @@ "upload-256": { "framework": "mq-bridge", "language": "Rust", - "rps": 1501, - "avg_latency": "164.66ms", - "p99_latency": "959.00ms", - "cpu": "5514.6%", - "memory": "5.1GiB", + "rps": 1504, + "avg_latency": "164.52ms", + "p99_latency": "972.50ms", + "cpu": "5320.3%", + "memory": "5.0GiB", "connections": 256, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "259.73KB/s", - "input_bw": "11.91GB/s", - "reconnects": 1470, - "status_2xx": 7506, + "bandwidth": "260.33KB/s", + "input_bw": "11.93GB/s", + "reconnects": 1487, + "status_2xx": 7524, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0 @@ -775,19 +775,19 @@ "upload-32": { "framework": "mq-bridge", "language": "Rust", - "rps": 1399, - "avg_latency": "22.87ms", - "p99_latency": "80.40ms", - "cpu": "2710.7%", + "rps": 1404, + "avg_latency": "22.77ms", + "p99_latency": "79.80ms", + "cpu": "2803.3%", "memory": "1.5GiB", "connections": 32, "threads": 64, "duration": "5s", "pipeline": 1, - "bandwidth": "242.08KB/s", - "input_bw": "11.10GB/s", - "reconnects": 1399, - "status_2xx": 6997, + "bandwidth": "242.93KB/s", + "input_bw": "11.14GB/s", + "reconnects": 1405, + "status_2xx": 7020, "status_3xx": 0, "status_4xx": 0, "status_5xx": 0