diff --git a/Cargo.lock b/Cargo.lock index b57c381..9f75b04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,17 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.20" @@ -78,9 +89,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" [[package]] name = "array-init" @@ -188,7 +199,7 @@ dependencies = [ "slab", "socket2", "waker-fn", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -216,7 +227,7 @@ dependencies = [ "futures-lite", "libc", "signal-hook", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -279,9 +290,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1" +checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2" dependencies = [ "proc-macro2", "quote", @@ -402,9 +413,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cache-padded" @@ -414,9 +425,9 @@ checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -629,7 +640,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.12.3", "lock_api", "once_cell", "parking_lot_core", @@ -762,9 +773,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] @@ -785,7 +796,7 @@ dependencies = [ "futures-sink", "nanorand", "pin-project", - "spin 0.9.4", + "spin 0.9.5", ] [[package]] @@ -805,9 +816,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" dependencies = [ "futures-channel", "futures-core", @@ -820,9 +831,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" dependencies = [ "futures-core", "futures-sink", @@ -830,15 +841,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" [[package]] name = "futures-executor" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" dependencies = [ "futures-core", "futures-task", @@ -847,9 +858,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" [[package]] name = "futures-lite" @@ -868,9 +879,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" dependencies = [ "proc-macro2", "quote", @@ -879,21 +890,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" dependencies = [ "futures-channel", "futures-core", @@ -997,6 +1008,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1015,6 +1035,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -1061,9 +1087,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -1140,7 +1166,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -1198,12 +1224,12 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1217,14 +1243,14 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1235,9 +1261,9 @@ checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] @@ -1262,6 +1288,15 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keyed-set" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79e110283e09081809ca488cf3a9709270c6d4d4c4a32674c39cc438366615a" +dependencies = [ + "hashbrown 0.13.2", +] + [[package]] name = "kv-log-macro" version = "1.0.7" @@ -1367,9 +1402,9 @@ dependencies = [ [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" @@ -1383,14 +1418,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1506,9 +1541,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -1545,15 +1580,15 @@ checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" [[package]] name = "parking_lot_core" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1579,9 +1614,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab62d2fa33726dbe6321cc97ef96d8cde531e3eeaf858a058de53a8a6d40d8f" +checksum = "028accff104c4e513bad663bbcd2ad7cfd5304144404c31ed0a77ac103d00660" dependencies = [ "thiserror", "ucd-trie", @@ -1589,9 +1624,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf026e2d0581559db66d837fe5242320f525d85c76283c61f4d51a1238d65ea" +checksum = "2ac3922aac69a40733080f53c1ce7f91dcf57e1a5f6c52f421fadec7fbdc4b69" dependencies = [ "pest", "pest_generator", @@ -1599,9 +1634,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b27bd18aa01d91c8ed2b61ea23406a676b42d82609c6e2581fba42f0c15f17f" +checksum = "d06646e185566b5961b4058dd107e0a7f56e77c3f484549fb119867773c0f202" dependencies = [ "pest", "pest_meta", @@ -1612,9 +1647,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.5.4" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02b677c1859756359fc9983c2e56a0237f18624a3789528804406b7e915e5d" +checksum = "e6f60b2ba541577e2a0c307c8f39d1439108120eb7903adeb6497fa880c59616" dependencies = [ "once_cell", "pest", @@ -1623,9 +1658,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", "indexmap", @@ -1785,7 +1820,7 @@ dependencies = [ "libc", "log", "wepoll-ffi", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1813,9 +1848,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] @@ -1867,7 +1902,7 @@ dependencies = [ "quinn-proto", "socket2", "tracing", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -2059,16 +2094,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.7" +version = "0.36.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2129,7 +2164,7 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -2160,9 +2195,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c4437699b6d34972de58652c68b98cb5b53a4199ab126db8e20ec8ded29a721" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", "core-foundation", @@ -2224,9 +2259,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" dependencies = [ "itoa", "ryu", @@ -2353,9 +2388,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" dependencies = [ "libc", "signal-hook-registry", @@ -2363,9 +2398,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -2391,9 +2426,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -2422,9 +2457,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spin" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" +checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc" dependencies = [ "lock_api", ] @@ -2644,15 +2679,24 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "token-cell" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a2b964fdb303b08a4eab04d7c1bad2bca33f8eee334ccd28802f1041c6eb87" +dependencies = [ + "paste", +] [[package]] name = "tokio" -version = "1.24.2" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb" +checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" dependencies = [ "autocfg", "bytes", @@ -2663,7 +2707,7 @@ dependencies = [ "pin-project-lite", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -2763,7 +2807,7 @@ dependencies = [ "lazy_static", "log", "serde", - "spin 0.9.4", + "spin 0.9.5", "uuid", ] @@ -2850,9 +2894,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.2.2" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" dependencies = [ "getrandom 0.2.8", ] @@ -2923,9 +2967,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2933,9 +2977,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", "log", @@ -2948,9 +2992,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" dependencies = [ "cfg-if", "js-sys", @@ -2960,9 +3004,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2970,9 +3014,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", @@ -2983,15 +3027,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" dependencies = [ "js-sys", "wasm-bindgen", @@ -3112,6 +3156,30 @@ dependencies = [ "windows_x86_64_msvc 0.42.1", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.1", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.1" @@ -3187,7 +3255,7 @@ checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "zenoh" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-global-executor", "async-std", @@ -3222,6 +3290,7 @@ dependencies = [ "zenoh-core", "zenoh-crypto", "zenoh-link", + "zenoh-macros", "zenoh-plugin-trait", "zenoh-protocol", "zenoh-result", @@ -3258,7 +3327,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "zenoh-collections", ] @@ -3266,16 +3335,15 @@ dependencies = [ [[package]] name = "zenoh-cfg-properties" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ - "zenoh-macros", "zenoh-result", ] [[package]] name = "zenoh-codec" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "uhlc", "zenoh-buffers", @@ -3286,12 +3354,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" [[package]] name = "zenoh-config" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "flume", "json5", @@ -3310,18 +3378,17 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "lazy_static", - "zenoh-macros", "zenoh-result", ] [[package]] name = "zenoh-crypto" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "aes 0.8.2", "hmac 0.12.1", @@ -3331,10 +3398,23 @@ dependencies = [ "zenoh-result", ] +[[package]] +name = "zenoh-keyexpr" +version = "0.7.0-rc" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" +dependencies = [ + "hashbrown 0.13.2", + "keyed-set", + "rand 0.8.5", + "serde", + "token-cell", + "zenoh-result", +] + [[package]] name = "zenoh-link" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "async-trait", @@ -3354,7 +3434,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "async-trait", @@ -3371,7 +3451,7 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "async-trait", @@ -3395,7 +3475,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "async-trait", @@ -3411,7 +3491,7 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-rustls", "async-std", @@ -3434,7 +3514,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "async-trait", @@ -3453,7 +3533,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "async-trait", @@ -3471,7 +3551,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "async-trait", @@ -3491,19 +3571,20 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.0", "syn", "unzip-n", + "zenoh-keyexpr", ] [[package]] name = "zenoh-plugin-trait" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "libloading", "log", @@ -3516,7 +3597,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "hex", "rand 0.8.5", @@ -3524,13 +3605,14 @@ dependencies = [ "uhlc", "uuid", "zenoh-buffers", + "zenoh-keyexpr", "zenoh-result", ] [[package]] name = "zenoh-result" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "anyhow", ] @@ -3538,7 +3620,7 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "bincode", "log", @@ -3551,7 +3633,7 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "event-listener", @@ -3566,7 +3648,7 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-executor", "async-global-executor", @@ -3597,7 +3679,7 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "async-trait", @@ -3615,18 +3697,15 @@ dependencies = [ "pnet_datalink", "shellexpand", "winapi", - "zenoh-cfg-properties", - "zenoh-collections", "zenoh-core", - "zenoh-crypto", + "zenoh-protocol", "zenoh-result", - "zenoh-sync", ] [[package]] name = "zenoh_backend_traits" version = "0.7.0-rc" -source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#a322f6bb055ba9cbbe7b1f95e3452eeb05847426" +source = "git+https://github.com/eclipse-zenoh/zenoh?branch=master#5a5d096a4a3c3285baa92fb54e89481cfd69b6d4" dependencies = [ "async-std", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index fa89902..02f23c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ authors = [ "Julien Enoch ", "Olivier Hécart ", "Luca Cominardi ", + "Sreeja Nair ", ] edition = "2018" license = " EPL-2.0 OR Apache-2.0" diff --git a/src/lib.rs b/src/lib.rs index e6d800b..da2fc3f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,11 +26,10 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use uuid::Uuid; use zenoh::buffers::{SplitBuffer, ZBuf}; -use zenoh::prelude::r#async::AsyncResolve; use zenoh::prelude::*; use zenoh::properties::Properties; use zenoh::selector::TimeExpr; -use zenoh::time::{new_reception_timestamp, Timestamp}; +use zenoh::time::Timestamp; use zenoh::Result as ZResult; use zenoh_backend_traits::config::{ PrivacyGetResult, PrivacyTransparentGet, StorageConfig, VolumeConfig, @@ -52,13 +51,16 @@ pub const PROP_STORAGE_ON_CLOSURE: &str = "on_closure"; pub const PROP_STORAGE_USERNAME: &str = PROP_BACKEND_USERNAME; pub const PROP_STORAGE_PASSWORD: &str = PROP_BACKEND_PASSWORD; +// Special key for None (when the prefix being stripped exactly matches the key) +pub const NONE_KEY: &str = "@@none_key@@"; + // delay after deletion to drop a measurement const DROP_MEASUREMENT_TIMEOUT_MS: u64 = 5000; const GIT_VERSION: &str = git_version::git_version!(prefix = "v", cargo_prefix = "v"); lazy_static::lazy_static!( static ref LONG_VERSION: String = format!("{} built with {}", GIT_VERSION, env!("RUSTC_VERSION")); - static ref INFLUX_REGEX_ALL: String = path_exprs_to_influx_regex(&["**".try_into().unwrap()]); + static ref INFLUX_REGEX_ALL: String = key_exprs_to_influx_regex(&["**".try_into().unwrap()]); ); #[allow(dead_code)] @@ -174,6 +176,14 @@ impl Volume for InfluxDbBackend { self.admin_status.to_json_value() } + fn get_capability(&self) -> Capability { + Capability { + persistence: Persistence::Durable, + history: History::All, + read_cost: 1, + } + } + async fn create_storage(&mut self, mut config: StorageConfig) -> ZResult> { let volume_cfg = match config.volume_cfg.as_object() { Some(v) => v, @@ -356,12 +366,14 @@ impl InfluxDbStorage { handle } - fn keyexpr_from_serie(&self, serie_name: &str) -> ZResult { - // reconstruct the key expression from the measurement name (same as serie.name), adding back strip_prefix if specified - if let Some(prefix) = &self.config.strip_prefix { - prefix.join(serie_name) + fn keyexpr_from_serie(&self, serie_name: &str) -> ZResult> { + if serie_name.eq(NONE_KEY) { + Ok(None) } else { - serie_name.try_into() + match OwnedKeyExpr::from_str(serie_name) { + Ok(key) => Ok(Some(key)), + Err(e) => Err(format!("{}", e).into()), + } } } } @@ -373,129 +385,121 @@ impl Storage for InfluxDbStorage { self.config.to_json_value() } - // When receiving a Sample (i.e. on PUT or DELETE operations) - async fn on_sample(&mut self, sample: Sample) -> ZResult { - // measurement is the key expression, stripped of the strip_prefix if any - let measurement = match &self.config.strip_prefix { - Some(prefix) => match sample.key_expr.as_str().strip_prefix(prefix.as_str()) { - Some(s) => &s[1..], // also remove the intermediate '/' - None => bail!( - "Received a Sample not starting with path_prefix '{}'", - prefix - ), - }, - None => sample.key_expr.as_str(), - }; + async fn put( + &mut self, + key: Option, + value: Value, + timestamp: Timestamp, + ) -> ZResult { + let measurement = key.unwrap_or_else(|| OwnedKeyExpr::from_str(NONE_KEY).unwrap()); // Note: assume that uhlc timestamp was generated by a clock using UNIX_EPOCH (that's the case by default) - let sample_ts = sample.timestamp.unwrap_or_else(new_reception_timestamp); - let influx_time = sample_ts.get_time().to_duration().as_nanos(); - - // Store or delete the sample depending the ChangeKind - match sample.kind { - SampleKind::Put => { - // get timestamp of deletion of this measurement, if any - if let Some(del_time) = self.get_deletion_timestamp(measurement).await? { - // ignore sample if oldest than the deletion - if sample_ts < del_time { - debug!("Received a Sample for {} with timestamp older than its deletion; ignore it", sample.key_expr); - return Ok(StorageInsertionResult::Outdated); - } - } + let influx_time = timestamp.get_time().to_duration().as_nanos(); - // encode the value as a string to be stored in InfluxDB, converting to base64 if the buffer is not a UTF-8 string - let (base64, strvalue) = - match String::from_utf8(sample.payload.contiguous().into_owned()) { - Ok(s) => (false, s), - Err(err) => (true, b64_std_engine.encode(err.into_bytes())), - }; - - // Note: tags are stored as strings in InfluxDB, while fileds are typed. - // For simpler/faster deserialization, we store encoding, timestamp and base64 as fields. - // while the kind is stored as a tag to be indexed by InfluxDB and have faster queries on it. - let query = - InfluxWQuery::new(InfluxTimestamp::Nanoseconds(influx_time), measurement) - .add_tag("kind", "PUT") - .add_field("timestamp", sample_ts.to_string()) - .add_field("encoding_prefix", u8::from(*sample.value.encoding.prefix())) - .add_field("encoding_suffix", sample.value.encoding.suffix()) - .add_field("base64", base64) - .add_field("value", strvalue); - debug!("Put {} with Influx query: {:?}", sample.key_expr, query); - if let Err(e) = self.client.query(&query).await { - bail!( - "Failed to put Value for {} in InfluxDb storage : {}", - sample.key_expr, - e - ) - } else { - Ok(StorageInsertionResult::Inserted) - } - } - SampleKind::Delete => { - // delete all points from the measurement that are older than this DELETE message - // (in case more recent PUT have been recevived un-ordered) - let query = InfluxRQuery::new(format!( - r#"DELETE FROM "{measurement}" WHERE time < {influx_time}"# - )); - debug!("Delete {} with Influx query: {:?}", sample.key_expr, query); - if let Err(e) = self.client.query(&query).await { - bail!( - "Failed to delete points for measurement '{}' from InfluxDb storage : {}", - measurement, - e - ) - } - // store a point (with timestamp) with "delete" tag, thus we don't re-introduce an older point later - let query = - InfluxWQuery::new(InfluxTimestamp::Nanoseconds(influx_time), measurement) - .add_field("timestamp", sample_ts.to_string()) - .add_tag("kind", "DEL"); + // get timestamp of deletion of this measurement, if any + if let Some(del_time) = self.get_deletion_timestamp(measurement.as_str()).await? { + // ignore sample if oldest than the deletion + if timestamp < del_time { debug!( - "Mark measurement {} as deleted at time {}", - measurement, influx_time + "Received a value for {:?} with timestamp older than its deletion; ignore it", + measurement ); - if let Err(e) = self.client.query(&query).await { - bail!( - "Failed to mark measurement {} as deleted : {}", - sample.key_expr, - e - ) - } - // schedule the drop of measurement later in the future, if it's empty - let _ = self.schedule_measurement_drop(measurement).await; - Ok(StorageInsertionResult::Deleted) + return Ok(StorageInsertionResult::Outdated); } } - } - // When receiving a Query (i.e. on GET operations) - async fn on_query(&mut self, query: Query) -> ZResult<()> { - // get the query's Selector - let selector = query.selector(); - let selector_str = selector.key_expr.as_str(); - // if a strip_prefix is used - let regex = if let Some(prefix) = &self.config.strip_prefix { - // get the list of sub-path expressions that will match the same stored keys than - // the selector, if those keys had the strip_prefix. - let vec = selector.key_expr.strip_prefix(prefix); - if vec.is_empty() { - warn!("Received query on selector '{}', but the configured strip_prefix='{:?}' is not a prefix of this selector", selector, self.config.strip_prefix); - return Ok(()); - } - debug!( - "Query on {} with strip_prefix={} => sub-keyexprs = {:?}", - selector, prefix, vec - ); - // convert the sub-path expressions into an Influx regex - path_exprs_to_influx_regex(vec.as_slice()) + // encode the value as a string to be stored in InfluxDB, converting to base64 if the buffer is not a UTF-8 string + let (base64, strvalue) = match String::from_utf8(value.payload.contiguous().into_owned()) { + Ok(s) => (false, s), + Err(err) => (true, b64_std_engine.encode(err.into_bytes())), + }; + + // Note: tags are stored as strings in InfluxDB, while fileds are typed. + // For simpler/faster deserialization, we store encoding, timestamp and base64 as fields. + // while the kind is stored as a tag to be indexed by InfluxDB and have faster queries on it. + let query = InfluxWQuery::new( + InfluxTimestamp::Nanoseconds(influx_time), + measurement.clone(), + ) + .add_tag("kind", "PUT") + .add_field("timestamp", timestamp.to_string()) + .add_field("encoding_prefix", u8::from(*value.encoding.prefix())) + .add_field("encoding_suffix", value.encoding.suffix()) + .add_field("base64", base64) + .add_field("value", strvalue); + debug!("Put {:?} with Influx query: {:?}", measurement, query); + if let Err(e) = self.client.query(&query).await { + bail!( + "Failed to put Value for {:?} in InfluxDb storage : {}", + measurement, + e + ) } else { - // convert the Selector's path expression into an Influx regex - path_exprs_to_influx_regex(&[selector.key_expr.as_keyexpr()]) + Ok(StorageInsertionResult::Inserted) + } + } + + async fn delete( + &mut self, + key: Option, + timestamp: Timestamp, + ) -> ZResult { + let measurement = key.unwrap_or_else(|| OwnedKeyExpr::from_str(NONE_KEY).unwrap()); + + // Note: assume that uhlc timestamp was generated by a clock using UNIX_EPOCH (that's the case by default) + let influx_time = timestamp.get_time().to_duration().as_nanos(); + + // delete all points from the measurement that are older than this DELETE message + // (in case more recent PUT have been recevived un-ordered) + let query = InfluxRQuery::new(format!( + r#"DELETE FROM "{}" WHERE time < {}"#, + measurement, influx_time + )); + debug!("Delete {:?} with Influx query: {:?}", measurement, query); + if let Err(e) = self.client.query(&query).await { + bail!( + "Failed to delete points for measurement '{}' from InfluxDb storage : {}", + measurement, + e + ) + } + // store a point (with timestamp) with "delete" tag, thus we don't re-introduce an older point later + let query = InfluxWQuery::new( + InfluxTimestamp::Nanoseconds(influx_time), + measurement.clone(), + ) + .add_field("timestamp", timestamp.to_string()) + .add_tag("kind", "DEL"); + debug!( + "Mark measurement {} as deleted at time {}", + measurement, influx_time + ); + if let Err(e) = self.client.query(&query).await { + bail!( + "Failed to mark measurement {:?} as deleted : {}", + measurement, + e + ) + } + // schedule the drop of measurement later in the future, if it's empty + let _ = self.schedule_measurement_drop(measurement.as_str()).await; + Ok(StorageInsertionResult::Deleted) + } + + async fn get( + &mut self, + key: Option, + parameters: &str, + ) -> ZResult> { + let measurement = match key.clone() { + Some(k) => k, + None => OwnedKeyExpr::from_str(NONE_KEY).unwrap(), }; + // convert the key expression into an Influx regex + let regex = key_exprs_to_influx_regex(&[&KeyExpr::from(measurement)]); - // construct the Influx query clauses from the Selector - let clauses = clauses_from_selector(&selector)?; + // construct the Influx query clauses from the parameters + let clauses = clauses_from_parameters(parameters)?; // the Influx query let influx_query_str = format!("SELECT * FROM {regex} {clauses}"); @@ -513,7 +517,8 @@ impl Storage for InfluxDbStorage { base64: bool, value: String, } - debug!("Get {} with Influx query: {}", selector, influx_query_str); + debug!("Get {:?} with Influx query: {}", key, influx_query_str); + let mut result = Vec::new(); match self.client.json_query(influx_query).await { Ok(mut query_result) => { while !query_result.results.is_empty() { @@ -532,7 +537,7 @@ impl Storage for InfluxDbStorage { continue; } }; - debug!("Replying {} values for {}", serie.values.len(), ke); + debug!("Replying {} values for {:?}", serie.values.len(), ke); // for each point for zpoint in serie.values { // get the encoding @@ -575,22 +580,7 @@ impl Storage for InfluxDbStorage { } }; let value = Value::new(payload).encoding(encoding); - // send the reply - if let Err(e) = query - .reply( - Sample::new(ke.clone(), value) - .with_timestamp(timestamp), - ) - .res() - .await - { - log::error!( - "Error replying to query on {} with {}: {}", - selector_str, - ke, - e - ); - } + result.push(StoredData { value, timestamp }); } } } @@ -603,7 +593,6 @@ impl Storage for InfluxDbStorage { } } } - Ok(()) } Err(e) => bail!( "Failed to query InfluxDb with '{}' : {}", @@ -611,9 +600,10 @@ impl Storage for InfluxDbStorage { e ), } + Ok(result) } - async fn get_all_entries(&self) -> ZResult> { + async fn get_all_entries(&self) -> ZResult, Timestamp)>> { let mut result = Vec::new(); // the Influx query @@ -639,7 +629,11 @@ impl Storage for InfluxDbStorage { // get the key expression from the serie name match self.keyexpr_from_serie(&serie.name) { Ok(ke) => { - debug!("Replying {} values for {}", serie.values.len(), ke); + debug!( + "Replying {} values for {:?}", + serie.values.len(), + ke + ); // for each point in the serie for zpoint in serie.values { // get the timestamp (ignore the point if failing) @@ -852,7 +846,7 @@ async fn create_db( // corresponding to the list of path expressions. I.e.: // Replace "**" with ".*", "*" with "[^\/]*" and "/" with "\/". // Concat each with "|", and surround the result with '/^' and '$/'. -fn path_exprs_to_influx_regex(path_exprs: &[&keyexpr]) -> String { +fn key_exprs_to_influx_regex(path_exprs: &[&keyexpr]) -> String { let mut result = String::with_capacity(2 * path_exprs[0].len()); result.push_str("/^"); for (i, path_expr) in path_exprs.iter().enumerate() { @@ -881,9 +875,9 @@ fn path_exprs_to_influx_regex(path_exprs: &[&keyexpr]) -> String { result } -fn clauses_from_selector(s: &Selector) -> ZResult { +fn clauses_from_parameters(p: &str) -> ZResult { use zenoh::selector::{TimeBound, TimeRange}; - let time_range = s.time_range()?; + let time_range = p.time_range()?; let mut result = String::with_capacity(256); result.push_str("WHERE kind!='DEL'"); match time_range {