mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Merge pull request #384 from LibreQoE/long_term_stats
Long term stats > Develop
This commit is contained in:
commit
9d7aae311f
216
src/rust/Cargo.lock
generated
216
src/rust/Cargo.lock
generated
@ -166,7 +166,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -177,7 +177,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -311,7 +311,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
"which",
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -529,7 +529,7 @@ dependencies = [
|
|||||||
"heck",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -564,6 +564,42 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console-api"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e"
|
||||||
|
dependencies = [
|
||||||
|
"prost",
|
||||||
|
"prost-types",
|
||||||
|
"tonic",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console-subscriber"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb"
|
||||||
|
dependencies = [
|
||||||
|
"console-api",
|
||||||
|
"crossbeam-channel",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"futures",
|
||||||
|
"hdrhistogram",
|
||||||
|
"humantime",
|
||||||
|
"prost-types",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thread_local",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tonic",
|
||||||
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-subscriber 0.3.17",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cookie"
|
name = "cookie"
|
||||||
version = "0.17.0"
|
version = "0.17.0"
|
||||||
@ -637,7 +673,7 @@ dependencies = [
|
|||||||
"clap 3.2.25",
|
"clap 3.2.25",
|
||||||
"criterion-plot",
|
"criterion-plot",
|
||||||
"futures",
|
"futures",
|
||||||
"itertools",
|
"itertools 0.10.5",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"oorandom",
|
"oorandom",
|
||||||
@ -659,7 +695,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
|
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cast",
|
"cast",
|
||||||
"itertools",
|
"itertools 0.10.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -871,7 +907,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"proc-macro2-diagnostics",
|
"proc-macro2-diagnostics",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1191,7 +1227,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1330,6 +1366,19 @@ dependencies = [
|
|||||||
"hashbrown 0.13.2",
|
"hashbrown 0.13.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hdrhistogram"
|
||||||
|
version = "7.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.13.1",
|
||||||
|
"byteorder",
|
||||||
|
"flate2",
|
||||||
|
"nom",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "headers"
|
name = "headers"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
@ -1482,6 +1531,18 @@ dependencies = [
|
|||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-timeout"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
|
||||||
|
dependencies = [
|
||||||
|
"hyper",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tokio-io-timeout",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-tls"
|
name = "hyper-tls"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -1583,7 +1644,7 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "990f899841aa30130fc06f7938e3cc2cbc3d5b92c03fd4b5d79a965045abcf16"
|
checksum = "990f899841aa30130fc06f7938e3cc2cbc3d5b92c03fd4b5d79a965045abcf16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools 0.10.5",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
@ -1705,6 +1766,15 @@ dependencies = [
|
|||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
@ -2143,9 +2213,11 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"axum",
|
"axum",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"console-subscriber",
|
||||||
"futures",
|
"futures",
|
||||||
"influxdb2",
|
"influxdb2",
|
||||||
"influxdb2-structmap",
|
"influxdb2-structmap",
|
||||||
|
"itertools 0.11.0",
|
||||||
"lqos_config",
|
"lqos_config",
|
||||||
"lts_client",
|
"lts_client",
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
@ -2479,7 +2551,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2615,7 +2687,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"proc-macro2-diagnostics",
|
"proc-macro2-diagnostics",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2665,7 +2737,7 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2727,14 +2799,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "617feabb81566b593beb4886fb8c1f38064169dae4dccad0e3220160c3b37203"
|
checksum = "617feabb81566b593beb4886fb8c1f38064169dae4dccad0e3220160c3b37203"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.57"
|
version = "1.0.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16"
|
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
@ -2747,11 +2819,43 @@ checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
"version_check",
|
"version_check",
|
||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost"
|
||||||
|
version = "0.11.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"prost-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost-derive"
|
||||||
|
version = "0.11.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"itertools 0.10.5",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost-types"
|
||||||
|
version = "0.11.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13"
|
||||||
|
dependencies = [
|
||||||
|
"prost",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyo3"
|
name = "pyo3"
|
||||||
version = "0.18.3"
|
version = "0.18.3"
|
||||||
@ -2814,9 +2918,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.27"
|
version = "1.0.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
|
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@ -2928,7 +3032,7 @@ checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3105,7 +3209,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rocket_http",
|
"rocket_http",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -3289,7 +3393,7 @@ checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3475,7 +3579,7 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e"
|
checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools 0.10.5",
|
||||||
"nom",
|
"nom",
|
||||||
"unicode_categories",
|
"unicode_categories",
|
||||||
]
|
]
|
||||||
@ -3662,9 +3766,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.16"
|
version = "2.0.27"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01"
|
checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -3749,22 +3853,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.40"
|
version = "1.0.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
|
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.40"
|
version = "1.0.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3856,9 +3960,20 @@ dependencies = [
|
|||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
|
"tracing",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-io-timeout"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
@ -3867,7 +3982,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3959,6 +4074,34 @@ dependencies = [
|
|||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tonic"
|
||||||
|
version = "0.9.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"axum",
|
||||||
|
"base64 0.21.0",
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"h2",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"hyper",
|
||||||
|
"hyper-timeout",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project",
|
||||||
|
"prost",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tower",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.4.13"
|
version = "0.4.13"
|
||||||
@ -3967,9 +4110,13 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"indexmap",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"rand",
|
||||||
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
@ -4033,7 +4180,7 @@ checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4357,7 +4504,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4391,7 +4538,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
"wasm-bindgen-backend",
|
"wasm-bindgen-backend",
|
||||||
"wasm-bindgen-shared",
|
"wasm-bindgen-shared",
|
||||||
]
|
]
|
||||||
@ -4423,6 +4570,7 @@ dependencies = [
|
|||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"serde_cbor",
|
"serde_cbor",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm_pipe_types",
|
"wasm_pipe_types",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
@ -4798,5 +4946,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.16",
|
"syn 2.0.27",
|
||||||
]
|
]
|
||||||
|
@ -17,7 +17,7 @@ pub async fn collect_tree(
|
|||||||
totals: &Option<Vec<StatsTreeNode>>,
|
totals: &Option<Vec<StatsTreeNode>>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if let Some(tree) = totals {
|
if let Some(tree) = totals {
|
||||||
//println!("{tree:?}");
|
//info!("{tree:?}");
|
||||||
let influx_url = format!("http://{}:8086", org.influx_host);
|
let influx_url = format!("http://{}:8086", org.influx_host);
|
||||||
let client = Client::new(&influx_url, &org.influx_org, &org.influx_token);
|
let client = Client::new(&influx_url, &org.influx_org, &org.influx_token);
|
||||||
let mut points: Vec<DataPoint> = Vec::new();
|
let mut points: Vec<DataPoint> = Vec::new();
|
||||||
@ -31,12 +31,22 @@ pub async fn collect_tree(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
for node in tree.iter() {
|
for node in tree.iter() {
|
||||||
|
let mut parents = format!("S{}S", node.parents.iter().map(|p| p.to_string()).collect::<Vec<String>>().join("S"));
|
||||||
|
if parents.is_empty() {
|
||||||
|
parents = "0S".to_string();
|
||||||
|
}
|
||||||
|
let my_id = node.index.to_string();
|
||||||
|
//let parent = node.immediate_parent.unwrap_or(0).to_string();
|
||||||
|
//warn!("{}: {}", node.name, parents);
|
||||||
|
//warn!("{parent}");
|
||||||
points.push(
|
points.push(
|
||||||
DataPoint::builder("tree")
|
DataPoint::builder("tree")
|
||||||
.tag("host_id", node_id.to_string())
|
.tag("host_id", node_id.to_string())
|
||||||
.tag("organization_id", org.key.to_string())
|
.tag("organization_id", org.key.to_string())
|
||||||
.tag("node_name", node.name.to_string())
|
.tag("node_name", node.name.to_string())
|
||||||
.tag("direction", "down".to_string())
|
.tag("direction", "down".to_string())
|
||||||
|
.tag("node_parents", parents.clone())
|
||||||
|
.tag("node_index", my_id.clone())
|
||||||
.timestamp(timestamp)
|
.timestamp(timestamp)
|
||||||
.field("bits_min", node.current_throughput.min.0 as i64)
|
.field("bits_min", node.current_throughput.min.0 as i64)
|
||||||
.field("bits_max", node.current_throughput.max.0 as i64)
|
.field("bits_max", node.current_throughput.max.0 as i64)
|
||||||
@ -49,6 +59,8 @@ pub async fn collect_tree(
|
|||||||
.tag("organization_id", org.key.to_string())
|
.tag("organization_id", org.key.to_string())
|
||||||
.tag("node_name", node.name.to_string())
|
.tag("node_name", node.name.to_string())
|
||||||
.tag("direction", "up".to_string())
|
.tag("direction", "up".to_string())
|
||||||
|
.tag("node_parents", parents.clone())
|
||||||
|
.tag("node_index", my_id.clone())
|
||||||
.timestamp(timestamp)
|
.timestamp(timestamp)
|
||||||
.field("bits_min", node.current_throughput.min.1 as i64)
|
.field("bits_min", node.current_throughput.min.1 as i64)
|
||||||
.field("bits_max", node.current_throughput.max.1 as i64)
|
.field("bits_max", node.current_throughput.max.1 as i64)
|
||||||
@ -60,6 +72,8 @@ pub async fn collect_tree(
|
|||||||
.tag("host_id", node_id.to_string())
|
.tag("host_id", node_id.to_string())
|
||||||
.tag("organization_id", org.key.to_string())
|
.tag("organization_id", org.key.to_string())
|
||||||
.tag("node_name", node.name.to_string())
|
.tag("node_name", node.name.to_string())
|
||||||
|
.tag("node_parents", parents)
|
||||||
|
.tag("node_index", my_id.clone())
|
||||||
.timestamp(timestamp)
|
.timestamp(timestamp)
|
||||||
.field("rtt_min", node.rtt.min as i64 / 100)
|
.field("rtt_min", node.rtt.min as i64 / 100)
|
||||||
.field("rtt_max", node.rtt.max as i64 / 100)
|
.field("rtt_max", node.rtt.max as i64 / 100)
|
||||||
@ -92,13 +106,16 @@ pub async fn collect_tree(
|
|||||||
error!("Error committing transaction: {}", e);
|
error!("Error committing transaction: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
client
|
if let Err(e) = client
|
||||||
.write_with_precision(
|
.write_with_precision(
|
||||||
&org.influx_bucket,
|
&org.influx_bucket,
|
||||||
stream::iter(points),
|
stream::iter(points),
|
||||||
influxdb2::api::write::TimestampPrecision::Seconds,
|
influxdb2::api::write::TimestampPrecision::Seconds,
|
||||||
)
|
)
|
||||||
.await?;
|
.await {
|
||||||
|
error!("Error committing tree to Influx: {}", e);
|
||||||
|
}
|
||||||
|
info!("Wrote tree to InfluxDB");
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,12 @@ influxdb2-structmap = "0"
|
|||||||
num-traits = "0"
|
num-traits = "0"
|
||||||
futures = "0"
|
futures = "0"
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3" }
|
||||||
tower = { version = "0.4", features = ["util"] }
|
tower = { version = "0.4", features = ["util"] }
|
||||||
tower-http = { version = "0.4.0", features = ["fs", "trace"] }
|
tower-http = { version = "0.4.0", features = ["fs", "trace"] }
|
||||||
chrono = "0"
|
chrono = "0"
|
||||||
miniz_oxide = "0.7.1"
|
miniz_oxide = "0.7.1"
|
||||||
tokio-util = { version = "0.7.8", features = ["io"] }
|
tokio-util = { version = "0.7.8", features = ["io"] }
|
||||||
wasm_pipe_types = { path = "../wasm_pipe_types" }
|
wasm_pipe_types = { path = "../wasm_pipe_types" }
|
||||||
|
console-subscriber = "0.1.10"
|
||||||
|
itertools = "0.11.0"
|
||||||
|
@ -10,4 +10,4 @@ cp ../../site_build/output/* .
|
|||||||
cp ../../site_build/src/main.html .
|
cp ../../site_build/src/main.html .
|
||||||
cp ../../site_build/wasm/wasm_pipe_bg.wasm .
|
cp ../../site_build/wasm/wasm_pipe_bg.wasm .
|
||||||
popd
|
popd
|
||||||
RUST_LOG=info RUST_BACKTRACE=1 cargo run
|
RUST_LOG=info RUST_BACKTRACE=1 cargo run --release
|
||||||
|
@ -1,10 +1,31 @@
|
|||||||
mod web;
|
mod web;
|
||||||
use tracing::{info, error};
|
use tracing::{error, info};
|
||||||
|
use tracing_subscriber::fmt::format::FmtSpan;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
// install global collector configured based on RUST_LOG env var.
|
// install global collector configured based on RUST_LOG env var.
|
||||||
tracing_subscriber::fmt::init();
|
let subscriber = tracing_subscriber::fmt()
|
||||||
|
// Use a more compact, abbreviated log format
|
||||||
|
.compact()
|
||||||
|
// Display source code file paths
|
||||||
|
.with_file(true)
|
||||||
|
// Display source code line numbers
|
||||||
|
.with_line_number(true)
|
||||||
|
// Display the thread ID an event was recorded on
|
||||||
|
.with_thread_ids(true)
|
||||||
|
// Don't display the event's target (module path)
|
||||||
|
.with_target(false)
|
||||||
|
// Include per-span timings
|
||||||
|
.with_span_events(FmtSpan::CLOSE)
|
||||||
|
// Build the subscriber
|
||||||
|
.finish();
|
||||||
|
|
||||||
|
// Set the subscriber as the default
|
||||||
|
tracing::subscriber::set_global_default(subscriber)?;
|
||||||
|
|
||||||
|
// Initialize the Tokio Console subscription
|
||||||
|
//console_subscriber::init();
|
||||||
|
|
||||||
// Get the database connection pool
|
// Get the database connection pool
|
||||||
let pool = pgdb::get_connection_pool(5).await;
|
let pool = pgdb::get_connection_pool(5).await;
|
||||||
|
@ -0,0 +1,199 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
use influxdb2::{Client, models::Query};
|
||||||
|
use influxdb2_structmap::FromMap;
|
||||||
|
use pgdb::{sqlx::{Pool, Postgres}, organization_cache::get_org_details, OrganizationDetails};
|
||||||
|
use anyhow::{Result, Error};
|
||||||
|
use tracing::instrument;
|
||||||
|
use super::queries::time_period::InfluxTimePeriod;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InfluxQueryBuilder {
|
||||||
|
imports: Vec<String>,
|
||||||
|
fields: Vec<String>,
|
||||||
|
period: InfluxTimePeriod,
|
||||||
|
measurement: Option<String>,
|
||||||
|
group_by: Vec<String>,
|
||||||
|
aggregate_window: bool,
|
||||||
|
yield_as: Option<String>,
|
||||||
|
host_id: Option<String>,
|
||||||
|
filters: Vec<String>,
|
||||||
|
sample_after_org: bool,
|
||||||
|
fill_empty: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InfluxQueryBuilder {
|
||||||
|
pub fn new(period: InfluxTimePeriod) -> Self {
|
||||||
|
Self {
|
||||||
|
fields: Vec::new(),
|
||||||
|
imports: Vec::new(),
|
||||||
|
group_by: Vec::new(),
|
||||||
|
period,
|
||||||
|
measurement: None,
|
||||||
|
aggregate_window: true,
|
||||||
|
yield_as: Some("last".to_string()),
|
||||||
|
host_id: None,
|
||||||
|
filters: Vec::new(),
|
||||||
|
sample_after_org: false,
|
||||||
|
fill_empty: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_measurement<S: ToString>(mut self, measurement: S) -> Self {
|
||||||
|
self.measurement = Some(measurement.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_import<S: ToString>(mut self, import: S) -> Self {
|
||||||
|
self.imports.push(import.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_field<S: ToString>(mut self, field: S) -> Self {
|
||||||
|
self.fields.push(field.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_fields<S: ToString>(mut self, fields: &[S]) -> Self {
|
||||||
|
for field in fields.iter() {
|
||||||
|
self.fields.push(field.to_string());
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_group<S: ToString>(mut self, group: S) -> Self {
|
||||||
|
self.group_by.push(group.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_groups<S: ToString>(mut self, group: &[S]) -> Self {
|
||||||
|
for group in group.iter() {
|
||||||
|
self.group_by.push(group.to_string());
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_host_id<S: ToString>(mut self, host_id: S) -> Self {
|
||||||
|
self.host_id = Some(host_id.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sample_no_window(mut self) -> Self {
|
||||||
|
self.aggregate_window = false;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_filter<S: ToString>(mut self, filter: S) -> Self {
|
||||||
|
self.filters.push(filter.to_string());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sample_after_org(mut self) -> Self {
|
||||||
|
self.sample_after_org = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fill_empty(mut self) -> Self {
|
||||||
|
self.fill_empty = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_query(&self, org: &OrganizationDetails) -> String {
|
||||||
|
let mut lines = Vec::<String>::with_capacity(10);
|
||||||
|
|
||||||
|
// Add any import stanzas
|
||||||
|
self.imports.iter().for_each(|i| lines.push(format!("import \"{i}\"")));
|
||||||
|
|
||||||
|
// Add the bucket
|
||||||
|
lines.push(format!("from(bucket: \"{}\")", org.influx_bucket));
|
||||||
|
|
||||||
|
// Add a range limit
|
||||||
|
lines.push(format!("|> {}", self.period.range()));
|
||||||
|
|
||||||
|
// Add the measurement filter
|
||||||
|
if let Some(measurement) = &self.measurement {
|
||||||
|
lines.push(format!("|> filter(fn: (r) => r[\"_measurement\"] == \"{}\")", measurement));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add fields filters
|
||||||
|
if !self.fields.is_empty() {
|
||||||
|
let mut fields = String::new();
|
||||||
|
for field in self.fields.iter() {
|
||||||
|
if !fields.is_empty() {
|
||||||
|
fields.push_str(" or ");
|
||||||
|
}
|
||||||
|
fields.push_str(&format!("r[\"_field\"] == \"{}\"", field));
|
||||||
|
}
|
||||||
|
lines.push(format!("|> filter(fn: (r) => {})", fields));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by organization id
|
||||||
|
lines.push(format!("|> filter(fn: (r) => r[\"organization_id\"] == \"{}\")", org.key));
|
||||||
|
|
||||||
|
if self.sample_after_org {
|
||||||
|
lines.push(format!("|> {}", self.period.sample()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by host_id
|
||||||
|
if let Some(host_id) = &self.host_id {
|
||||||
|
lines.push(format!("|> filter(fn: (r) => r[\"host_id\"] == \"{}\")", host_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any other filters
|
||||||
|
for filter in self.filters.iter() {
|
||||||
|
lines.push(format!("|> filter(fn: (r) => {})", filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group by
|
||||||
|
if !self.group_by.is_empty() {
|
||||||
|
let mut group_by = String::new();
|
||||||
|
for group in self.group_by.iter() {
|
||||||
|
if !group_by.is_empty() {
|
||||||
|
group_by.push_str(", ");
|
||||||
|
}
|
||||||
|
group_by.push_str(&format!("\"{}\"", group));
|
||||||
|
}
|
||||||
|
lines.push(format!("|> group(columns: [{}])", group_by));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggregate Window
|
||||||
|
if self.aggregate_window {
|
||||||
|
if self.fill_empty {
|
||||||
|
lines.push(format!("|> {}", self.period.aggregate_window_empty()));
|
||||||
|
} else {
|
||||||
|
lines.push(format!("|> {}", self.period.aggregate_window()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lines.push(format!("|> {}", self.period.sample()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yield as
|
||||||
|
if let Some(yield_as) = &self.yield_as {
|
||||||
|
lines.push(format!("|> yield(name: \"{}\")", yield_as));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine
|
||||||
|
lines.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(self, cnn, key))]
|
||||||
|
pub async fn execute<T>(&self, cnn: &Pool<Postgres>, key: &str) -> Result<Vec<T>>
|
||||||
|
where T: FromMap + std::fmt::Debug
|
||||||
|
{
|
||||||
|
if let Some(org) = get_org_details(cnn, key).await {
|
||||||
|
let influx_url = format!("http://{}:8086", org.influx_host);
|
||||||
|
let client = Client::new(influx_url, &org.influx_org, &org.influx_token);
|
||||||
|
let query_string = self.build_query(&org);
|
||||||
|
tracing::info!("{query_string}");
|
||||||
|
let query = Query::new(query_string);
|
||||||
|
let rows = client.query::<T>(Some(query)).await;
|
||||||
|
if let Ok(rows) = rows {
|
||||||
|
Ok(rows)
|
||||||
|
} else {
|
||||||
|
tracing::error!("InfluxDb query error: {rows:?}");
|
||||||
|
Err(Error::msg("Influx query error"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(Error::msg("Organization not found"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
use axum::extract::ws::WebSocket;
|
use axum::extract::ws::WebSocket;
|
||||||
use pgdb::sqlx::{Pool, Postgres};
|
use pgdb::sqlx::{Pool, Postgres};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use tracing::instrument;
|
||||||
use wasm_pipe_types::WasmResponse;
|
use wasm_pipe_types::WasmResponse;
|
||||||
|
|
||||||
use super::send_response;
|
use super::send_response;
|
||||||
@ -13,6 +14,7 @@ pub struct LoginResult {
|
|||||||
pub license_key: String,
|
pub license_key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(license, username, password, socket, cnn))]
|
||||||
pub async fn on_login(license: &str, username: &str, password: &str, socket: &mut WebSocket, cnn: Pool<Postgres>) -> Option<LoginResult> {
|
pub async fn on_login(license: &str, username: &str, password: &str, socket: &mut WebSocket, cnn: Pool<Postgres>) -> Option<LoginResult> {
|
||||||
let login = pgdb::try_login(cnn, license, username, password).await;
|
let login = pgdb::try_login(cnn, license, username, password).await;
|
||||||
if let Ok(login) = login {
|
if let Ok(login) = login {
|
||||||
@ -35,6 +37,7 @@ pub async fn on_login(license: &str, username: &str, password: &str, socket: &mu
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(token_id, socket, cnn))]
|
||||||
pub async fn on_token_auth(token_id: &str, socket: &mut WebSocket, cnn: Pool<Postgres>) -> Option<LoginResult> {
|
pub async fn on_token_auth(token_id: &str, socket: &mut WebSocket, cnn: Pool<Postgres>) -> Option<LoginResult> {
|
||||||
let login = pgdb::token_to_credentials(cnn, token_id).await;
|
let login = pgdb::token_to_credentials(cnn, token_id).await;
|
||||||
if let Ok(login) = login {
|
if let Ok(login) = login {
|
||||||
|
@ -8,6 +8,7 @@ use crate::web::wss::{
|
|||||||
omnisearch, root_heat_map, send_circuit_info, send_packets_for_all_nodes,
|
omnisearch, root_heat_map, send_circuit_info, send_packets_for_all_nodes,
|
||||||
send_packets_for_node, send_perf_for_node, send_rtt_for_all_nodes,
|
send_packets_for_node, send_perf_for_node, send_rtt_for_all_nodes,
|
||||||
send_rtt_for_all_nodes_circuit, send_rtt_for_all_nodes_site, send_rtt_for_node,
|
send_rtt_for_all_nodes_circuit, send_rtt_for_all_nodes_site, send_rtt_for_node,
|
||||||
|
send_rtt_histogram_for_all_nodes,
|
||||||
send_site_info, send_site_parents, send_site_stack_map, send_throughput_for_all_nodes,
|
send_site_info, send_site_parents, send_site_stack_map, send_throughput_for_all_nodes,
|
||||||
send_throughput_for_all_nodes_by_circuit, send_throughput_for_all_nodes_by_site,
|
send_throughput_for_all_nodes_by_circuit, send_throughput_for_all_nodes_by_site,
|
||||||
send_throughput_for_node, site_heat_map,
|
send_throughput_for_node, site_heat_map,
|
||||||
@ -24,10 +25,12 @@ use axum::{
|
|||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
};
|
};
|
||||||
use pgdb::sqlx::{Pool, Postgres};
|
use pgdb::sqlx::{Pool, Postgres};
|
||||||
|
use tracing::instrument;
|
||||||
use wasm_pipe_types::{WasmRequest, WasmResponse};
|
use wasm_pipe_types::{WasmRequest, WasmResponse};
|
||||||
mod login;
|
mod login;
|
||||||
mod nodes;
|
mod nodes;
|
||||||
mod queries;
|
mod queries;
|
||||||
|
mod influx_query_builder;
|
||||||
|
|
||||||
pub async fn ws_handler(
|
pub async fn ws_handler(
|
||||||
ws: WebSocketUpgrade,
|
ws: WebSocketUpgrade,
|
||||||
@ -168,6 +171,15 @@ async fn handle_socket(mut socket: WebSocket, cnn: Pool<Postgres>) {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
(WasmRequest::RttHistogram { period }, Some(credentials)) => {
|
||||||
|
let _ = send_rtt_histogram_for_all_nodes(
|
||||||
|
&cnn,
|
||||||
|
wss,
|
||||||
|
&credentials.license_key,
|
||||||
|
InfluxTimePeriod::new(period),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
(WasmRequest::RttChartSite { period, site_id }, Some(credentials)) => {
|
(WasmRequest::RttChartSite { period, site_id }, Some(credentials)) => {
|
||||||
let _ = send_rtt_for_all_nodes_site(
|
let _ = send_rtt_for_all_nodes_site(
|
||||||
&cnn,
|
&cnn,
|
||||||
@ -310,6 +322,7 @@ fn serialize_response(response: WasmResponse) -> Vec<u8> {
|
|||||||
miniz_oxide::deflate::compress_to_vec(&cbor, 8)
|
miniz_oxide::deflate::compress_to_vec(&cbor, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(socket, response))]
|
||||||
pub async fn send_response(socket: &mut WebSocket, response: WasmResponse) {
|
pub async fn send_response(socket: &mut WebSocket, response: WasmResponse) {
|
||||||
let serialized = serialize_response(response);
|
let serialized = serialize_response(response);
|
||||||
socket.send(Message::Binary(serialized)).await.unwrap();
|
socket.send(Message::Binary(serialized)).await.unwrap();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use axum::extract::ws::WebSocket;
|
use axum::extract::ws::WebSocket;
|
||||||
use pgdb::sqlx::{Pool, Postgres};
|
use pgdb::sqlx::{Pool, Postgres};
|
||||||
|
use tracing::instrument;
|
||||||
use wasm_pipe_types::Node;
|
use wasm_pipe_types::Node;
|
||||||
|
|
||||||
use crate::web::wss::send_response;
|
use crate::web::wss::send_response;
|
||||||
@ -12,6 +13,7 @@ fn convert(ns: pgdb::NodeStatus) -> Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cnn, socket, key))]
|
||||||
pub async fn node_status(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str) {
|
pub async fn node_status(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str) {
|
||||||
tracing::info!("Fetching node status, {key}");
|
tracing::info!("Fetching node status, {key}");
|
||||||
let nodes = pgdb::node_status(cnn, key).await;
|
let nodes = pgdb::node_status(cnn, key).await;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
//! then be used by the web server to respond to requests.
|
//! then be used by the web server to respond to requests.
|
||||||
|
|
||||||
mod circuit_info;
|
mod circuit_info;
|
||||||
|
pub mod ext_device;
|
||||||
mod node_perf;
|
mod node_perf;
|
||||||
mod packet_counts;
|
mod packet_counts;
|
||||||
mod rtt;
|
mod rtt;
|
||||||
@ -11,18 +12,19 @@ mod site_info;
|
|||||||
mod site_parents;
|
mod site_parents;
|
||||||
pub mod site_tree;
|
pub mod site_tree;
|
||||||
mod throughput;
|
mod throughput;
|
||||||
pub mod ext_device;
|
|
||||||
pub mod time_period;
|
pub mod time_period;
|
||||||
pub use circuit_info::send_circuit_info;
|
pub use circuit_info::send_circuit_info;
|
||||||
pub use node_perf::send_perf_for_node;
|
pub use node_perf::send_perf_for_node;
|
||||||
pub use packet_counts::{send_packets_for_all_nodes, send_packets_for_node};
|
pub use packet_counts::{send_packets_for_all_nodes, send_packets_for_node};
|
||||||
pub use rtt::{send_rtt_for_all_nodes, send_rtt_for_all_nodes_site, send_rtt_for_node, send_rtt_for_all_nodes_circuit};
|
pub use rtt::{
|
||||||
|
send_rtt_for_all_nodes, send_rtt_for_all_nodes_circuit, send_rtt_for_all_nodes_site,
|
||||||
|
send_rtt_for_node, send_rtt_histogram_for_all_nodes,
|
||||||
|
};
|
||||||
pub use search::omnisearch;
|
pub use search::omnisearch;
|
||||||
pub use site_heat_map::{root_heat_map, site_heat_map};
|
pub use site_heat_map::{root_heat_map, site_heat_map};
|
||||||
pub use site_info::send_site_info;
|
pub use site_info::send_site_info;
|
||||||
pub use site_parents::{send_site_parents, send_circuit_parents, send_root_parents};
|
pub use site_parents::{send_circuit_parents, send_root_parents, send_site_parents};
|
||||||
pub use throughput::{
|
pub use throughput::{
|
||||||
send_throughput_for_all_nodes, send_throughput_for_all_nodes_by_circuit,
|
send_site_stack_map, send_throughput_for_all_nodes, send_throughput_for_all_nodes_by_circuit,
|
||||||
send_throughput_for_all_nodes_by_site, send_throughput_for_node,
|
send_throughput_for_all_nodes_by_site, send_throughput_for_node,
|
||||||
send_site_stack_map,
|
|
||||||
};
|
};
|
||||||
|
@ -2,24 +2,78 @@
|
|||||||
mod packet_row;
|
mod packet_row;
|
||||||
use self::packet_row::PacketRow;
|
use self::packet_row::PacketRow;
|
||||||
use super::time_period::InfluxTimePeriod;
|
use super::time_period::InfluxTimePeriod;
|
||||||
use crate::web::wss::send_response;
|
use crate::web::wss::{influx_query_builder::InfluxQueryBuilder, send_response};
|
||||||
use axum::extract::ws::WebSocket;
|
use axum::extract::ws::WebSocket;
|
||||||
use futures::future::join_all;
|
use pgdb::sqlx::{Pool, Postgres};
|
||||||
use influxdb2::{models::Query, Client};
|
use tracing::instrument;
|
||||||
use pgdb::{sqlx::{Pool, Postgres}, organization_cache::get_org_details};
|
|
||||||
use wasm_pipe_types::{PacketHost, Packets};
|
use wasm_pipe_types::{PacketHost, Packets};
|
||||||
|
|
||||||
|
fn add_by_direction(direction: &str, down: &mut Vec<Packets>, up: &mut Vec<Packets>, row: &PacketRow) {
|
||||||
|
match direction {
|
||||||
|
"down" => {
|
||||||
|
down.push(Packets {
|
||||||
|
value: row.avg,
|
||||||
|
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
l: row.min,
|
||||||
|
u: row.max - row.min,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"up" => {
|
||||||
|
up.push(Packets {
|
||||||
|
value: row.avg,
|
||||||
|
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
l: row.min,
|
||||||
|
u: row.max - row.min,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cnn, socket, key, period))]
|
||||||
pub async fn send_packets_for_all_nodes(
|
pub async fn send_packets_for_all_nodes(
|
||||||
cnn: &Pool<Postgres>,
|
cnn: &Pool<Postgres>,
|
||||||
socket: &mut WebSocket,
|
socket: &mut WebSocket,
|
||||||
key: &str,
|
key: &str,
|
||||||
period: InfluxTimePeriod,
|
period: InfluxTimePeriod,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let nodes = get_packets_for_all_nodes(cnn, key, period).await?;
|
let node_status = pgdb::node_status(cnn, key).await?;
|
||||||
|
let mut nodes = Vec::<PacketHost>::new();
|
||||||
|
InfluxQueryBuilder::new(period.clone())
|
||||||
|
.with_measurement("packets")
|
||||||
|
.with_fields(&["min", "max", "avg"])
|
||||||
|
.with_groups(&["host_id", "min", "max", "avg", "direction", "_field"])
|
||||||
|
.execute::<PacketRow>(cnn, key)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|row| {
|
||||||
|
if let Some(node) = nodes.iter_mut().find(|n| n.node_id == row.host_id) {
|
||||||
|
add_by_direction(&row.direction, &mut node.down, &mut node.up, &row);
|
||||||
|
} else {
|
||||||
|
let mut down = Vec::new();
|
||||||
|
let mut up = Vec::new();
|
||||||
|
|
||||||
|
add_by_direction(&row.direction, &mut down, &mut up, &row);
|
||||||
|
|
||||||
|
let node_name = if let Some(node) = node_status.iter().find(|n| n.node_id == row.host_id) {
|
||||||
|
node.node_name.clone()
|
||||||
|
} else {
|
||||||
|
row.host_id.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.push(PacketHost {
|
||||||
|
node_id: row.host_id,
|
||||||
|
node_name,
|
||||||
|
down,
|
||||||
|
up,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
send_response(socket, wasm_pipe_types::WasmResponse::PacketChart { nodes }).await;
|
send_response(socket, wasm_pipe_types::WasmResponse::PacketChart { nodes }).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cnn, socket, key, period))]
|
||||||
pub async fn send_packets_for_node(
|
pub async fn send_packets_for_node(
|
||||||
cnn: &Pool<Postgres>,
|
cnn: &Pool<Postgres>,
|
||||||
socket: &mut WebSocket,
|
socket: &mut WebSocket,
|
||||||
@ -39,31 +93,6 @@ pub async fn send_packets_for_node(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Requests packet-per-second data for all shaper nodes for a given organization
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
/// * `cnn` - A connection pool to the database
|
|
||||||
/// * `key` - The organization's license key
|
|
||||||
pub async fn get_packets_for_all_nodes(
|
|
||||||
cnn: &Pool<Postgres>,
|
|
||||||
key: &str,
|
|
||||||
period: InfluxTimePeriod,
|
|
||||||
) -> anyhow::Result<Vec<PacketHost>> {
|
|
||||||
let node_status = pgdb::node_status(cnn, key).await?;
|
|
||||||
let mut futures = Vec::new();
|
|
||||||
for node in node_status {
|
|
||||||
futures.push(get_packets_for_node(
|
|
||||||
cnn,
|
|
||||||
key,
|
|
||||||
node.node_id.to_string(),
|
|
||||||
node.node_name.to_string(),
|
|
||||||
period.clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let all_nodes: anyhow::Result<Vec<PacketHost>> = join_all(futures).await.into_iter().collect();
|
|
||||||
all_nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Requests packet-per-second data for a single shaper node.
|
/// Requests packet-per-second data for a single shaper node.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
@ -78,67 +107,53 @@ pub async fn get_packets_for_node(
|
|||||||
node_name: String,
|
node_name: String,
|
||||||
period: InfluxTimePeriod,
|
period: InfluxTimePeriod,
|
||||||
) -> anyhow::Result<PacketHost> {
|
) -> anyhow::Result<PacketHost> {
|
||||||
if let Some(org) = get_org_details(cnn, key).await {
|
let rows = InfluxQueryBuilder::new(period.clone())
|
||||||
let influx_url = format!("http://{}:8086", org.influx_host);
|
.with_measurement("packets")
|
||||||
let client = Client::new(influx_url, &org.influx_org, &org.influx_token);
|
.with_host_id(&node_id)
|
||||||
|
.with_field("min")
|
||||||
|
.with_field("max")
|
||||||
|
.with_field("avg")
|
||||||
|
.execute::<PacketRow>(cnn, key)
|
||||||
|
.await;
|
||||||
|
|
||||||
let qs = format!(
|
match rows {
|
||||||
"from(bucket: \"{}\")
|
Err(e) => {
|
||||||
|> {}
|
tracing::error!("Error querying InfluxDB (packets by node): {}", e);
|
||||||
|> filter(fn: (r) => r[\"_measurement\"] == \"packets\")
|
Err(anyhow::Error::msg("Unable to query influx"))
|
||||||
|> filter(fn: (r) => r[\"organization_id\"] == \"{}\")
|
}
|
||||||
|> filter(fn: (r) => r[\"host_id\"] == \"{}\")
|
Ok(rows) => {
|
||||||
|> {}
|
// Parse and send the data
|
||||||
|> yield(name: \"last\")",
|
//println!("{rows:?}");
|
||||||
org.influx_bucket,
|
|
||||||
period.range(),
|
|
||||||
org.key,
|
|
||||||
node_id,
|
|
||||||
period.aggregate_window()
|
|
||||||
);
|
|
||||||
|
|
||||||
let query = Query::new(qs);
|
let mut down = Vec::new();
|
||||||
let rows = client.query::<PacketRow>(Some(query)).await;
|
let mut up = Vec::new();
|
||||||
match rows {
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("Error querying InfluxDB (packets by node): {}", e);
|
|
||||||
return Err(anyhow::Error::msg("Unable to query influx"));
|
|
||||||
}
|
|
||||||
Ok(rows) => {
|
|
||||||
// Parse and send the data
|
|
||||||
//println!("{rows:?}");
|
|
||||||
|
|
||||||
let mut down = Vec::new();
|
// Fill download
|
||||||
let mut up = Vec::new();
|
for row in rows.iter().filter(|r| r.direction == "down") {
|
||||||
|
down.push(Packets {
|
||||||
// Fill download
|
value: row.avg,
|
||||||
for row in rows.iter().filter(|r| r.direction == "down") {
|
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
down.push(Packets {
|
l: row.min,
|
||||||
value: row.avg,
|
u: row.max - row.min,
|
||||||
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
|
||||||
l: row.min,
|
|
||||||
u: row.max - row.min,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill upload
|
|
||||||
for row in rows.iter().filter(|r| r.direction == "up") {
|
|
||||||
up.push(Packets {
|
|
||||||
value: row.avg,
|
|
||||||
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
|
||||||
l: row.min,
|
|
||||||
u: row.max - row.min,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(PacketHost {
|
|
||||||
node_id,
|
|
||||||
node_name,
|
|
||||||
down,
|
|
||||||
up,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fill upload
|
||||||
|
for row in rows.iter().filter(|r| r.direction == "up") {
|
||||||
|
up.push(Packets {
|
||||||
|
value: row.avg,
|
||||||
|
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
l: row.min,
|
||||||
|
u: row.max - row.min,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(PacketHost {
|
||||||
|
node_id,
|
||||||
|
node_name,
|
||||||
|
down,
|
||||||
|
up,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(anyhow::Error::msg("Unable to query influx"))
|
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,18 @@
|
|||||||
|
mod per_node;
|
||||||
|
pub use per_node::*;
|
||||||
|
|
||||||
use axum::extract::ws::WebSocket;
|
use axum::extract::ws::WebSocket;
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use influxdb2::{Client, models::Query};
|
use influxdb2::{Client, models::Query};
|
||||||
use pgdb::{sqlx::{Pool, Postgres}, organization_cache::get_org_details};
|
use pgdb::{sqlx::{Pool, Postgres}, organization_cache::get_org_details};
|
||||||
|
use tracing::instrument;
|
||||||
use wasm_pipe_types::{RttHost, Rtt};
|
use wasm_pipe_types::{RttHost, Rtt};
|
||||||
use crate::web::wss::{queries::rtt::rtt_row::RttCircuitRow, send_response};
|
use crate::web::wss::{queries::rtt::rtt_row::RttCircuitRow, send_response};
|
||||||
use self::rtt_row::{RttRow, RttSiteRow};
|
use self::rtt_row::{RttRow, RttSiteRow};
|
||||||
|
|
||||||
use super::time_period::InfluxTimePeriod;
|
use super::time_period::InfluxTimePeriod;
|
||||||
mod rtt_row;
|
mod rtt_row;
|
||||||
|
|
||||||
pub async fn send_rtt_for_all_nodes(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str, period: InfluxTimePeriod) -> anyhow::Result<()> {
|
#[instrument(skip(cnn, socket, key, site_id, period))]
|
||||||
let nodes = get_rtt_for_all_nodes(cnn, key, period).await?;
|
|
||||||
|
|
||||||
let mut histogram = vec![0; 20];
|
|
||||||
for node in nodes.iter() {
|
|
||||||
for rtt in node.rtt.iter() {
|
|
||||||
let bucket = usize::min(19, (rtt.value / 10.0) as usize);
|
|
||||||
histogram[bucket] += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let nodes = vec![RttHost { node_id: "".to_string(), node_name: "".to_string(), rtt: rtt_bucket_merge(&nodes) }];
|
|
||||||
send_response(socket, wasm_pipe_types::WasmResponse::RttChart { nodes, histogram }).await;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn send_rtt_for_all_nodes_site(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str, site_id: String, period: InfluxTimePeriod) -> anyhow::Result<()> {
|
pub async fn send_rtt_for_all_nodes_site(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str, site_id: String, period: InfluxTimePeriod) -> anyhow::Result<()> {
|
||||||
let nodes = get_rtt_for_all_nodes_site(cnn, key, &site_id, period).await?;
|
let nodes = get_rtt_for_all_nodes_site(cnn, key, &site_id, period).await?;
|
||||||
|
|
||||||
@ -40,6 +28,7 @@ pub async fn send_rtt_for_all_nodes_site(cnn: &Pool<Postgres>, socket: &mut WebS
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cnn, socket, key, site_id, period))]
|
||||||
pub async fn send_rtt_for_all_nodes_circuit(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str, site_id: String, period: InfluxTimePeriod) -> anyhow::Result<()> {
|
pub async fn send_rtt_for_all_nodes_circuit(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str, site_id: String, period: InfluxTimePeriod) -> anyhow::Result<()> {
|
||||||
let nodes = get_rtt_for_all_nodes_circuit(cnn, key, &site_id, period).await?;
|
let nodes = get_rtt_for_all_nodes_circuit(cnn, key, &site_id, period).await?;
|
||||||
|
|
||||||
@ -59,50 +48,18 @@ pub async fn send_rtt_for_node(cnn: &Pool<Postgres>, socket: &mut WebSocket, key
|
|||||||
let node = get_rtt_for_node(cnn, key, node_id, node_name, period).await?;
|
let node = get_rtt_for_node(cnn, key, node_id, node_name, period).await?;
|
||||||
let nodes = vec![node];
|
let nodes = vec![node];
|
||||||
|
|
||||||
let mut histogram = vec![0; 20];
|
/*let mut histogram = vec![0; 20];
|
||||||
for node in nodes.iter() {
|
for node in nodes.iter() {
|
||||||
for rtt in node.rtt.iter() {
|
for rtt in node.rtt.iter() {
|
||||||
let bucket = usize::min(19, (rtt.value / 200.0) as usize);
|
let bucket = usize::min(19, (rtt.value / 200.0) as usize);
|
||||||
histogram[bucket] += 1;
|
histogram[bucket] += 1;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
send_response(socket, wasm_pipe_types::WasmResponse::RttChart { nodes, histogram }).await;
|
send_response(socket, wasm_pipe_types::WasmResponse::RttChart { nodes }).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rtt_bucket_merge(rtt: &[RttHost]) -> Vec<Rtt> {
|
|
||||||
let mut entries: Vec<Rtt> = Vec::new();
|
|
||||||
for entry in rtt.iter() {
|
|
||||||
for entry in entry.rtt.iter() {
|
|
||||||
if let Some(e) = entries.iter().position(|d| d.date == entry.date) {
|
|
||||||
entries[e].l = f64::min(entries[e].l, entry.l);
|
|
||||||
entries[e].u = f64::max(entries[e].u, entry.u);
|
|
||||||
} else {
|
|
||||||
entries.push(entry.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entries
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_rtt_for_all_nodes(cnn: &Pool<Postgres>, key: &str, period: InfluxTimePeriod) -> anyhow::Result<Vec<RttHost>> {
|
|
||||||
let node_status = pgdb::node_status(cnn, key).await?;
|
|
||||||
let mut futures = Vec::new();
|
|
||||||
for node in node_status {
|
|
||||||
futures.push(get_rtt_for_node(
|
|
||||||
cnn,
|
|
||||||
key,
|
|
||||||
node.node_id.to_string(),
|
|
||||||
node.node_name.to_string(),
|
|
||||||
period.clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let all_nodes: anyhow::Result<Vec<RttHost>> = join_all(futures).await
|
|
||||||
.into_iter().collect();
|
|
||||||
all_nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_rtt_for_all_nodes_site(cnn: &Pool<Postgres>, key: &str, site_id: &str, period: InfluxTimePeriod) -> anyhow::Result<Vec<RttHost>> {
|
pub async fn get_rtt_for_all_nodes_site(cnn: &Pool<Postgres>, key: &str, site_id: &str, period: InfluxTimePeriod) -> anyhow::Result<Vec<RttHost>> {
|
||||||
let node_status = pgdb::node_status(cnn, key).await?;
|
let node_status = pgdb::node_status(cnn, key).await?;
|
||||||
let mut futures = Vec::new();
|
let mut futures = Vec::new();
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
use crate::web::wss::{queries::time_period::InfluxTimePeriod, send_response, influx_query_builder::InfluxQueryBuilder};
|
||||||
|
use axum::extract::ws::WebSocket;
|
||||||
|
use pgdb::{
|
||||||
|
sqlx::{Pool, Postgres},
|
||||||
|
NodeStatus
|
||||||
|
};
|
||||||
|
use tracing::instrument;
|
||||||
|
use wasm_pipe_types::{Rtt, RttHost};
|
||||||
|
|
||||||
|
use super::rtt_row::{RttRow, RttHistoRow};
|
||||||
|
|
||||||
|
#[instrument(skip(cnn, socket, key, period))]
|
||||||
|
pub async fn send_rtt_for_all_nodes(
|
||||||
|
cnn: &Pool<Postgres>,
|
||||||
|
socket: &mut WebSocket,
|
||||||
|
key: &str,
|
||||||
|
period: InfluxTimePeriod,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let rows = InfluxQueryBuilder::new(period.clone())
|
||||||
|
.with_measurement("rtt")
|
||||||
|
.with_fields(&["avg", "min", "max"])
|
||||||
|
.with_groups(&["host_id", "_field"])
|
||||||
|
.execute::<RttRow>(cnn, key)
|
||||||
|
.await?;
|
||||||
|
let node_status = pgdb::node_status(cnn, key).await?;
|
||||||
|
let nodes = rtt_rows_to_result(rows, node_status);
|
||||||
|
send_response(socket, wasm_pipe_types::WasmResponse::RttChart { nodes }).await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cnn, socket, key, period))]
|
||||||
|
pub async fn send_rtt_histogram_for_all_nodes(
|
||||||
|
cnn: &Pool<Postgres>,
|
||||||
|
socket: &mut WebSocket,
|
||||||
|
key: &str,
|
||||||
|
period: InfluxTimePeriod,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let rows = InfluxQueryBuilder::new(period.clone())
|
||||||
|
.with_measurement("rtt")
|
||||||
|
.with_field("avg")
|
||||||
|
.sample_no_window()
|
||||||
|
.execute::<RttHistoRow>(cnn, key)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let mut histo = vec![0u32; 20];
|
||||||
|
rows.iter().for_each(|row| {
|
||||||
|
let rtt = f64::min(row.avg, 200.);
|
||||||
|
let bucket = usize::min((rtt / 10.0) as usize, 19);
|
||||||
|
histo[bucket] += 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
send_response(socket, wasm_pipe_types::WasmResponse::RttHistogram { histogram: histo }).await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rtt_rows_to_result(rows: Vec<RttRow>, node_status: Vec<NodeStatus>) -> Vec<RttHost> {
|
||||||
|
let mut result = Vec::<RttHost>::new();
|
||||||
|
for row in rows.into_iter() {
|
||||||
|
if let Some(host) = result.iter_mut().find(|h| h.node_id == row.host_id) {
|
||||||
|
// We found one - add to it
|
||||||
|
host.rtt.push(Rtt {
|
||||||
|
value: f64::min(200.0, row.avg),
|
||||||
|
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
l: f64::min(200.0, row.min),
|
||||||
|
u: f64::min(200.0, row.max) - f64::min(200.0, row.min),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let rtt = vec![Rtt {
|
||||||
|
value: f64::min(200.0, row.avg),
|
||||||
|
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
l: f64::min(200.0, row.min),
|
||||||
|
u: f64::min(200.0, row.max) - f64::min(200.0, row.min),
|
||||||
|
}];
|
||||||
|
|
||||||
|
let node_name = node_status
|
||||||
|
.iter()
|
||||||
|
.filter(|n| n.node_id == row.host_id)
|
||||||
|
.map(|n| n.node_name.clone())
|
||||||
|
.next()
|
||||||
|
.unwrap_or("".to_string());
|
||||||
|
|
||||||
|
let new_host = RttHost {
|
||||||
|
node_id: row.host_id,
|
||||||
|
node_name,
|
||||||
|
rtt,
|
||||||
|
};
|
||||||
|
result.push(new_host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
@ -22,6 +22,11 @@ impl Default for RttRow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, FromDataPoint, Default)]
|
||||||
|
pub struct RttHistoRow {
|
||||||
|
pub avg: f64,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, FromDataPoint)]
|
#[derive(Debug, FromDataPoint)]
|
||||||
pub struct RttSiteRow {
|
pub struct RttSiteRow {
|
||||||
pub host_id: String,
|
pub host_id: String,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::time_period::InfluxTimePeriod;
|
use super::time_period::InfluxTimePeriod;
|
||||||
|
use crate::web::wss::influx_query_builder::InfluxQueryBuilder;
|
||||||
use crate::web::wss::send_response;
|
use crate::web::wss::send_response;
|
||||||
use axum::extract::ws::WebSocket;
|
use axum::extract::ws::WebSocket;
|
||||||
use chrono::{DateTime, FixedOffset, Utc};
|
use chrono::{DateTime, FixedOffset, Utc};
|
||||||
@ -8,16 +9,50 @@ use pgdb::organization_cache::get_org_details;
|
|||||||
use pgdb::sqlx::{query, Pool, Postgres, Row};
|
use pgdb::sqlx::{query, Pool, Postgres, Row};
|
||||||
use pgdb::OrganizationDetails;
|
use pgdb::OrganizationDetails;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use tracing::instrument;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use wasm_pipe_types::WasmResponse;
|
use wasm_pipe_types::WasmResponse;
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
#[instrument(skip(cnn,socket,key,period))]
|
||||||
pub async fn root_heat_map(
|
pub async fn root_heat_map(
|
||||||
cnn: &Pool<Postgres>,
|
cnn: &Pool<Postgres>,
|
||||||
socket: &mut WebSocket,
|
socket: &mut WebSocket,
|
||||||
key: &str,
|
key: &str,
|
||||||
period: InfluxTimePeriod,
|
period: InfluxTimePeriod,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
if let Some(org) = get_org_details(cnn, key).await {
|
let rows: Vec<HeatRow> = InfluxQueryBuilder::new(period.clone())
|
||||||
|
.with_import("strings")
|
||||||
|
.with_measurement("tree")
|
||||||
|
.with_fields(&["rtt_avg"])
|
||||||
|
.sample_after_org()
|
||||||
|
.with_filter("exists(r[\"node_parents\"])")
|
||||||
|
.with_filter("strings.hasSuffix(suffix: \"S0S\" + r[\"node_index\"] + \"S\", v: r[\"node_parents\"])")
|
||||||
|
.with_filter("r[\"_value\"] > 0.0")
|
||||||
|
.with_groups(&["_field", "node_name"])
|
||||||
|
.execute(cnn, key)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let mut headings = rows.iter().map(|r| r.time).collect::<Vec<_>>();
|
||||||
|
headings.sort();
|
||||||
|
let headings: Vec<DateTime<FixedOffset>> = headings.iter().dedup().cloned().collect();
|
||||||
|
//println!("{headings:#?}");
|
||||||
|
let defaults = headings.iter().map(|h| (*h, 0.0)).collect::<Vec<_>>();
|
||||||
|
let mut sorter: HashMap<String, Vec<(DateTime<FixedOffset>, f64)>> = HashMap::new();
|
||||||
|
for row in rows.into_iter() {
|
||||||
|
let entry = sorter.entry(row.node_name).or_insert(defaults.clone());
|
||||||
|
if let Some(idx) = headings.iter().position(|h| h == &row.time) {
|
||||||
|
entry[idx] = (row.time, row.rtt_avg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//println!("{:?}", sorter);
|
||||||
|
send_response(socket, WasmResponse::RootHeat { data: sorter }).await;
|
||||||
|
|
||||||
|
|
||||||
|
/*if let Some(org) = get_org_details(cnn, key).await {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let influx_url = format!("http://{}:8086", org.influx_host);
|
let influx_url = format!("http://{}:8086", org.influx_host);
|
||||||
let client = Client::new(influx_url, &org.influx_org, &org.influx_token);
|
let client = Client::new(influx_url, &org.influx_org, &org.influx_token);
|
||||||
|
|
||||||
@ -46,6 +81,7 @@ pub async fn root_heat_map(
|
|||||||
|> filter(fn: (r) => r[\"_measurement\"] == \"tree\")
|
|> filter(fn: (r) => r[\"_measurement\"] == \"tree\")
|
||||||
|> filter(fn: (r) => r[\"organization_id\"] == \"{}\")
|
|> filter(fn: (r) => r[\"organization_id\"] == \"{}\")
|
||||||
|> filter(fn: (r) => r[\"_field\"] == \"rtt_avg\")
|
|> filter(fn: (r) => r[\"_field\"] == \"rtt_avg\")
|
||||||
|
|> filter(fn: (r) => r[\"_value\"] > 0.0)
|
||||||
|> {}
|
|> {}
|
||||||
|> {}
|
|> {}
|
||||||
|> yield(name: \"last\")",
|
|> yield(name: \"last\")",
|
||||||
@ -55,7 +91,7 @@ pub async fn root_heat_map(
|
|||||||
host_filter,
|
host_filter,
|
||||||
period.aggregate_window()
|
period.aggregate_window()
|
||||||
);
|
);
|
||||||
//println!("{qs}");
|
println!("{qs}");
|
||||||
|
|
||||||
let query = Query::new(qs);
|
let query = Query::new(qs);
|
||||||
let rows = client.query::<HeatRow>(Some(query)).await;
|
let rows = client.query::<HeatRow>(Some(query)).await;
|
||||||
@ -76,7 +112,7 @@ pub async fn root_heat_map(
|
|||||||
send_response(socket, WasmResponse::RootHeat { data: sorter }).await;
|
send_response(socket, WasmResponse::RootHeat { data: sorter }).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -4,19 +4,70 @@ use axum::extract::ws::WebSocket;
|
|||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use influxdb2::{Client, models::Query};
|
use influxdb2::{Client, models::Query};
|
||||||
use pgdb::{sqlx::{Pool, Postgres}, organization_cache::get_org_details};
|
use pgdb::{sqlx::{Pool, Postgres}, organization_cache::get_org_details};
|
||||||
|
use tracing::instrument;
|
||||||
use wasm_pipe_types::{ThroughputHost, Throughput};
|
use wasm_pipe_types::{ThroughputHost, Throughput};
|
||||||
use crate::web::wss::send_response;
|
use crate::web::wss::{send_response, influx_query_builder::InfluxQueryBuilder};
|
||||||
use self::throughput_row::{ThroughputRow, ThroughputRowBySite, ThroughputRowByCircuit};
|
use self::throughput_row::{ThroughputRow, ThroughputRowBySite, ThroughputRowByCircuit};
|
||||||
use super::time_period::InfluxTimePeriod;
|
use super::time_period::InfluxTimePeriod;
|
||||||
mod throughput_row;
|
mod throughput_row;
|
||||||
pub use site_stack::send_site_stack_map;
|
pub use site_stack::send_site_stack_map;
|
||||||
|
|
||||||
pub async fn send_throughput_for_all_nodes(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str, period: InfluxTimePeriod) -> anyhow::Result<()> {
|
fn add_by_direction(direction: &str, down: &mut Vec<Throughput>, up: &mut Vec<Throughput>, row: &ThroughputRow) {
|
||||||
let nodes = get_throughput_for_all_nodes(cnn, key, period).await?;
|
match direction {
|
||||||
send_response(socket, wasm_pipe_types::WasmResponse::BitsChart { nodes }).await;
|
"down" => {
|
||||||
Ok(())
|
down.push(Throughput {
|
||||||
|
value: row.avg,
|
||||||
|
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
l: row.min,
|
||||||
|
u: row.max - row.min,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"up" => {
|
||||||
|
up.push(Throughput {
|
||||||
|
value: row.avg,
|
||||||
|
date: row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
l: row.min,
|
||||||
|
u: row.max - row.min,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cnn, socket, key, period))]
|
||||||
|
pub async fn send_throughput_for_all_nodes(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str, period: InfluxTimePeriod) -> anyhow::Result<()> {
|
||||||
|
let node_status = pgdb::node_status(cnn, key).await?;
|
||||||
|
let mut nodes = Vec::<ThroughputHost>::new();
|
||||||
|
InfluxQueryBuilder::new(period.clone())
|
||||||
|
.with_measurement("bits")
|
||||||
|
.with_fields(&["min", "max", "avg"])
|
||||||
|
.with_groups(&["host_id", "direction", "_field"])
|
||||||
|
.execute::<ThroughputRow>(cnn, key)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|row| {
|
||||||
|
if let Some(node) = nodes.iter_mut().find(|n| n.node_id == row.host_id) {
|
||||||
|
add_by_direction(&row.direction, &mut node.down, &mut node.up, &row);
|
||||||
|
} else {
|
||||||
|
let mut down = Vec::new();
|
||||||
|
let mut up = Vec::new();
|
||||||
|
|
||||||
|
add_by_direction(&row.direction, &mut down, &mut up, &row);
|
||||||
|
|
||||||
|
let node_name = if let Some(node) = node_status.iter().find(|n| n.node_id == row.host_id) {
|
||||||
|
node.node_name.clone()
|
||||||
|
} else {
|
||||||
|
row.host_id.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.push(ThroughputHost { node_id: row.host_id, node_name, down, up });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
send_response(socket, wasm_pipe_types::WasmResponse::BitsChart { nodes }).await;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cnn, socket, key, period, site_name))]
|
||||||
pub async fn send_throughput_for_all_nodes_by_site(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str, site_name: String, period: InfluxTimePeriod) -> anyhow::Result<()> {
|
pub async fn send_throughput_for_all_nodes_by_site(cnn: &Pool<Postgres>, socket: &mut WebSocket, key: &str, site_name: String, period: InfluxTimePeriod) -> anyhow::Result<()> {
|
||||||
let nodes = get_throughput_for_all_nodes_by_site(cnn, key, period, &site_name).await?;
|
let nodes = get_throughput_for_all_nodes_by_site(cnn, key, period, &site_name).await?;
|
||||||
|
|
||||||
@ -36,23 +87,6 @@ pub async fn send_throughput_for_node(cnn: &Pool<Postgres>, socket: &mut WebSock
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_throughput_for_all_nodes(cnn: &Pool<Postgres>, key: &str, period: InfluxTimePeriod) -> anyhow::Result<Vec<ThroughputHost>> {
|
|
||||||
let node_status = pgdb::node_status(cnn, key).await?;
|
|
||||||
let mut futures = Vec::new();
|
|
||||||
for node in node_status {
|
|
||||||
futures.push(get_throughput_for_node(
|
|
||||||
cnn,
|
|
||||||
key,
|
|
||||||
node.node_id.to_string(),
|
|
||||||
node.node_name.to_string(),
|
|
||||||
period.clone(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let all_nodes: anyhow::Result<Vec<ThroughputHost>> = join_all(futures).await
|
|
||||||
.into_iter().collect();
|
|
||||||
all_nodes
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_throughput_for_all_nodes_by_site(cnn: &Pool<Postgres>, key: &str, period: InfluxTimePeriod, site_name: &str) -> anyhow::Result<Vec<ThroughputHost>> {
|
pub async fn get_throughput_for_all_nodes_by_site(cnn: &Pool<Postgres>, key: &str, period: InfluxTimePeriod, site_name: &str) -> anyhow::Result<Vec<ThroughputHost>> {
|
||||||
let node_status = pgdb::node_status(cnn, key).await?;
|
let node_status = pgdb::node_status(cnn, key).await?;
|
||||||
let mut futures = Vec::new();
|
let mut futures = Vec::new();
|
||||||
|
@ -1,10 +1,35 @@
|
|||||||
use crate::web::wss::{queries::time_period::InfluxTimePeriod, send_response};
|
use crate::web::wss::{queries::time_period::InfluxTimePeriod, send_response};
|
||||||
use axum::extract::ws::WebSocket;
|
use axum::extract::ws::WebSocket;
|
||||||
use pgdb::sqlx::{Pool, Postgres, Row};
|
use pgdb::{
|
||||||
use wasm_pipe_types::Throughput;
|
organization_cache::get_org_details,
|
||||||
|
sqlx::{Pool, Postgres},
|
||||||
|
OrganizationDetails,
|
||||||
|
};
|
||||||
|
use tracing::{error, instrument};
|
||||||
|
use wasm_pipe_types::SiteStackHost;
|
||||||
|
|
||||||
use super::{get_throughput_for_all_nodes_by_circuit, get_throughput_for_all_nodes_by_site};
|
#[derive(Debug, influxdb2::FromDataPoint)]
|
||||||
|
pub struct SiteStackRow {
|
||||||
|
pub node_name: String,
|
||||||
|
pub node_parents: String,
|
||||||
|
pub bits_max: i64,
|
||||||
|
pub time: chrono::DateTime<chrono::FixedOffset>,
|
||||||
|
pub direction: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SiteStackRow {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
node_name: "".to_string(),
|
||||||
|
node_parents: "".to_string(),
|
||||||
|
bits_max: 0,
|
||||||
|
time: chrono::DateTime::<chrono::Utc>::MIN_UTC.into(),
|
||||||
|
direction: "".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(cnn, socket, key, period))]
|
||||||
pub async fn send_site_stack_map(
|
pub async fn send_site_stack_map(
|
||||||
cnn: &Pool<Postgres>,
|
cnn: &Pool<Postgres>,
|
||||||
socket: &mut WebSocket,
|
socket: &mut WebSocket,
|
||||||
@ -13,99 +38,125 @@ pub async fn send_site_stack_map(
|
|||||||
site_id: String,
|
site_id: String,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let site_index = pgdb::get_site_id_from_name(cnn, key, &site_id).await?;
|
let site_index = pgdb::get_site_id_from_name(cnn, key, &site_id).await?;
|
||||||
//println!("Site index: {site_index}");
|
|
||||||
|
|
||||||
let sites: Vec<String> =
|
if let Some(org) = get_org_details(cnn, key).await {
|
||||||
pgdb::sqlx::query("SELECT DISTINCT site_name FROM site_tree WHERE key=$1 AND parent=$2")
|
let rows = query_site_stack_influx(&org, &period, site_index).await;
|
||||||
.bind(key)
|
match rows {
|
||||||
.bind(site_index)
|
Err(e) => error!("Influxdb tree query error: {e}"),
|
||||||
.fetch_all(cnn)
|
Ok(rows) => {
|
||||||
.await?
|
let mut result = site_rows_to_hosts(rows);
|
||||||
.iter()
|
reduce_to_x_entries(&mut result);
|
||||||
.map(|row| row.try_get("site_name").unwrap())
|
|
||||||
.collect();
|
|
||||||
//println!("{sites:?}");
|
|
||||||
|
|
||||||
let circuits: Vec<(String, String)> =
|
// Send the reply
|
||||||
pgdb::sqlx::query("SELECT DISTINCT circuit_id, circuit_name FROM shaped_devices WHERE key=$1 AND parent_node=$2")
|
send_response(
|
||||||
.bind(key)
|
socket,
|
||||||
.bind(site_id)
|
wasm_pipe_types::WasmResponse::SiteStack { nodes: result },
|
||||||
.fetch_all(cnn)
|
)
|
||||||
.await?
|
.await;
|
||||||
.iter()
|
}
|
||||||
.map(|row| (row.try_get("circuit_id").unwrap(), row.try_get("circuit_name").unwrap()))
|
}
|
||||||
.collect();
|
|
||||||
//println!("{circuits:?}");
|
|
||||||
|
|
||||||
let mut result = Vec::new();
|
|
||||||
for site in sites.into_iter() {
|
|
||||||
let mut throughput =
|
|
||||||
get_throughput_for_all_nodes_by_site(cnn, key, period.clone(), &site).await?;
|
|
||||||
throughput
|
|
||||||
.iter_mut()
|
|
||||||
.for_each(|row| row.node_name = site.clone());
|
|
||||||
result.extend(throughput);
|
|
||||||
}
|
}
|
||||||
for circuit in circuits.into_iter() {
|
|
||||||
let mut throughput =
|
|
||||||
get_throughput_for_all_nodes_by_circuit(cnn, key, period.clone(), &circuit.0).await?;
|
|
||||||
throughput
|
|
||||||
.iter_mut()
|
|
||||||
.for_each(|row| row.node_name = circuit.1.clone());
|
|
||||||
result.extend(throughput);
|
|
||||||
}
|
|
||||||
//println!("{result:?}");
|
|
||||||
|
|
||||||
// Sort by total
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(org, period, site_index))]
|
||||||
|
async fn query_site_stack_influx(
|
||||||
|
org: &OrganizationDetails,
|
||||||
|
period: &InfluxTimePeriod,
|
||||||
|
site_index: i32,
|
||||||
|
) -> anyhow::Result<Vec<SiteStackRow>> {
|
||||||
|
let influx_url = format!("http://{}:8086", org.influx_host);
|
||||||
|
let client = influxdb2::Client::new(influx_url, &org.influx_org, &org.influx_token);
|
||||||
|
let qs = format!("import \"strings\"
|
||||||
|
|
||||||
|
from(bucket: \"{}\")
|
||||||
|
|> {}
|
||||||
|
|> filter(fn: (r) => r[\"_field\"] == \"bits_max\" and r[\"_measurement\"] == \"tree\" and r[\"organization_id\"] == \"{}\")
|
||||||
|
|> {}
|
||||||
|
|> filter(fn: (r) => exists r[\"node_parents\"] and exists r[\"node_index\"])
|
||||||
|
|> filter(fn: (r) => strings.hasSuffix(v: r[\"node_parents\"], suffix: \"S{}S\" + r[\"node_index\"] + \"S\" ))
|
||||||
|
|> group(columns: [\"node_name\", \"node_parents\", \"_field\", \"node_index\", \"direction\"])
|
||||||
|
|> yield(name: \"last\")",
|
||||||
|
org.influx_bucket, period.range(), org.key, period.sample(), site_index);
|
||||||
|
|
||||||
|
println!("{qs}");
|
||||||
|
|
||||||
|
let query = influxdb2::models::Query::new(qs);
|
||||||
|
//let rows = client.query_raw(Some(query)).await;
|
||||||
|
Ok(client.query::<SiteStackRow>(Some(query)).await?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn site_rows_to_hosts(rows: Vec<SiteStackRow>) -> Vec<SiteStackHost> {
|
||||||
|
let mut result: Vec<SiteStackHost> = Vec::new();
|
||||||
|
for row in rows.iter() {
|
||||||
|
if let Some(r) = result.iter_mut().find(|r| r.node_name == row.node_name) {
|
||||||
|
if row.direction == "down" {
|
||||||
|
r.download.push((
|
||||||
|
row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
row.bits_max,
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
r.upload.push((
|
||||||
|
row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
row.bits_max,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else if row.direction == "down" {
|
||||||
|
result.push(SiteStackHost {
|
||||||
|
node_name: row.node_name.clone(),
|
||||||
|
download: vec![(
|
||||||
|
row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
row.bits_max,
|
||||||
|
)],
|
||||||
|
upload: vec![],
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
result.push(SiteStackHost {
|
||||||
|
node_name: row.node_name.clone(),
|
||||||
|
upload: vec![(
|
||||||
|
row.time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||||
|
row.bits_max,
|
||||||
|
)],
|
||||||
|
download: vec![],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reduce_to_x_entries(result: &mut Vec<SiteStackHost>) {
|
||||||
|
// Sort descending by total
|
||||||
result.sort_by(|a, b| {
|
result.sort_by(|a, b| {
|
||||||
b.total()
|
b.total()
|
||||||
.partial_cmp(&a.total())
|
.partial_cmp(&a.total())
|
||||||
.unwrap_or(std::cmp::Ordering::Equal)
|
.unwrap_or(std::cmp::Ordering::Equal)
|
||||||
});
|
});
|
||||||
|
|
||||||
// If there are more than 9 entries, create an "others" to handle the remainder
|
const MAX_HOSTS: usize = 8;
|
||||||
if result.len() > 9 {
|
if result.len() > MAX_HOSTS {
|
||||||
let mut others = wasm_pipe_types::ThroughputHost {
|
let mut others = SiteStackHost {
|
||||||
node_id: "others".to_string(),
|
|
||||||
node_name: "others".to_string(),
|
node_name: "others".to_string(),
|
||||||
down: Vec::new(),
|
download: Vec::new(),
|
||||||
up: Vec::new(),
|
upload: Vec::new(),
|
||||||
};
|
};
|
||||||
result[0].down.iter().for_each(|x| {
|
result[0].download.iter().for_each(|x| {
|
||||||
others.down.push(Throughput {
|
others.download.push((x.0.clone(), 0));
|
||||||
value: 0.0,
|
others.upload.push((x.0.clone(), 0));
|
||||||
date: x.date.clone(),
|
});
|
||||||
l: 0.0,
|
result.iter().skip(MAX_HOSTS).for_each(|row| {
|
||||||
u: 0.0,
|
row.download.iter().enumerate().for_each(|(i, x)| {
|
||||||
|
if i < others.download.len() {
|
||||||
|
others.download[i].1 += x.1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
row.upload.iter().enumerate().for_each(|(i, x)| {
|
||||||
|
if i < others.upload.len() {
|
||||||
|
others.upload[i].1 += x.1;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
result[0].up.iter().for_each(|x| {
|
result.truncate(MAX_HOSTS-1);
|
||||||
others.up.push(Throughput {
|
|
||||||
value: 0.0,
|
|
||||||
date: x.date.clone(),
|
|
||||||
l: 0.0,
|
|
||||||
u: 0.0,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
result.iter().skip(9).for_each(|row| {
|
|
||||||
row.down.iter().enumerate().for_each(|(i, x)| {
|
|
||||||
others.down[i].value += x.value;
|
|
||||||
});
|
|
||||||
row.up.iter().enumerate().for_each(|(i, x)| {
|
|
||||||
others.up[i].value += x.value;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
result.truncate(9);
|
|
||||||
result.push(others);
|
result.push(others);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_response(
|
|
||||||
socket,
|
|
||||||
wasm_pipe_types::WasmResponse::SiteStack { nodes: result },
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#[derive(Clone)]
|
#![allow(dead_code)]
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub struct InfluxTimePeriod {
|
pub struct InfluxTimePeriod {
|
||||||
start: String,
|
start: String,
|
||||||
aggregate: String,
|
aggregate: String,
|
||||||
|
sample: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InfluxTimePeriod {
|
impl InfluxTimePeriod {
|
||||||
@ -30,9 +32,23 @@ impl InfluxTimePeriod {
|
|||||||
_ => "10s",
|
_ => "10s",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let sample = match period {
|
||||||
|
"5m" => 3,
|
||||||
|
"15m" => 10,
|
||||||
|
"1h" => 40,
|
||||||
|
"6h" => 100,
|
||||||
|
"12h" => 200,
|
||||||
|
"24h" => 400,
|
||||||
|
"7d" => 2100,
|
||||||
|
"28d" => 4400,
|
||||||
|
_ => 1
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
start: start.to_string(),
|
start: start.to_string(),
|
||||||
aggregate: aggregate.to_string(),
|
aggregate: aggregate.to_string(),
|
||||||
|
sample
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +62,24 @@ impl InfluxTimePeriod {
|
|||||||
self.aggregate
|
self.aggregate
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn aggregate_window_empty(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"aggregateWindow(every: {}, fn: mean, createEmpty: true)",
|
||||||
|
self.aggregate
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn aggregate_window_fn(&self, mode: &str) -> String {
|
||||||
|
format!(
|
||||||
|
"aggregateWindow(every: {}, fn: {mode}, createEmpty: false)",
|
||||||
|
self.aggregate
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sample(&self) -> String {
|
||||||
|
format!("sample(n: {}, pos: 1)", self.sample)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&String> for InfluxTimePeriod {
|
impl From<&String> for InfluxTimePeriod {
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -25,7 +25,7 @@ declare global {
|
|||||||
window.auth = new Auth;
|
window.auth = new Auth;
|
||||||
window.bus = new Bus();
|
window.bus = new Bus();
|
||||||
window.router = new SiteRouter();
|
window.router = new SiteRouter();
|
||||||
window.bus.connect();
|
//window.bus.connect();
|
||||||
window.router.initialRoute();
|
window.router.initialRoute();
|
||||||
let graphPeriod = localStorage.getItem('graphPeriod');
|
let graphPeriod = localStorage.getItem('graphPeriod');
|
||||||
if (!graphPeriod) {
|
if (!graphPeriod) {
|
||||||
@ -39,19 +39,25 @@ window.changeGraphPeriod = (period: string) => changeGraphPeriod(period);
|
|||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
window.bus.updateConnected();
|
window.bus.updateConnected();
|
||||||
window.router.ontick();
|
window.router.ontick();
|
||||||
let btn = document.getElementById("graphPeriodBtn") as HTMLButtonElement;
|
|
||||||
btn.innerText = window.graphPeriod;
|
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
// Faster interval for tracking the WSS connection
|
// Faster interval for tracking the WSS connection
|
||||||
window.setInterval(() => {
|
window.setInterval(() => {
|
||||||
|
updateDisplayedInterval();
|
||||||
window.bus.updateConnected();
|
window.bus.updateConnected();
|
||||||
window.bus.sendQueue();
|
window.bus.sendQueue();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
function updateDisplayedInterval() {
|
||||||
|
let btn = document.getElementById("graphPeriodBtn") as HTMLButtonElement | null;
|
||||||
|
if (!btn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
btn.innerText = window.graphPeriod;
|
||||||
|
}
|
||||||
|
|
||||||
function changeGraphPeriod(period: string) {
|
function changeGraphPeriod(period: string) {
|
||||||
window.graphPeriod = period;
|
window.graphPeriod = period;
|
||||||
localStorage.setItem('graphPeriod', period);
|
localStorage.setItem('graphPeriod', period);
|
||||||
let btn = document.getElementById("graphPeriodBtn") as HTMLButtonElement;
|
updateDisplayedInterval();
|
||||||
btn.innerText = period;
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import { connect_wasm_pipe, is_wasm_connected, send_wss_queue } from "../wasm/wasm_pipe";
|
import { is_wasm_connected, send_wss_queue, initialize_wss } from "../wasm/wasm_pipe";
|
||||||
import { Auth } from "./auth";
|
import { Auth } from "./auth";
|
||||||
import { SiteRouter } from "./router";
|
import { SiteRouter } from "./router";
|
||||||
|
|
||||||
export class Bus {
|
export class Bus {
|
||||||
ws: WebSocket;
|
ws: WebSocket;
|
||||||
connected: boolean;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const currentUrlWithoutAnchors = window.location.href.split('#')[0].replace("https://", "").replace("http://", "");
|
const currentUrlWithoutAnchors = window.location.href.split('#')[0].replace("https://", "").replace("http://", "");
|
||||||
const url = "ws://" + currentUrlWithoutAnchors + "ws";
|
const url = "ws://" + currentUrlWithoutAnchors + "ws";
|
||||||
this.connected = false;
|
initialize_wss(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateConnected() {
|
updateConnected() {
|
||||||
@ -19,7 +18,6 @@ export class Bus {
|
|||||||
indicator.style.color = "green";
|
indicator.style.color = "green";
|
||||||
} else if (indicator) {
|
} else if (indicator) {
|
||||||
indicator.style.color = "red";
|
indicator.style.color = "red";
|
||||||
retryConnect();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,12 +25,6 @@ export class Bus {
|
|||||||
send_wss_queue();
|
send_wss_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
connect() {
|
|
||||||
const currentUrlWithoutAnchors = window.location.href.split('#')[0].replace("https://", "").replace("http://", "");
|
|
||||||
const url = "ws://" + currentUrlWithoutAnchors + "ws";
|
|
||||||
connect_wasm_pipe(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
getToken(): string {
|
getToken(): string {
|
||||||
if (window.auth.hasCredentials && window.auth.token) {
|
if (window.auth.hasCredentials && window.auth.token) {
|
||||||
return window.auth.token;
|
return window.auth.token;
|
||||||
@ -128,12 +120,6 @@ export class Bus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function retryConnect() {
|
|
||||||
if (!window.bus.connected) {
|
|
||||||
//window.bus.connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WASM callback
|
// WASM callback
|
||||||
export function onAuthFail() {
|
export function onAuthFail() {
|
||||||
window.auth.hasCredentials = false;
|
window.auth.hasCredentials = false;
|
||||||
|
@ -5,7 +5,6 @@ import * as echarts from 'echarts';
|
|||||||
export class RootHeat implements Component {
|
export class RootHeat implements Component {
|
||||||
div: HTMLElement;
|
div: HTMLElement;
|
||||||
myChart: echarts.ECharts | null = null;
|
myChart: echarts.ECharts | null = null;
|
||||||
counter: number = 0;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.div = document.getElementById("rootHeat") as HTMLElement;
|
this.div = document.getElementById("rootHeat") as HTMLElement;
|
||||||
@ -16,9 +15,7 @@ export class RootHeat implements Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ontick(): void {
|
ontick(): void {
|
||||||
this.counter++;
|
request_root_heat(window.graphPeriod);
|
||||||
if (this.counter % 10 == 0)
|
|
||||||
request_root_heat(window.graphPeriod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onmessage(event: any): void {
|
onmessage(event: any): void {
|
||||||
|
@ -88,7 +88,18 @@ export class RttChart implements Component {
|
|||||||
this.myChart.setOption<echarts.EChartsOption>(
|
this.myChart.setOption<echarts.EChartsOption>(
|
||||||
(option = {
|
(option = {
|
||||||
title: { text: "TCP Round-Trip Time" },
|
title: { text: "TCP Round-Trip Time" },
|
||||||
tooltip: { trigger: "axis" },
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
formatter: function (params: any) {
|
||||||
|
let ret = "";
|
||||||
|
for (let i=0; i<params.length; i+=3) {
|
||||||
|
if (params[i+2].value > 0) {
|
||||||
|
ret += "<strong>" + params[i+2].seriesName + "</strong>: " + params[i+2].value.toFixed(1) + " ms<br/>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
legend: {
|
legend: {
|
||||||
orient: "horizontal",
|
orient: "horizontal",
|
||||||
right: 10,
|
right: 10,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { scaleNumber } from "../helpers";
|
import { scaleNumber } from "../helpers";
|
||||||
import { Component } from "./component";
|
import { Component } from "./component";
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
|
import { request_rtt_histogram } from "../../wasm/wasm_pipe";
|
||||||
|
|
||||||
export class RttHisto implements Component {
|
export class RttHisto implements Component {
|
||||||
div: HTMLElement;
|
div: HTMLElement;
|
||||||
@ -16,18 +17,20 @@ export class RttHisto implements Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wireup(): void {
|
wireup(): void {
|
||||||
|
request_rtt_histogram(window.graphPeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
ontick(): void {
|
ontick(): void {
|
||||||
|
request_rtt_histogram(window.graphPeriod);
|
||||||
}
|
}
|
||||||
|
|
||||||
onmessage(event: any): void {
|
onmessage(event: any): void {
|
||||||
if (event.msg == "RttChart") {
|
if (event.msg == "RttHistogram") {
|
||||||
//console.log(event);
|
//console.log(event);
|
||||||
this.download = [];
|
this.download = [];
|
||||||
this.x = [];
|
this.x = [];
|
||||||
for (let i = 0; i < event.RttChart.histogram.length; i++) {
|
for (let i = 0; i < event.RttHistogram.histogram.length; i++) {
|
||||||
this.download.push(event.RttChart.histogram[i]);
|
this.download.push(event.RttHistogram.histogram[i]);
|
||||||
this.x.push(i * 10);
|
this.x.push(i * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,9 @@ export class SiteHeat implements Component {
|
|||||||
ontick(): void {
|
ontick(): void {
|
||||||
console.log("SiteHeat ontick");
|
console.log("SiteHeat ontick");
|
||||||
this.counter++;
|
this.counter++;
|
||||||
if (this.counter % 10 == 0)
|
if (this.counter == 0) {
|
||||||
request_site_heat(window.graphPeriod, this.siteId);
|
request_site_heat(window.graphPeriod, this.siteId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onmessage(event: any): void {
|
onmessage(event: any): void {
|
||||||
|
@ -37,19 +37,16 @@ export class SiteStackChart implements Component {
|
|||||||
let legend: string[] = [];
|
let legend: string[] = [];
|
||||||
for (let i = 0; i < event.SiteStack.nodes.length; i++) {
|
for (let i = 0; i < event.SiteStack.nodes.length; i++) {
|
||||||
let node = event.SiteStack.nodes[i];
|
let node = event.SiteStack.nodes[i];
|
||||||
|
console.log(node);
|
||||||
if (node.node_name != "Root") {
|
if (node.node_name != "Root") {
|
||||||
legend.push(node.node_name);
|
legend.push(node.node_name);
|
||||||
//legend.push(node.node_name + " UL");
|
//legend.push(node.node_name + " UL");
|
||||||
//console.log(node);
|
//console.log(node);
|
||||||
|
|
||||||
let d: number[] = [];
|
let d: number[] = [];
|
||||||
let u: number[] = [];
|
for (let j = 0; j < node.download.length; j++) {
|
||||||
let l: number[] = [];
|
if (first) x.push(node.download[j][0]);
|
||||||
for (let j = 0; j < node.down.length; j++) {
|
d.push(node.download[j][1] * 8.0);
|
||||||
if (first) x.push(node.down[j].date);
|
|
||||||
d.push(node.down[j].value * 8.0);
|
|
||||||
u.push(node.down[j].u * 8.0);
|
|
||||||
l.push(node.down[j].l * 8.0);
|
|
||||||
}
|
}
|
||||||
if (first) first = false;
|
if (first) first = false;
|
||||||
|
|
||||||
@ -66,13 +63,11 @@ export class SiteStackChart implements Component {
|
|||||||
|
|
||||||
// Do the same for upload
|
// Do the same for upload
|
||||||
d = [];
|
d = [];
|
||||||
u = [];
|
for (let j = 0; j < node.upload.length; j++) {
|
||||||
l = [];
|
if (first) x.push(node.upload[j][0]);
|
||||||
for (let j = 0; j < node.down.length; j++) {
|
d.push(0.0 - (node.upload[j][1] * 8.0));
|
||||||
d.push(0.0 - (node.up[j].value * 8.0));
|
|
||||||
u.push(0.0 - (node.up[j].u * 8.0));
|
|
||||||
l.push(0.0 - (node.up[j].l * 8.0));
|
|
||||||
}
|
}
|
||||||
|
if (first) first = false;
|
||||||
|
|
||||||
val = {
|
val = {
|
||||||
name: node.node_name,
|
name: node.node_name,
|
||||||
@ -81,7 +76,6 @@ export class SiteStackChart implements Component {
|
|||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
stack: 'upload',
|
stack: 'upload',
|
||||||
areaStyle: {},
|
areaStyle: {},
|
||||||
label: { show: false }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
series.push(val);
|
series.push(val);
|
||||||
@ -93,7 +87,7 @@ export class SiteStackChart implements Component {
|
|||||||
var option: echarts.EChartsOption;
|
var option: echarts.EChartsOption;
|
||||||
this.myChart.setOption<echarts.EChartsOption>(
|
this.myChart.setOption<echarts.EChartsOption>(
|
||||||
(option = {
|
(option = {
|
||||||
title: { text: "Child Node Throughput (Bits)" },
|
title: { text: "Child Node Throughput (Bits - Max)" },
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: "axis",
|
trigger: "axis",
|
||||||
formatter: function (params: any) {
|
formatter: function (params: any) {
|
||||||
@ -101,7 +95,7 @@ export class SiteStackChart implements Component {
|
|||||||
let result = "";
|
let result = "";
|
||||||
for (let i = 0; i < params.length; i+=2) {
|
for (let i = 0; i < params.length; i+=2) {
|
||||||
let siteName = params[i].seriesName;
|
let siteName = params[i].seriesName;
|
||||||
siteName += " (⬇️" + scaleNumber(params[i].value) + " / ⬆️" + scaleNumber(0.0 - params[i+1].value) + ")";
|
siteName += " (⬇️" + scaleNumber(params[i].value) + " / ⬆️" + scaleNumber(Math.abs(params[i+1].value)) + ")";
|
||||||
result += `${siteName}<br />`;
|
result += `${siteName}<br />`;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -23,13 +23,13 @@ export class DashboardPage implements Page {
|
|||||||
}
|
}
|
||||||
this.components = [
|
this.components = [
|
||||||
new NodeStatus(),
|
new NodeStatus(),
|
||||||
|
new RootBreadcrumbs(),
|
||||||
new PacketsChart(),
|
new PacketsChart(),
|
||||||
new ThroughputChart(),
|
new ThroughputChart(),
|
||||||
new RttChart(),
|
new RttChart(),
|
||||||
new RttHisto(),
|
new RttHisto(),
|
||||||
new RootHeat(),
|
new RootHeat(),
|
||||||
new SiteStackChart("root"),
|
new SiteStackChart("root"),
|
||||||
new RootBreadcrumbs(),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
/**
|
/**
|
||||||
* @param {string} url
|
* @param {string} url
|
||||||
*/
|
*/
|
||||||
export function connect_wasm_pipe(url: string): void;
|
export function initialize_wss(url: string): void;
|
||||||
/**
|
/**
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
@ -65,6 +65,10 @@ export function request_site_stack(period: string, site_id: string): void;
|
|||||||
export function request_rtt_chart(period: string): void;
|
export function request_rtt_chart(period: string): void;
|
||||||
/**
|
/**
|
||||||
* @param {string} period
|
* @param {string} period
|
||||||
|
*/
|
||||||
|
export function request_rtt_histogram(period: string): void;
|
||||||
|
/**
|
||||||
|
* @param {string} period
|
||||||
* @param {string} site_id
|
* @param {string} site_id
|
||||||
*/
|
*/
|
||||||
export function request_rtt_chart_for_site(period: string, site_id: string): void;
|
export function request_rtt_chart_for_site(period: string, site_id: string): void;
|
||||||
@ -140,7 +144,7 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
|
|||||||
|
|
||||||
export interface InitOutput {
|
export interface InitOutput {
|
||||||
readonly memory: WebAssembly.Memory;
|
readonly memory: WebAssembly.Memory;
|
||||||
readonly connect_wasm_pipe: (a: number, b: number) => void;
|
readonly initialize_wss: (a: number, b: number) => void;
|
||||||
readonly is_wasm_connected: () => number;
|
readonly is_wasm_connected: () => number;
|
||||||
readonly send_wss_queue: () => void;
|
readonly send_wss_queue: () => void;
|
||||||
readonly send_token: (a: number, b: number) => void;
|
readonly send_token: (a: number, b: number) => void;
|
||||||
@ -154,6 +158,7 @@ export interface InitOutput {
|
|||||||
readonly request_throughput_chart_for_circuit: (a: number, b: number, c: number, d: number) => void;
|
readonly request_throughput_chart_for_circuit: (a: number, b: number, c: number, d: number) => void;
|
||||||
readonly request_site_stack: (a: number, b: number, c: number, d: number) => void;
|
readonly request_site_stack: (a: number, b: number, c: number, d: number) => void;
|
||||||
readonly request_rtt_chart: (a: number, b: number) => void;
|
readonly request_rtt_chart: (a: number, b: number) => void;
|
||||||
|
readonly request_rtt_histogram: (a: number, b: number) => void;
|
||||||
readonly request_rtt_chart_for_site: (a: number, b: number, c: number, d: number) => void;
|
readonly request_rtt_chart_for_site: (a: number, b: number, c: number, d: number) => void;
|
||||||
readonly request_rtt_chart_for_node: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
readonly request_rtt_chart_for_node: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
||||||
readonly request_rtt_chart_for_circuit: (a: number, b: number, c: number, d: number) => void;
|
readonly request_rtt_chart_for_circuit: (a: number, b: number, c: number, d: number) => void;
|
||||||
@ -170,13 +175,12 @@ export interface InitOutput {
|
|||||||
readonly request_ext_device_info: (a: number, b: number) => void;
|
readonly request_ext_device_info: (a: number, b: number) => void;
|
||||||
readonly request_ext_snr_graph: (a: number, b: number, c: number, d: number) => void;
|
readonly request_ext_snr_graph: (a: number, b: number, c: number, d: number) => void;
|
||||||
readonly request_ext_capacity_graph: (a: number, b: number, c: number, d: number) => void;
|
readonly request_ext_capacity_graph: (a: number, b: number, c: number, d: number) => void;
|
||||||
readonly __wbindgen_malloc: (a: number) => number;
|
readonly __wbindgen_export_0: (a: number) => number;
|
||||||
readonly __wbindgen_realloc: (a: number, b: number, c: number) => number;
|
readonly __wbindgen_export_1: (a: number, b: number, c: number) => number;
|
||||||
readonly __wbindgen_export_2: WebAssembly.Table;
|
readonly __wbindgen_export_2: WebAssembly.Table;
|
||||||
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb4b341652e081e3f: (a: number, b: number, c: number) => void;
|
readonly __wbindgen_export_3: (a: number, b: number, c: number) => void;
|
||||||
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha318d2d73313995c: (a: number, b: number, c: number) => void;
|
readonly __wbindgen_export_4: (a: number, b: number) => void;
|
||||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
readonly __wbindgen_export_5: (a: number) => void;
|
||||||
readonly __wbindgen_exn_store: (a: number) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
||||||
|
@ -201,21 +201,16 @@ function makeMutClosure(arg0, arg1, dtor, f) {
|
|||||||
return real;
|
return real;
|
||||||
}
|
}
|
||||||
function __wbg_adapter_12(arg0, arg1, arg2) {
|
function __wbg_adapter_12(arg0, arg1, arg2) {
|
||||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb4b341652e081e3f(arg0, arg1, addHeapObject(arg2));
|
wasm.__wbindgen_export_3(arg0, arg1, addHeapObject(arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
function __wbg_adapter_15(arg0, arg1, arg2) {
|
|
||||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha318d2d73313995c(arg0, arg1, addHeapObject(arg2));
|
|
||||||
}
|
|
||||||
|
|
||||||
function notDefined(what) { return () => { throw new Error(`${what} is not defined`); }; }
|
|
||||||
/**
|
/**
|
||||||
* @param {string} url
|
* @param {string} url
|
||||||
*/
|
*/
|
||||||
export function connect_wasm_pipe(url) {
|
export function initialize_wss(url) {
|
||||||
const ptr0 = passStringToWasm0(url, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(url, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.connect_wasm_pipe(ptr0, len0);
|
wasm.initialize_wss(ptr0, len0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,11 +227,12 @@ export function send_wss_queue() {
|
|||||||
wasm.send_wss_queue();
|
wasm.send_wss_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function notDefined(what) { return () => { throw new Error(`${what} is not defined`); }; }
|
||||||
/**
|
/**
|
||||||
* @param {string} token
|
* @param {string} token
|
||||||
*/
|
*/
|
||||||
export function send_token(token) {
|
export function send_token(token) {
|
||||||
const ptr0 = passStringToWasm0(token, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(token, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.send_token(ptr0, len0);
|
wasm.send_token(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -247,11 +243,11 @@ export function send_token(token) {
|
|||||||
* @param {string} password
|
* @param {string} password
|
||||||
*/
|
*/
|
||||||
export function send_login(license, username, password) {
|
export function send_login(license, username, password) {
|
||||||
const ptr0 = passStringToWasm0(license, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(license, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(username, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(username, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
const ptr2 = passStringToWasm0(password, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr2 = passStringToWasm0(password, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len2 = WASM_VECTOR_LEN;
|
const len2 = WASM_VECTOR_LEN;
|
||||||
wasm.send_login(ptr0, len0, ptr1, len1, ptr2, len2);
|
wasm.send_login(ptr0, len0, ptr1, len1, ptr2, len2);
|
||||||
}
|
}
|
||||||
@ -266,7 +262,7 @@ export function request_node_status() {
|
|||||||
* @param {string} period
|
* @param {string} period
|
||||||
*/
|
*/
|
||||||
export function request_packet_chart(period) {
|
export function request_packet_chart(period) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_packet_chart(ptr0, len0);
|
wasm.request_packet_chart(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -277,11 +273,11 @@ export function request_packet_chart(period) {
|
|||||||
* @param {string} node_name
|
* @param {string} node_name
|
||||||
*/
|
*/
|
||||||
export function request_packet_chart_for_node(period, node_id, node_name) {
|
export function request_packet_chart_for_node(period, node_id, node_name) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(node_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(node_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
const ptr2 = passStringToWasm0(node_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr2 = passStringToWasm0(node_name, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len2 = WASM_VECTOR_LEN;
|
const len2 = WASM_VECTOR_LEN;
|
||||||
wasm.request_packet_chart_for_node(ptr0, len0, ptr1, len1, ptr2, len2);
|
wasm.request_packet_chart_for_node(ptr0, len0, ptr1, len1, ptr2, len2);
|
||||||
}
|
}
|
||||||
@ -290,7 +286,7 @@ export function request_packet_chart_for_node(period, node_id, node_name) {
|
|||||||
* @param {string} period
|
* @param {string} period
|
||||||
*/
|
*/
|
||||||
export function request_throughput_chart(period) {
|
export function request_throughput_chart(period) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_throughput_chart(ptr0, len0);
|
wasm.request_throughput_chart(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -300,9 +296,9 @@ export function request_throughput_chart(period) {
|
|||||||
* @param {string} site_id
|
* @param {string} site_id
|
||||||
*/
|
*/
|
||||||
export function request_throughput_chart_for_site(period, site_id) {
|
export function request_throughput_chart_for_site(period, site_id) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(site_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(site_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
wasm.request_throughput_chart_for_site(ptr0, len0, ptr1, len1);
|
wasm.request_throughput_chart_for_site(ptr0, len0, ptr1, len1);
|
||||||
}
|
}
|
||||||
@ -313,11 +309,11 @@ export function request_throughput_chart_for_site(period, site_id) {
|
|||||||
* @param {string} node_name
|
* @param {string} node_name
|
||||||
*/
|
*/
|
||||||
export function request_throughput_chart_for_node(period, node_id, node_name) {
|
export function request_throughput_chart_for_node(period, node_id, node_name) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(node_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(node_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
const ptr2 = passStringToWasm0(node_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr2 = passStringToWasm0(node_name, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len2 = WASM_VECTOR_LEN;
|
const len2 = WASM_VECTOR_LEN;
|
||||||
wasm.request_throughput_chart_for_node(ptr0, len0, ptr1, len1, ptr2, len2);
|
wasm.request_throughput_chart_for_node(ptr0, len0, ptr1, len1, ptr2, len2);
|
||||||
}
|
}
|
||||||
@ -327,9 +323,9 @@ export function request_throughput_chart_for_node(period, node_id, node_name) {
|
|||||||
* @param {string} circuit_id
|
* @param {string} circuit_id
|
||||||
*/
|
*/
|
||||||
export function request_throughput_chart_for_circuit(period, circuit_id) {
|
export function request_throughput_chart_for_circuit(period, circuit_id) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(circuit_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(circuit_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
wasm.request_throughput_chart_for_circuit(ptr0, len0, ptr1, len1);
|
wasm.request_throughput_chart_for_circuit(ptr0, len0, ptr1, len1);
|
||||||
}
|
}
|
||||||
@ -339,9 +335,9 @@ export function request_throughput_chart_for_circuit(period, circuit_id) {
|
|||||||
* @param {string} site_id
|
* @param {string} site_id
|
||||||
*/
|
*/
|
||||||
export function request_site_stack(period, site_id) {
|
export function request_site_stack(period, site_id) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(site_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(site_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
wasm.request_site_stack(ptr0, len0, ptr1, len1);
|
wasm.request_site_stack(ptr0, len0, ptr1, len1);
|
||||||
}
|
}
|
||||||
@ -350,19 +346,28 @@ export function request_site_stack(period, site_id) {
|
|||||||
* @param {string} period
|
* @param {string} period
|
||||||
*/
|
*/
|
||||||
export function request_rtt_chart(period) {
|
export function request_rtt_chart(period) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_rtt_chart(ptr0, len0);
|
wasm.request_rtt_chart(ptr0, len0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} period
|
||||||
|
*/
|
||||||
|
export function request_rtt_histogram(period) {
|
||||||
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
|
const len0 = WASM_VECTOR_LEN;
|
||||||
|
wasm.request_rtt_histogram(ptr0, len0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} period
|
* @param {string} period
|
||||||
* @param {string} site_id
|
* @param {string} site_id
|
||||||
*/
|
*/
|
||||||
export function request_rtt_chart_for_site(period, site_id) {
|
export function request_rtt_chart_for_site(period, site_id) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(site_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(site_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
wasm.request_rtt_chart_for_site(ptr0, len0, ptr1, len1);
|
wasm.request_rtt_chart_for_site(ptr0, len0, ptr1, len1);
|
||||||
}
|
}
|
||||||
@ -373,11 +378,11 @@ export function request_rtt_chart_for_site(period, site_id) {
|
|||||||
* @param {string} node_name
|
* @param {string} node_name
|
||||||
*/
|
*/
|
||||||
export function request_rtt_chart_for_node(period, node_id, node_name) {
|
export function request_rtt_chart_for_node(period, node_id, node_name) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(node_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(node_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
const ptr2 = passStringToWasm0(node_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr2 = passStringToWasm0(node_name, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len2 = WASM_VECTOR_LEN;
|
const len2 = WASM_VECTOR_LEN;
|
||||||
wasm.request_rtt_chart_for_node(ptr0, len0, ptr1, len1, ptr2, len2);
|
wasm.request_rtt_chart_for_node(ptr0, len0, ptr1, len1, ptr2, len2);
|
||||||
}
|
}
|
||||||
@ -387,9 +392,9 @@ export function request_rtt_chart_for_node(period, node_id, node_name) {
|
|||||||
* @param {string} circuit_id
|
* @param {string} circuit_id
|
||||||
*/
|
*/
|
||||||
export function request_rtt_chart_for_circuit(period, circuit_id) {
|
export function request_rtt_chart_for_circuit(period, circuit_id) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(circuit_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(circuit_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
wasm.request_rtt_chart_for_circuit(ptr0, len0, ptr1, len1);
|
wasm.request_rtt_chart_for_circuit(ptr0, len0, ptr1, len1);
|
||||||
}
|
}
|
||||||
@ -400,11 +405,11 @@ export function request_rtt_chart_for_circuit(period, circuit_id) {
|
|||||||
* @param {string} node_name
|
* @param {string} node_name
|
||||||
*/
|
*/
|
||||||
export function request_node_perf_chart(period, node_id, node_name) {
|
export function request_node_perf_chart(period, node_id, node_name) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(node_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(node_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
const ptr2 = passStringToWasm0(node_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr2 = passStringToWasm0(node_name, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len2 = WASM_VECTOR_LEN;
|
const len2 = WASM_VECTOR_LEN;
|
||||||
wasm.request_node_perf_chart(ptr0, len0, ptr1, len1, ptr2, len2);
|
wasm.request_node_perf_chart(ptr0, len0, ptr1, len1, ptr2, len2);
|
||||||
}
|
}
|
||||||
@ -413,7 +418,7 @@ export function request_node_perf_chart(period, node_id, node_name) {
|
|||||||
* @param {string} period
|
* @param {string} period
|
||||||
*/
|
*/
|
||||||
export function request_root_heat(period) {
|
export function request_root_heat(period) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_root_heat(ptr0, len0);
|
wasm.request_root_heat(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -423,9 +428,9 @@ export function request_root_heat(period) {
|
|||||||
* @param {string} site_id
|
* @param {string} site_id
|
||||||
*/
|
*/
|
||||||
export function request_site_heat(period, site_id) {
|
export function request_site_heat(period, site_id) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(site_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(site_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
wasm.request_site_heat(ptr0, len0, ptr1, len1);
|
wasm.request_site_heat(ptr0, len0, ptr1, len1);
|
||||||
}
|
}
|
||||||
@ -434,7 +439,7 @@ export function request_site_heat(period, site_id) {
|
|||||||
* @param {string} parent
|
* @param {string} parent
|
||||||
*/
|
*/
|
||||||
export function request_tree(parent) {
|
export function request_tree(parent) {
|
||||||
const ptr0 = passStringToWasm0(parent, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(parent, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_tree(ptr0, len0);
|
wasm.request_tree(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -443,7 +448,7 @@ export function request_tree(parent) {
|
|||||||
* @param {string} site_id
|
* @param {string} site_id
|
||||||
*/
|
*/
|
||||||
export function request_site_info(site_id) {
|
export function request_site_info(site_id) {
|
||||||
const ptr0 = passStringToWasm0(site_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(site_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_site_info(ptr0, len0);
|
wasm.request_site_info(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -452,7 +457,7 @@ export function request_site_info(site_id) {
|
|||||||
* @param {string} site_id
|
* @param {string} site_id
|
||||||
*/
|
*/
|
||||||
export function request_site_parents(site_id) {
|
export function request_site_parents(site_id) {
|
||||||
const ptr0 = passStringToWasm0(site_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(site_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_site_parents(ptr0, len0);
|
wasm.request_site_parents(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -461,7 +466,7 @@ export function request_site_parents(site_id) {
|
|||||||
* @param {string} circuit_id
|
* @param {string} circuit_id
|
||||||
*/
|
*/
|
||||||
export function request_circuit_parents(circuit_id) {
|
export function request_circuit_parents(circuit_id) {
|
||||||
const ptr0 = passStringToWasm0(circuit_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(circuit_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_circuit_parents(ptr0, len0);
|
wasm.request_circuit_parents(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -476,7 +481,7 @@ export function request_root_parents() {
|
|||||||
* @param {string} term
|
* @param {string} term
|
||||||
*/
|
*/
|
||||||
export function request_search(term) {
|
export function request_search(term) {
|
||||||
const ptr0 = passStringToWasm0(term, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(term, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_search(ptr0, len0);
|
wasm.request_search(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -485,7 +490,7 @@ export function request_search(term) {
|
|||||||
* @param {string} circuit_id
|
* @param {string} circuit_id
|
||||||
*/
|
*/
|
||||||
export function request_circuit_info(circuit_id) {
|
export function request_circuit_info(circuit_id) {
|
||||||
const ptr0 = passStringToWasm0(circuit_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(circuit_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_circuit_info(ptr0, len0);
|
wasm.request_circuit_info(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -494,7 +499,7 @@ export function request_circuit_info(circuit_id) {
|
|||||||
* @param {string} circuit_id
|
* @param {string} circuit_id
|
||||||
*/
|
*/
|
||||||
export function request_ext_device_info(circuit_id) {
|
export function request_ext_device_info(circuit_id) {
|
||||||
const ptr0 = passStringToWasm0(circuit_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(circuit_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
wasm.request_ext_device_info(ptr0, len0);
|
wasm.request_ext_device_info(ptr0, len0);
|
||||||
}
|
}
|
||||||
@ -504,9 +509,9 @@ export function request_ext_device_info(circuit_id) {
|
|||||||
* @param {string} device_id
|
* @param {string} device_id
|
||||||
*/
|
*/
|
||||||
export function request_ext_snr_graph(period, device_id) {
|
export function request_ext_snr_graph(period, device_id) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(device_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(device_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
wasm.request_ext_snr_graph(ptr0, len0, ptr1, len1);
|
wasm.request_ext_snr_graph(ptr0, len0, ptr1, len1);
|
||||||
}
|
}
|
||||||
@ -516,9 +521,9 @@ export function request_ext_snr_graph(period, device_id) {
|
|||||||
* @param {string} device_id
|
* @param {string} device_id
|
||||||
*/
|
*/
|
||||||
export function request_ext_capacity_graph(period, device_id) {
|
export function request_ext_capacity_graph(period, device_id) {
|
||||||
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(period, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len0 = WASM_VECTOR_LEN;
|
const len0 = WASM_VECTOR_LEN;
|
||||||
const ptr1 = passStringToWasm0(device_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(device_id, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
wasm.request_ext_capacity_graph(ptr0, len0, ptr1, len1);
|
wasm.request_ext_capacity_graph(ptr0, len0, ptr1, len1);
|
||||||
}
|
}
|
||||||
@ -527,7 +532,7 @@ function handleError(f, args) {
|
|||||||
try {
|
try {
|
||||||
return f.apply(this, args);
|
return f.apply(this, args);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
wasm.__wbindgen_exn_store(addHeapObject(e));
|
wasm.__wbindgen_export_5(addHeapObject(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,75 +575,39 @@ async function __wbg_load(module, imports) {
|
|||||||
function __wbg_get_imports() {
|
function __wbg_get_imports() {
|
||||||
const imports = {};
|
const imports = {};
|
||||||
imports.wbg = {};
|
imports.wbg = {};
|
||||||
|
imports.wbg.__wbg_new_39e958ac9d5cae7d = function() { return handleError(function (arg0, arg1) {
|
||||||
|
const ret = new WebSocket(getStringFromWasm0(arg0, arg1));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
|
||||||
|
const ret = getStringFromWasm0(arg0, arg1);
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_setbinaryType_2e2320b177c86b17 = function(arg0, arg1) {
|
||||||
|
getObject(arg0).binaryType = takeObject(arg1);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_setonclose_6b22bc5d93628786 = function(arg0, arg1) {
|
||||||
|
getObject(arg0).onclose = getObject(arg1);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_setonerror_9f7532626d7a9ce2 = function(arg0, arg1) {
|
||||||
|
getObject(arg0).onerror = getObject(arg1);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_setonopen_6fd8b28538150568 = function(arg0, arg1) {
|
||||||
|
getObject(arg0).onopen = getObject(arg1);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_setonmessage_493b82147081ec7e = function(arg0, arg1) {
|
||||||
|
getObject(arg0).onmessage = getObject(arg1);
|
||||||
|
};
|
||||||
imports.wbg.__wbg_log_cd48b3599daf93ee = function(arg0, arg1) {
|
imports.wbg.__wbg_log_cd48b3599daf93ee = function(arg0, arg1) {
|
||||||
console.log(getStringFromWasm0(arg0, arg1));
|
console.log(getStringFromWasm0(arg0, arg1));
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_windowbusgetToken_eab6ac8f06d69af2 = function(arg0) {
|
imports.wbg.__wbg_windowbusgetToken_eab6ac8f06d69af2 = function(arg0) {
|
||||||
const ret = window.bus.getToken();
|
const ret = window.bus.getToken();
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_windowonAuthOk_9cd9fb8f74884ca4 = function(arg0, arg1, arg2, arg3, arg4, arg5) {
|
|
||||||
let deferred0_0;
|
|
||||||
let deferred0_1;
|
|
||||||
let deferred1_0;
|
|
||||||
let deferred1_1;
|
|
||||||
let deferred2_0;
|
|
||||||
let deferred2_1;
|
|
||||||
try {
|
|
||||||
deferred0_0 = arg0;
|
|
||||||
deferred0_1 = arg1;
|
|
||||||
deferred1_0 = arg2;
|
|
||||||
deferred1_1 = arg3;
|
|
||||||
deferred2_0 = arg4;
|
|
||||||
deferred2_1 = arg5;
|
|
||||||
window.onAuthOk(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3), getStringFromWasm0(arg4, arg5));
|
|
||||||
} finally {
|
|
||||||
wasm.__wbindgen_free(deferred0_0, deferred0_1);
|
|
||||||
wasm.__wbindgen_free(deferred1_0, deferred1_1);
|
|
||||||
wasm.__wbindgen_free(deferred2_0, deferred2_1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_windowonAuthFail_ddfdfcd594ff15b8 = typeof window.onAuthFail == 'function' ? window.onAuthFail : notDefined('window.onAuthFail');
|
|
||||||
imports.wbg.__wbg_windowonMessage_5c5b80d5376153dc = function(arg0, arg1) {
|
|
||||||
let deferred0_0;
|
|
||||||
let deferred0_1;
|
|
||||||
try {
|
|
||||||
deferred0_0 = arg0;
|
|
||||||
deferred0_1 = arg1;
|
|
||||||
window.onMessage(getStringFromWasm0(arg0, arg1));
|
|
||||||
} finally {
|
|
||||||
wasm.__wbindgen_free(deferred0_0, deferred0_1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_setonopen_6fd8b28538150568 = function(arg0, arg1) {
|
|
||||||
getObject(arg0).onopen = getObject(arg1);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_setonerror_9f7532626d7a9ce2 = function(arg0, arg1) {
|
|
||||||
getObject(arg0).onerror = getObject(arg1);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_setonclose_6b22bc5d93628786 = function(arg0, arg1) {
|
|
||||||
getObject(arg0).onclose = getObject(arg1);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_setonmessage_493b82147081ec7e = function(arg0, arg1) {
|
|
||||||
getObject(arg0).onmessage = getObject(arg1);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_setbinaryType_2e2320b177c86b17 = function(arg0, arg1) {
|
|
||||||
getObject(arg0).binaryType = takeObject(arg1);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_new_39e958ac9d5cae7d = function() { return handleError(function (arg0, arg1) {
|
|
||||||
const ret = new WebSocket(getStringFromWasm0(arg0, arg1));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_send_737fddb36434277e = function() { return handleError(function (arg0, arg1, arg2) {
|
|
||||||
getObject(arg0).send(getArrayU8FromWasm0(arg1, arg2));
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
|
|
||||||
const ret = getStringFromWasm0(arg0, arg1);
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_data_ef47af9c565d228b = function(arg0) {
|
imports.wbg.__wbg_data_ef47af9c565d228b = function(arg0) {
|
||||||
const ret = getObject(arg0).data;
|
const ret = getObject(arg0).data;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
@ -661,19 +630,59 @@ function __wbg_get_imports() {
|
|||||||
const ret = getObject(arg0).length;
|
const ret = getObject(arg0).length;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_set_4b3aa8445ac1e91c = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_memory = function() {
|
||||||
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
|
const ret = wasm.memory;
|
||||||
};
|
return addHeapObject(ret);
|
||||||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
|
||||||
takeObject(arg0);
|
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_buffer_fcbfb6d88b2732e9 = function(arg0) {
|
imports.wbg.__wbg_buffer_fcbfb6d88b2732e9 = function(arg0) {
|
||||||
const ret = getObject(arg0).buffer;
|
const ret = getObject(arg0).buffer;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbg_set_4b3aa8445ac1e91c = function(arg0, arg1, arg2) {
|
||||||
|
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_windowonMessage_5c5b80d5376153dc = function(arg0, arg1) {
|
||||||
|
let deferred0_0;
|
||||||
|
let deferred0_1;
|
||||||
|
try {
|
||||||
|
deferred0_0 = arg0;
|
||||||
|
deferred0_1 = arg1;
|
||||||
|
window.onMessage(getStringFromWasm0(arg0, arg1));
|
||||||
|
} finally {
|
||||||
|
wasm.__wbindgen_export_4(deferred0_0, deferred0_1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_windowonAuthOk_9cd9fb8f74884ca4 = function(arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||||
|
let deferred0_0;
|
||||||
|
let deferred0_1;
|
||||||
|
let deferred1_0;
|
||||||
|
let deferred1_1;
|
||||||
|
let deferred2_0;
|
||||||
|
let deferred2_1;
|
||||||
|
try {
|
||||||
|
deferred0_0 = arg0;
|
||||||
|
deferred0_1 = arg1;
|
||||||
|
deferred1_0 = arg2;
|
||||||
|
deferred1_1 = arg3;
|
||||||
|
deferred2_0 = arg4;
|
||||||
|
deferred2_1 = arg5;
|
||||||
|
window.onAuthOk(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3), getStringFromWasm0(arg4, arg5));
|
||||||
|
} finally {
|
||||||
|
wasm.__wbindgen_export_4(deferred0_0, deferred0_1);
|
||||||
|
wasm.__wbindgen_export_4(deferred1_0, deferred1_1);
|
||||||
|
wasm.__wbindgen_export_4(deferred2_0, deferred2_1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
imports.wbg.__wbg_windowonAuthFail_ddfdfcd594ff15b8 = typeof window.onAuthFail == 'function' ? window.onAuthFail : notDefined('window.onAuthFail');
|
||||||
|
imports.wbg.__wbg_send_737fddb36434277e = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
|
getObject(arg0).send(getArrayU8FromWasm0(arg1, arg2));
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
||||||
|
takeObject(arg0);
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
||||||
const ret = debugString(getObject(arg1));
|
const ret = debugString(getObject(arg1));
|
||||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1);
|
||||||
const len1 = WASM_VECTOR_LEN;
|
const len1 = WASM_VECTOR_LEN;
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||||
@ -681,16 +690,12 @@ function __wbg_get_imports() {
|
|||||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_memory = function() {
|
imports.wbg.__wbindgen_closure_wrapper1471 = function(arg0, arg1, arg2) {
|
||||||
const ret = wasm.memory;
|
const ret = makeMutClosure(arg0, arg1, 8, __wbg_adapter_12);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper440 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper1473 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 89, __wbg_adapter_12);
|
const ret = makeMutClosure(arg0, arg1, 8, __wbg_adapter_12);
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbindgen_closure_wrapper442 = function(arg0, arg1, arg2) {
|
|
||||||
const ret = makeMutClosure(arg0, arg1, 87, __wbg_adapter_15);
|
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
export const memory: WebAssembly.Memory;
|
export const memory: WebAssembly.Memory;
|
||||||
export function connect_wasm_pipe(a: number, b: number): void;
|
export function initialize_wss(a: number, b: number): void;
|
||||||
export function is_wasm_connected(): number;
|
export function is_wasm_connected(): number;
|
||||||
export function send_wss_queue(): void;
|
export function send_wss_queue(): void;
|
||||||
export function send_token(a: number, b: number): void;
|
export function send_token(a: number, b: number): void;
|
||||||
@ -15,6 +15,7 @@ export function request_throughput_chart_for_node(a: number, b: number, c: numbe
|
|||||||
export function request_throughput_chart_for_circuit(a: number, b: number, c: number, d: number): void;
|
export function request_throughput_chart_for_circuit(a: number, b: number, c: number, d: number): void;
|
||||||
export function request_site_stack(a: number, b: number, c: number, d: number): void;
|
export function request_site_stack(a: number, b: number, c: number, d: number): void;
|
||||||
export function request_rtt_chart(a: number, b: number): void;
|
export function request_rtt_chart(a: number, b: number): void;
|
||||||
|
export function request_rtt_histogram(a: number, b: number): void;
|
||||||
export function request_rtt_chart_for_site(a: number, b: number, c: number, d: number): void;
|
export function request_rtt_chart_for_site(a: number, b: number, c: number, d: number): void;
|
||||||
export function request_rtt_chart_for_node(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
export function request_rtt_chart_for_node(a: number, b: number, c: number, d: number, e: number, f: number): void;
|
||||||
export function request_rtt_chart_for_circuit(a: number, b: number, c: number, d: number): void;
|
export function request_rtt_chart_for_circuit(a: number, b: number, c: number, d: number): void;
|
||||||
@ -31,10 +32,9 @@ export function request_circuit_info(a: number, b: number): void;
|
|||||||
export function request_ext_device_info(a: number, b: number): void;
|
export function request_ext_device_info(a: number, b: number): void;
|
||||||
export function request_ext_snr_graph(a: number, b: number, c: number, d: number): void;
|
export function request_ext_snr_graph(a: number, b: number, c: number, d: number): void;
|
||||||
export function request_ext_capacity_graph(a: number, b: number, c: number, d: number): void;
|
export function request_ext_capacity_graph(a: number, b: number, c: number, d: number): void;
|
||||||
export function __wbindgen_malloc(a: number): number;
|
export function __wbindgen_export_0(a: number): number;
|
||||||
export function __wbindgen_realloc(a: number, b: number, c: number): number;
|
export function __wbindgen_export_1(a: number, b: number, c: number): number;
|
||||||
export const __wbindgen_export_2: WebAssembly.Table;
|
export const __wbindgen_export_2: WebAssembly.Table;
|
||||||
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb4b341652e081e3f(a: number, b: number, c: number): void;
|
export function __wbindgen_export_3(a: number, b: number, c: number): void;
|
||||||
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha318d2d73313995c(a: number, b: number, c: number): void;
|
export function __wbindgen_export_4(a: number, b: number): void;
|
||||||
export function __wbindgen_free(a: number, b: number): void;
|
export function __wbindgen_export_5(a: number): void;
|
||||||
export function __wbindgen_exn_store(a: number): void;
|
|
||||||
|
@ -13,6 +13,7 @@ miniz_oxide = "0.7.1"
|
|||||||
serde_cbor = "0" # For RFC8949/7409 format C binary objects
|
serde_cbor = "0" # For RFC8949/7409 format C binary objects
|
||||||
wasm_pipe_types = { path = "../wasm_pipe_types" }
|
wasm_pipe_types = { path = "../wasm_pipe_types" }
|
||||||
serde_json = "1.0.96"
|
serde_json = "1.0.96"
|
||||||
|
thiserror = "1.0.44"
|
||||||
|
|
||||||
[dependencies.web-sys]
|
[dependencies.web-sys]
|
||||||
version = "0.3.22"
|
version = "0.3.22"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cargo build --target wasm32-unknown-unknown
|
CARGO_PROFILE_RELEASE_OPT_LEVEL=z CARGO_PROFILE_RELEASE_LTO=true CARGO_PROFILE_RELEASE_STRIP=symbols CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 CARGO_PROFILE_RELEASE_INCREMENTAL=false cargo build --target wasm32-unknown-unknown --release
|
||||||
wasm-bindgen --target web --out-dir staging/ ../../target/wasm32-unknown-unknown/debug/wasm_pipe.wasm
|
wasm-bindgen --target web --out-dir staging/ ../../target/wasm32-unknown-unknown/release/wasm_pipe.wasm
|
||||||
cp staging/* ../site_build/wasm
|
cp staging/* ../site_build/wasm
|
||||||
cp staging/wasm_pipe_bg.wasm ../lts_node/web
|
cp staging/wasm_pipe_bg.wasm ../lts_node/web
|
||||||
|
227
src/rust/long_term_stats/wasm_pipe/src/conduit.rs
Normal file
227
src/rust/long_term_stats/wasm_pipe/src/conduit.rs
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use wasm_pipe_types::{WasmResponse, WasmRequest};
|
||||||
|
use web_sys::{WebSocket, BinaryType, ErrorEvent, MessageEvent};
|
||||||
|
use thiserror::Error;
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
use crate::{message::{WsResponseMessage, WsRequestMessage}, onAuthOk, onAuthFail, onMessage, get_token};
|
||||||
|
use super::log;
|
||||||
|
|
||||||
|
static mut CONDUIT: Option<Conduit> = None;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn initialize_wss(url: String) {
|
||||||
|
log(&format!("Initializing WSS to: {url}"));
|
||||||
|
unsafe {
|
||||||
|
if CONDUIT.is_none() {
|
||||||
|
CONDUIT = Some(Conduit::new(url));
|
||||||
|
|
||||||
|
if let Some(conduit) = &mut CONDUIT {
|
||||||
|
match conduit.connect() {
|
||||||
|
Ok(_) => log("Connection requested."),
|
||||||
|
Err(e) => log(&format!("Error connecting: {:?}", e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log("Conduit already initialized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn is_wasm_connected() -> bool {
|
||||||
|
unsafe {
|
||||||
|
if let Some(conduit) = &CONDUIT {
|
||||||
|
conduit.is_connected()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn send_wss_queue() {
|
||||||
|
unsafe {
|
||||||
|
if let Some(conduit) = &mut CONDUIT {
|
||||||
|
conduit.send_queue();
|
||||||
|
} else {
|
||||||
|
log("No conduit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_message(msg: WasmRequest) {
|
||||||
|
unsafe {
|
||||||
|
if let Some(conduit) = &mut CONDUIT {
|
||||||
|
conduit.enqueue_raw(msg);
|
||||||
|
} else {
|
||||||
|
log("No conduit");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
enum WebSocketError {
|
||||||
|
#[error("URL is empty")]
|
||||||
|
NoURL,
|
||||||
|
#[error("Already connected")]
|
||||||
|
AlreadyConnected,
|
||||||
|
#[error("WebSocket already exists")]
|
||||||
|
AlreadyExists,
|
||||||
|
#[error("WebSocket Creation Error")]
|
||||||
|
CreationError,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
enum ConnectionStatus {
|
||||||
|
New,
|
||||||
|
Connected,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handles WS connection to the server.
|
||||||
|
struct Conduit {
|
||||||
|
status: ConnectionStatus,
|
||||||
|
socket: Option<WebSocket>,
|
||||||
|
url: String,
|
||||||
|
message_queue: VecDeque<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Conduit {
|
||||||
|
fn new(url: String) -> Self {
|
||||||
|
Self {
|
||||||
|
status: ConnectionStatus::New,
|
||||||
|
socket: None,
|
||||||
|
url,
|
||||||
|
message_queue: VecDeque::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect(&mut self) -> Result<(), WebSocketError> {
|
||||||
|
// Precondition testing
|
||||||
|
if self.url.is_empty() { return Err(WebSocketError::NoURL); }
|
||||||
|
if self.status != ConnectionStatus::New { return Err(WebSocketError::AlreadyConnected); }
|
||||||
|
if self.socket.is_some() { return Err(WebSocketError::AlreadyExists); }
|
||||||
|
self.socket = Some(WebSocket::new(&self.url).map_err(|_| WebSocketError::CreationError)?);
|
||||||
|
if let Some(socket) = &mut self.socket {
|
||||||
|
socket.set_binary_type(BinaryType::Arraybuffer);
|
||||||
|
|
||||||
|
// Wire up on_close
|
||||||
|
let onclose_callback = Closure::<dyn FnMut(_)>::new(move |_e: ErrorEvent| {
|
||||||
|
on_close();
|
||||||
|
});
|
||||||
|
socket.set_onclose(Some(onclose_callback.as_ref().unchecked_ref()));
|
||||||
|
onclose_callback.forget();
|
||||||
|
|
||||||
|
// Wire up on_error
|
||||||
|
let onerror_callback = Closure::<dyn FnMut(_)>::new(move |e: ErrorEvent| {
|
||||||
|
log(&format!("Error Received: {e:?}"));
|
||||||
|
on_error()
|
||||||
|
});
|
||||||
|
socket.set_onerror(Some(onerror_callback.as_ref().unchecked_ref()));
|
||||||
|
onerror_callback.forget();
|
||||||
|
|
||||||
|
// Wire up on_open
|
||||||
|
let onopen_callback = Closure::<dyn FnMut(_)>::new(move |_e: ErrorEvent| {
|
||||||
|
log("Open Received");
|
||||||
|
on_open();
|
||||||
|
});
|
||||||
|
socket.set_onopen(Some(onopen_callback.as_ref().unchecked_ref()));
|
||||||
|
onopen_callback.forget();
|
||||||
|
|
||||||
|
// Wire up on message
|
||||||
|
let onmessage_callback = Closure::<dyn FnMut(_)>::new(move |e: MessageEvent| {
|
||||||
|
log("Message Received");
|
||||||
|
if let Ok(abuf) = e.data().dyn_into::<js_sys::ArrayBuffer>() {
|
||||||
|
let response = WsResponseMessage::from_array_buffer(abuf);
|
||||||
|
match response {
|
||||||
|
Err(e) => log(&format!("Error parsing message: {:?}", e)),
|
||||||
|
Ok(WsResponseMessage(msg)) => {
|
||||||
|
match msg {
|
||||||
|
WasmResponse::AuthOk { token, name, license_key } => {
|
||||||
|
onAuthOk(token, name, license_key);
|
||||||
|
}
|
||||||
|
WasmResponse::AuthFail => {
|
||||||
|
onAuthFail();
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let json = serde_json::to_string(&msg).unwrap();
|
||||||
|
onMessage(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
socket.set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref()));
|
||||||
|
onmessage_callback.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_connected(&self) -> bool {
|
||||||
|
self.status == ConnectionStatus::Connected
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enqueue_raw(&mut self, message: WasmRequest) {
|
||||||
|
let msg = WsRequestMessage::new(message);
|
||||||
|
self.enqueue_message(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enqueue_message(&mut self, message: WsRequestMessage) {
|
||||||
|
let serialized = message.serialize();
|
||||||
|
match serialized {
|
||||||
|
Ok(msg) => self.message_queue.push_back(msg),
|
||||||
|
Err(e) => log(&format!("Error enqueing message: {:?}", e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_queue(&mut self) {
|
||||||
|
// Bail out if there's nothing to do
|
||||||
|
if self.message_queue.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send queued messages
|
||||||
|
if let Some(ws) = &mut self.socket {
|
||||||
|
while let Some(msg) = self.message_queue.pop_front() {
|
||||||
|
log(&format!("Sending message: {msg:?}"));
|
||||||
|
if let Err(e) = ws.send_with_u8_array(&msg) {
|
||||||
|
log(&format!("Error sending message: {e:?}"));
|
||||||
|
self.status = ConnectionStatus::New;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log("No WebSocket connection");
|
||||||
|
let _ = self.connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_close() {
|
||||||
|
unsafe {
|
||||||
|
if let Some(conduit) = &mut CONDUIT {
|
||||||
|
conduit.socket = None;
|
||||||
|
conduit.status = ConnectionStatus::New;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_error() {
|
||||||
|
unsafe {
|
||||||
|
if let Some(conduit) = &mut CONDUIT {
|
||||||
|
conduit.socket = None;
|
||||||
|
conduit.status = ConnectionStatus::New;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_open() {
|
||||||
|
unsafe {
|
||||||
|
if let Some(conduit) = &mut CONDUIT {
|
||||||
|
conduit.status = ConnectionStatus::Connected;
|
||||||
|
conduit.enqueue_raw(WasmRequest::Auth { token: get_token() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,7 @@
|
|||||||
use std::collections::VecDeque;
|
|
||||||
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_pipe_types::{WasmRequest, WasmResponse};
|
use wasm_pipe_types::WasmRequest;
|
||||||
use web_sys::{BinaryType, ErrorEvent, MessageEvent, WebSocket};
|
mod conduit;
|
||||||
|
mod message;
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -22,117 +21,11 @@ extern "C" {
|
|||||||
fn onMessage(json: String);
|
fn onMessage(json: String);
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut CONNECTED: bool = false;
|
pub use conduit::{initialize_wss, is_wasm_connected, send_wss_queue};
|
||||||
static mut WS: Option<WebSocket> = None;
|
|
||||||
static mut QUEUE: VecDeque<Vec<u8>> = VecDeque::new();
|
|
||||||
static mut URL: String = String::new();
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
pub fn connect_wasm_pipe(url: String) {
|
|
||||||
unsafe {
|
|
||||||
if CONNECTED {
|
|
||||||
log("Already connected");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if !url.is_empty() {
|
|
||||||
URL = url.clone();
|
|
||||||
}
|
|
||||||
WS = Some(WebSocket::new(&url).unwrap());
|
|
||||||
if let Some(ws) = &mut WS {
|
|
||||||
ws.set_binary_type(BinaryType::Arraybuffer);
|
|
||||||
|
|
||||||
ws.set_binary_type(BinaryType::Arraybuffer);
|
|
||||||
let onmessage_callback = Closure::<dyn FnMut(_)>::new(move |e: MessageEvent| {
|
|
||||||
log("Message Received");
|
|
||||||
if let Ok(abuf) = e.data().dyn_into::<js_sys::ArrayBuffer>() {
|
|
||||||
let array = js_sys::Uint8Array::new(&abuf);
|
|
||||||
//let len = array.byte_length() as usize;
|
|
||||||
let raw = array.to_vec();
|
|
||||||
let decompressed = miniz_oxide::inflate::decompress_to_vec(&raw).unwrap();
|
|
||||||
let msg: WasmResponse = serde_cbor::from_slice(&decompressed).unwrap();
|
|
||||||
//log(&format!("Message: {:?}", msg));
|
|
||||||
|
|
||||||
match msg {
|
|
||||||
WasmResponse::AuthOk { token, name, license_key } => {
|
|
||||||
onAuthOk(token, name, license_key);
|
|
||||||
}
|
|
||||||
WasmResponse::AuthFail => {
|
|
||||||
onAuthFail();
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let json = serde_json::to_string(&msg).unwrap();
|
|
||||||
onMessage(json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let onerror_callback = Closure::<dyn FnMut(_)>::new(move |e: ErrorEvent| {
|
|
||||||
log(&format!("Error Received: {e:?}"));
|
|
||||||
CONNECTED = false;
|
|
||||||
});
|
|
||||||
let onclose_callback = Closure::<dyn FnMut(_)>::new(move |_e: ErrorEvent| {
|
|
||||||
log("Close Received");
|
|
||||||
CONNECTED = false;
|
|
||||||
});
|
|
||||||
let onopen_callback = Closure::<dyn FnMut(_)>::new(move |_e: ErrorEvent| {
|
|
||||||
log("Open Received");
|
|
||||||
CONNECTED = true;
|
|
||||||
let token = get_token();
|
|
||||||
send_token(token);
|
|
||||||
});
|
|
||||||
ws.set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref()));
|
|
||||||
ws.set_onclose(Some(onclose_callback.as_ref().unchecked_ref()));
|
|
||||||
ws.set_onerror(Some(onerror_callback.as_ref().unchecked_ref()));
|
|
||||||
ws.set_onopen(Some(onopen_callback.as_ref().unchecked_ref()));
|
|
||||||
// Prevent closures from recursing
|
|
||||||
onopen_callback.forget();
|
|
||||||
onclose_callback.forget();
|
|
||||||
onerror_callback.forget();
|
|
||||||
onmessage_callback.forget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
pub fn is_wasm_connected() -> bool {
|
|
||||||
unsafe { CONNECTED && WS.is_some() }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
pub fn send_wss_queue() {
|
|
||||||
//log("Call to send queue");
|
|
||||||
unsafe {
|
|
||||||
// Bail out if there's nothing to do
|
|
||||||
if QUEUE.is_empty() {
|
|
||||||
//log("Queue is empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send queued messages
|
|
||||||
if let Some(ws) = &mut WS {
|
|
||||||
while let Some(msg) = QUEUE.pop_front() {
|
|
||||||
log(&format!("Sending message: {msg:?}"));
|
|
||||||
ws.send_with_u8_array(&msg).unwrap();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log("No WebSocket connection");
|
|
||||||
CONNECTED = false;
|
|
||||||
connect_wasm_pipe(String::new());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_message(msg: WasmRequest) -> Vec<u8> {
|
|
||||||
let cbor = serde_cbor::to_vec(&msg).unwrap();
|
|
||||||
miniz_oxide::deflate::compress_to_vec(&cbor, 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn send_message(msg: WasmRequest) {
|
fn send_message(msg: WasmRequest) {
|
||||||
log(&format!("Sending message: {msg:?}"));
|
log(&format!("Enqueueing message: {msg:?}"));
|
||||||
let msg = build_message(msg);
|
conduit::send_message(msg);
|
||||||
unsafe {
|
|
||||||
QUEUE.push_back(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@ -196,6 +89,11 @@ pub fn request_rtt_chart(period: String) {
|
|||||||
send_message(WasmRequest::RttChart { period });
|
send_message(WasmRequest::RttChart { period });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn request_rtt_histogram(period: String) {
|
||||||
|
send_message(WasmRequest::RttHistogram { period });
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn request_rtt_chart_for_site(period: String, site_id: String) {
|
pub fn request_rtt_chart_for_site(period: String, site_id: String) {
|
||||||
send_message(WasmRequest::RttChartSite { period, site_id });
|
send_message(WasmRequest::RttChartSite { period, site_id });
|
||||||
|
40
src/rust/long_term_stats/wasm_pipe/src/message.rs
Normal file
40
src/rust/long_term_stats/wasm_pipe/src/message.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use thiserror::Error;
|
||||||
|
use wasm_pipe_types::{WasmRequest, WasmResponse};
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum MessageError {
|
||||||
|
#[error("Unable to decompress stream")]
|
||||||
|
DecompressError,
|
||||||
|
#[error("Unable to de-serialize CBOR into native type")]
|
||||||
|
DeserializeError,
|
||||||
|
#[error("Unable to serialize CBOR from native type")]
|
||||||
|
SerializeError,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WsResponseMessage(pub WasmResponse);
|
||||||
|
|
||||||
|
impl WsResponseMessage {
|
||||||
|
pub fn from_array_buffer(buffer: js_sys::ArrayBuffer) -> Result<Self, MessageError> {
|
||||||
|
// Convert the array buffer into a strongly typed buffer
|
||||||
|
let array = js_sys::Uint8Array::new(&buffer);
|
||||||
|
let raw = array.to_vec();
|
||||||
|
let decompressed = miniz_oxide::inflate::decompress_to_vec(&raw)
|
||||||
|
.map_err(|_| MessageError::DecompressError)?;
|
||||||
|
let msg: WasmResponse =
|
||||||
|
serde_cbor::from_slice(&decompressed).map_err(|_| MessageError::DeserializeError)?;
|
||||||
|
Ok(Self(msg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct WsRequestMessage(pub WasmRequest);
|
||||||
|
|
||||||
|
impl WsRequestMessage {
|
||||||
|
pub fn new(msg: WasmRequest) -> Self {
|
||||||
|
Self(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize(&self) -> Result<Vec<u8>, MessageError> {
|
||||||
|
let cbor = serde_cbor::to_vec(&self.0).map_err(|_| MessageError::SerializeError)?;
|
||||||
|
Ok(miniz_oxide::deflate::compress_to_vec(&cbor, 8))
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ pub enum WasmRequest {
|
|||||||
ThroughputChartSite { period: String, site_id: String },
|
ThroughputChartSite { period: String, site_id: String },
|
||||||
ThroughputChartCircuit { period: String, circuit_id: String },
|
ThroughputChartCircuit { period: String, circuit_id: String },
|
||||||
RttChart { period: String },
|
RttChart { period: String },
|
||||||
|
RttHistogram { period: String },
|
||||||
RttChartSingle { period: String, node_id: String, node_name: String },
|
RttChartSingle { period: String, node_id: String, node_name: String },
|
||||||
RttChartSite { period: String, site_id: String },
|
RttChartSite { period: String, site_id: String },
|
||||||
RttChartCircuit { period: String, circuit_id: String },
|
RttChartCircuit { period: String, circuit_id: String },
|
||||||
@ -42,10 +43,11 @@ pub enum WasmResponse {
|
|||||||
NodeStatus { nodes: Vec<Node> },
|
NodeStatus { nodes: Vec<Node> },
|
||||||
PacketChart { nodes: Vec<PacketHost> },
|
PacketChart { nodes: Vec<PacketHost> },
|
||||||
BitsChart { nodes: Vec<ThroughputHost> },
|
BitsChart { nodes: Vec<ThroughputHost> },
|
||||||
RttChart { nodes: Vec<RttHost>, histogram: Vec<u32> },
|
RttChart { nodes: Vec<RttHost> },
|
||||||
|
RttHistogram { histogram: Vec<u32> },
|
||||||
RttChartSite { nodes: Vec<RttHost>, histogram: Vec<u32> },
|
RttChartSite { nodes: Vec<RttHost>, histogram: Vec<u32> },
|
||||||
RttChartCircuit { nodes: Vec<RttHost>, histogram: Vec<u32> },
|
RttChartCircuit { nodes: Vec<RttHost>, histogram: Vec<u32> },
|
||||||
SiteStack { nodes: Vec<ThroughputHost> },
|
SiteStack { nodes: Vec<SiteStackHost> },
|
||||||
RootHeat { data: HashMap<String, Vec<(DateTime<FixedOffset>, f64)>>},
|
RootHeat { data: HashMap<String, Vec<(DateTime<FixedOffset>, f64)>>},
|
||||||
SiteHeat { data: HashMap<String, Vec<(DateTime<FixedOffset>, f64)>>},
|
SiteHeat { data: HashMap<String, Vec<(DateTime<FixedOffset>, f64)>>},
|
||||||
NodePerfChart { nodes: Vec<PerfHost> },
|
NodePerfChart { nodes: Vec<PerfHost> },
|
||||||
@ -97,6 +99,19 @@ impl ThroughputHost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct SiteStackHost {
|
||||||
|
pub node_name: String,
|
||||||
|
pub download: Vec<(String, i64)>,
|
||||||
|
pub upload: Vec<(String, i64)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SiteStackHost {
|
||||||
|
pub fn total(&self) -> i64 {
|
||||||
|
self.download.iter().map(|x| x.1).sum::<i64>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct Throughput {
|
pub struct Throughput {
|
||||||
pub value: f64,
|
pub value: f64,
|
||||||
|
Loading…
Reference in New Issue
Block a user