From f9d8de8453f58dec53719d8056bbaadf9bc6cdb9 Mon Sep 17 00:00:00 2001 From: Eugene Date: Sun, 28 Apr 2024 23:31:46 +0400 Subject: [PATCH 1/7] bump deps --- Cargo.lock | 312 +++++++++++++++++++++-------------------------------- Cargo.toml | 7 +- 2 files changed, 127 insertions(+), 192 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 715a6c0..04654b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,17 +178,20 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "binance-rs-async" version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2347d34c9a4dd742ad5dbcd1b31d1783b488048a338e5c961845edd872bea6e7" +source = "git+https://github.com/Fogapod/binance-rs-async?rev=1197a144dbf8926995d173216f6faaba03899d2a#1197a144dbf8926995d173216f6faaba03899d2a" dependencies = [ - "boolinator", "chrono", "futures", "hex", - "lazy_static", "reqwest", "ring", "serde", @@ -291,12 +294,6 @@ dependencies = [ "objc2", ] -[[package]] -name = "boolinator" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" - [[package]] name = "bumpalo" version = "3.15.4" @@ -901,15 +898,6 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" -[[package]] -name = "encoding_rs" -version = "0.8.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" -dependencies = [ - "cfg-if", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1422,25 +1410,6 @@ dependencies = [ "svg_fmt", ] -[[package]] -name = "h2" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "2.4.0" @@ -1511,9 +1480,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1521,24 +1490,25 @@ dependencies = [ ] [[package]] -name = "http" -version = "1.1.0" +name = "http-body" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "fnv", - "itoa", + "http", ] [[package]] -name = "http-body" -version = "0.4.6" +name = "http-body-util" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", - "http 0.2.12", + "futures-core", + "http", + "http-body", "pin-project-lite", ] @@ -1548,48 +1518,60 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "hyper" -version = "0.14.28" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", - "h2", - "http 0.2.12", + "http", "http-body", "httparse", - "httpdate", "itoa", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http 0.2.12", + "http", "hyper", - "rustls 0.21.10", + "hyper-util", + "rustls", + "rustls-pki-types", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -2654,6 +2636,26 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -3017,20 +3019,20 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "reqwest" -version = "0.11.26" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ - "base64", + "base64 0.22.0", "bytes", - "encoding_rs", "futures-core", "futures-util", - "h2", - "http 0.2.12", + "http", "http-body", + "http-body-util", "hyper", "hyper-rustls", + "hyper-util", "ipnet", "js-sys", "log", @@ -3038,21 +3040,21 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls", "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.4", + "webpki-roots", "winreg", ] @@ -3155,18 +3157,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.21.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.7", - "sct", -] - [[package]] name = "rustls" version = "0.22.2" @@ -3176,18 +3166,19 @@ dependencies = [ "log", "ring", "rustls-pki-types", - "rustls-webpki 0.102.2", + "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64", + "base64 0.22.0", + "rustls-pki-types", ] [[package]] @@ -3196,16 +3187,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "868e20fada228fefaf6b652e00cc73623d54f8171e7352c18bb281571f2d92da" -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustls-webpki" version = "0.102.2" @@ -3277,16 +3258,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "sctk-adwaita" version = "0.8.1" @@ -3345,9 +3316,9 @@ dependencies = [ [[package]] name = "serde_qs" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" +checksum = "cd34f36fe4c5ba9654417139a9b3a20d2e1de6012ee678ad14d240c22c78d8d6" dependencies = [ "percent-encoding", "serde", @@ -3403,15 +3374,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "simd-adler32" version = "0.3.7" @@ -3646,27 +3608,6 @@ dependencies = [ "libc", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -3772,18 +3713,16 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", "libc", "mio", "num_cpus", - "parking_lot 0.12.1", "pin-project-lite", - "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.48.0", @@ -3800,23 +3739,13 @@ dependencies = [ "syn 2.0.53", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.10", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.2", + "rustls", "rustls-pki-types", "tokio", ] @@ -3829,26 +3758,12 @@ checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", - "rustls 0.22.2", + "rustls", "rustls-pki-types", "tokio", - "tokio-rustls 0.25.0", + "tokio-rustls", "tungstenite", - "webpki-roots 0.26.1", -] - -[[package]] -name = "tokio-util" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", + "webpki-roots", ] [[package]] @@ -3868,6 +3783,28 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -3880,6 +3817,7 @@ version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3968,11 +3906,11 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http", "httparse", "log", "rand", - "rustls 0.22.2", + "rustls", "rustls-pki-types", "sha1", "thiserror", @@ -4084,7 +4022,7 @@ version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c51daa774fe9ee5efcf7b4fec13019b8119cda764d9a8b5b06df02bb1445c656" dependencies = [ - "base64", + "base64 0.21.7", "log", "pico-args", "usvg-parser", @@ -4392,12 +4330,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webpki-roots" version = "0.26.1" @@ -4859,9 +4791,9 @@ dependencies = [ [[package]] name = "winreg" -version = "0.50.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" dependencies = [ "cfg-if", "windows-sys 0.48.0", diff --git a/Cargo.toml b/Cargo.toml index 5144d83..75d126e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,13 +9,13 @@ identifier = "io.github.me.dynasty" icon = ["assets/dynasty.icns"] [dependencies] -binance-rs-async = { version = "1.3.2", default_features = false, features = ["rustls-tls", "wallet_api"] } +binance-rs-async = { version = "1.3.3", default_features = false, features = ["rustls-tls", "wallet_api"] } chrono = "0.4.31" iced = { version = "0.12.0", features = ["tokio", "debug", "lazy", "svg", "image", "advanced", "canvas"] } iced_futures = "0.12.0" serde = { version = "1.0.197", features = ["derive"] } serde_json = "1.0.114" -tokio = { version = "1.32.0", default-features = false, features=["sync"]} +tokio = { version = "1.37.0", default-features = false, features=["sync", "macros"]} ngnk = { path = "crates/ngnk", optional = true } meval = { version = "0.2.0", optional = true } plotters = "0.3.5" @@ -43,6 +43,9 @@ directories-next = "2.0" [target.'cfg(target_arch = "wasm32")'.dependencies] web-sys = { version = "0.3", features = ["Window", "Storage"] } +[patch.crates-io] +binance-rs-async = { git = "https://github.com/Fogapod/binance-rs-async", rev = "1197a144dbf8926995d173216f6faaba03899d2a" } + [profile.release] codegen-units = 1 lto = true From 0bf2098253af480785080ded1cea82d31777cc7f Mon Sep 17 00:00:00 2001 From: Eugene Date: Mon, 29 Apr 2024 00:06:26 +0400 Subject: [PATCH 2/7] ping pong change --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04654b6..a9f3814 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,7 +187,7 @@ checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" [[package]] name = "binance-rs-async" version = "1.3.3" -source = "git+https://github.com/Fogapod/binance-rs-async?rev=1197a144dbf8926995d173216f6faaba03899d2a#1197a144dbf8926995d173216f6faaba03899d2a" +source = "git+https://github.com/Fogapod/binance-rs-async?rev=fb2a1daf1063d3b7edb551d4dc8ef8d4d7197538#fb2a1daf1063d3b7edb551d4dc8ef8d4d7197538" dependencies = [ "chrono", "futures", diff --git a/Cargo.toml b/Cargo.toml index 75d126e..2ea329a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ directories-next = "2.0" web-sys = { version = "0.3", features = ["Window", "Storage"] } [patch.crates-io] -binance-rs-async = { git = "https://github.com/Fogapod/binance-rs-async", rev = "1197a144dbf8926995d173216f6faaba03899d2a" } +binance-rs-async = { git = "https://github.com/Fogapod/binance-rs-async", rev = "fb2a1daf1063d3b7edb551d4dc8ef8d4d7197538" } [profile.release] codegen-units = 1 From ebf5701da458bfe072933be230a54fc8fb749978 Mon Sep 17 00:00:00 2001 From: Eugene Date: Fri, 3 May 2024 20:24:52 +0400 Subject: [PATCH 3/7] websocket ping pongs --- Cargo.lock | 1 + Cargo.toml | 10 ++++- src/ws/book.rs | 8 ++-- src/ws/listener.rs | 107 ++++++++++++++++++++++++++++++++++++--------- src/ws/prices.rs | 4 +- src/ws/trades.rs | 8 ++-- src/ws/user.rs | 8 ++-- 7 files changed, 108 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9f3814..8639753 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -889,6 +889,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", + "tungstenite", "web-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 2ea329a..2dd5fc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,10 +12,9 @@ icon = ["assets/dynasty.icns"] binance-rs-async = { version = "1.3.3", default_features = false, features = ["rustls-tls", "wallet_api"] } chrono = "0.4.31" iced = { version = "0.12.0", features = ["tokio", "debug", "lazy", "svg", "image", "advanced", "canvas"] } -iced_futures = "0.12.0" serde = { version = "1.0.197", features = ["derive"] } serde_json = "1.0.114" -tokio = { version = "1.37.0", default-features = false, features=["sync", "macros"]} +tokio = { version = "1.37.0", default-features = false, features = ["sync", "macros", "time"] } ngnk = { path = "crates/ngnk", optional = true } meval = { version = "0.2.0", optional = true } plotters = "0.3.5" @@ -24,11 +23,18 @@ phf = "0.11.1" regex = "1.10.4" ringbuf = "0.3.3" ahash = "0.8.11" + +# logging tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } + # loader widget lyon_algorithms = "1.0.4" +# websocket +iced_futures = "0.12.0" +tungstenite = { version = "0.21.0", default_featurs = false } + [features] default = ["calculator_meval"] diff --git a/src/ws/book.rs b/src/ws/book.rs index 974c035..8256082 100644 --- a/src/ws/book.rs +++ b/src/ws/book.rs @@ -1,4 +1,4 @@ -use std::{error::Error, sync::atomic::AtomicBool}; +use std::error::Error; use binance::websockets::diff_book_depth_stream; use iced::subscription::{self, Subscription}; @@ -81,13 +81,13 @@ impl WsListener for BookWs { } } - fn handle_input(&mut self, input: Self::Input, keep_running: &mut AtomicBool) { + fn handle_input(&mut self, input: Self::Input) -> bool { match input { Message::NewPair(new_pair) => { self.pair = new_pair; - keep_running.store(false, std::sync::atomic::Ordering::Relaxed); + false } - }; + } } } diff --git a/src/ws/listener.rs b/src/ws/listener.rs index 59503fa..d6ab877 100644 --- a/src/ws/listener.rs +++ b/src/ws/listener.rs @@ -1,15 +1,80 @@ -use std::{error::Error, sync::atomic::AtomicBool, time::Duration}; +use std::{ + error::Error, + time::{Duration, Instant}, +}; use binance::websockets::WebSockets; -use iced_futures::futures::{channel::mpsc as mpsc_futures, SinkExt}; -use serde::de::DeserializeOwned; +use iced_futures::futures::{channel::mpsc as mpsc_futures, SinkExt, StreamExt}; use tokio::sync::mpsc as mpsc_tokio; +use tokio::time::timeout; use tracing::info; use super::{WsEvent, WsHandle, WsMessage}; +const PING_INTEVAL: u64 = 5; + +async fn event_loop( + ws: WebSockets<'_, WE>, + output: &mut mpsc_futures::Sender, +) -> binance::errors::Result<()> +where + WE: serde::de::DeserializeOwned, +{ + use binance::errors::Error; + use tungstenite::Message; + + let (socket, _) = ws.socket.expect("socket not connected"); + let (mut tx, mut rx) = socket.split(); + + let mut interval = tokio::time::interval(Duration::from_secs(PING_INTEVAL)); + let mut last_pong = Instant::now(); + + loop { + tokio::select! { + msg = rx.next() => { + let Some(msg) = msg.transpose()? else { + return Ok(()); + }; + + match msg { + Message::Text(msg) => { + let event = serde_json::from_str(msg.as_str())?; + + output.send(event).await.map_err(|e| Error::Msg(e.to_string()))?; + } + Message::Ping(data) => { + let _ = tx.send(Message::Pong(data)).await; + } + Message::Pong(_) => last_pong = Instant::now(), + Message::Close(e) => { + return Err(Error::Msg(format!("Disconnected {e:?}"))); + } + Message::Binary(_) | Message::Frame(_) => {} + } + } + _ = interval.tick() => { + if last_pong.elapsed().as_secs() > PING_INTEVAL * 2 { + return Err(Error::Msg( + format!("Did not receive ping in the last {} seconds)", PING_INTEVAL * 2) + )); + } + + let msg = Message::Ping(Vec::new()); + // NOTE: unsure if timeout is needed here. This does not time out on internet + // disconnect + match timeout(Duration::from_secs(PING_INTEVAL), tx.send(msg)).await { + Ok(result) => if let Err(e) = result { + return Err(Error::Msg(format!("Ping send failed {e}"))) + }, + Err(e) => return Err(Error::Msg(format!("Ping send timed out {e}"))), + } + } + } + } +} + pub(crate) trait WsListener { - type Event: Send + DeserializeOwned; + type Event: serde::de::DeserializeOwned; type Input; type Output; @@ -24,30 +89,25 @@ pub(crate) trait WsListener { /// Handle message from input channel /// - /// `keep_running` can disconnect websocket if set to false - fn handle_input(&mut self, input: Self::Input, keep_running: &mut AtomicBool); + /// Return value indicates wether ws should stay connected + fn handle_input(&mut self, _: Self::Input) -> bool { + true + } /// Main entrypoint async fn run(&mut self, mut output: mpsc_futures::Sender) -> ! { // forward messages out of websocket callback - let (tx, mut rx) = mpsc_tokio::unbounded_channel(); - - let mut web_socket = WebSockets::new(|event| { - tx.send(event) - .map_err(|e| binance::errors::Error::Msg(e.to_string())) - }); + let (mut tx, mut rx) = mpsc_futures::channel(100); let (input_tx, mut input_rx) = mpsc_tokio::unbounded_channel(); - let connected = self.message(WsEvent::Created(WsHandle(input_tx))); - let _ = output.send(connected).await; + let created = self.message(WsEvent::Created(WsHandle(input_tx))); + let _ = output.send(created).await; loop { - let mut keep_running = AtomicBool::new(true); - // input might alter endpoint result if let Ok(input) = input_rx.try_recv() { - self.handle_input(input, &mut keep_running); + self.handle_input(input); continue; } @@ -61,6 +121,7 @@ pub(crate) trait WsListener { } }; + let mut web_socket = WebSockets::new(|_| Ok(())); if let Err(e) = web_socket.connect(&endpoint).await { tracing::error!("connection error: {e}"); @@ -72,21 +133,25 @@ pub(crate) trait WsListener { let connected = self.message(WsEvent::Connected); let _ = output.send(connected).await; + let mut ws_loop = Box::pin(event_loop(web_socket, &mut tx)); + loop { tokio::select! { biased; - ws_closed = web_socket.event_loop(&keep_running) => { + ws_closed = &mut ws_loop => { if let Err(e) = ws_closed { tracing::error!("stream error: {e}"); } break; } input = input_rx.recv() => { - self.handle_input(input.expect("channel closed"), &mut keep_running); + if !self.handle_input(input.expect("channel closed")) { + break; + } } - event = rx.recv() => { - let handled = self.handle_event(event.expect("channel closed")); + event = rx.select_next_some() => { + let handled = self.handle_event(event); let message = self.message(WsEvent::Message(handled)); let _ = output.send(message).await; } diff --git a/src/ws/prices.rs b/src/ws/prices.rs index db54ee9..86e18b1 100644 --- a/src/ws/prices.rs +++ b/src/ws/prices.rs @@ -1,4 +1,4 @@ -use std::{error::Error, sync::atomic::AtomicBool}; +use std::error::Error; use binance::websockets::all_ticker_stream; use iced::subscription::{self, Subscription}; @@ -50,8 +50,6 @@ impl WsListener for PricesWs { fn handle_event(&self, event: Self::Event) -> Self::Output { event } - - fn handle_input(&mut self, _: Self::Input, _: &mut AtomicBool) {} } pub fn connect() -> Subscription { diff --git a/src/ws/trades.rs b/src/ws/trades.rs index 763b1fe..ce63975 100644 --- a/src/ws/trades.rs +++ b/src/ws/trades.rs @@ -1,4 +1,4 @@ -use std::{error::Error, sync::atomic::AtomicBool}; +use std::error::Error; use binance::websockets::agg_trade_stream; use iced::subscription::{self, Subscription}; @@ -76,13 +76,13 @@ impl WsListener for TradesWs { event } - fn handle_input(&mut self, input: Self::Input, keep_running: &mut AtomicBool) { + fn handle_input(&mut self, input: Self::Input) -> bool { match input { Message::NewPair(new_pair) => { self.pair = new_pair; - keep_running.store(false, std::sync::atomic::Ordering::Relaxed); + false } - }; + } } } diff --git a/src/ws/user.rs b/src/ws/user.rs index c3243f1..5032cf7 100644 --- a/src/ws/user.rs +++ b/src/ws/user.rs @@ -1,4 +1,4 @@ -use std::{error::Error, sync::atomic::AtomicBool}; +use std::error::Error; use binance::{api::Binance, userstream::UserStream, ws_model::WebsocketEvent}; use iced::subscription::{self, Subscription}; @@ -46,13 +46,13 @@ impl WsListener for UserWs { event } - fn handle_input(&mut self, input: Self::Input, keep_running: &mut AtomicBool) { + fn handle_input(&mut self, input: Self::Input) -> bool { match input { Message::NewApiKey(new_key) => { self.api_key = new_key; - keep_running.store(false, std::sync::atomic::Ordering::Relaxed); + false } - }; + } } } From 42acd1b4d008c065cd3f7a1e2f256d7e9f77adf6 Mon Sep 17 00:00:00 2001 From: Eugene Date: Sat, 4 May 2024 00:58:38 +0400 Subject: [PATCH 4/7] map_err --- src/ws/listener.rs | 10 ++++------ src/ws/trades.rs | 12 ++++++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/ws/listener.rs b/src/ws/listener.rs index d6ab877..0d1ddc8 100644 --- a/src/ws/listener.rs +++ b/src/ws/listener.rs @@ -62,12 +62,10 @@ where let msg = Message::Ping(Vec::new()); // NOTE: unsure if timeout is needed here. This does not time out on internet // disconnect - match timeout(Duration::from_secs(PING_INTEVAL), tx.send(msg)).await { - Ok(result) => if let Err(e) = result { - return Err(Error::Msg(format!("Ping send failed {e}"))) - }, - Err(e) => return Err(Error::Msg(format!("Ping send timed out {e}"))), - } + timeout(Duration::from_secs(PING_INTEVAL), tx.send(msg)) + .await + .map_err(|e| Error::Msg(format!("Ping send timed out {e}")))? + .map_err(|e| Error::Msg(format!("Ping send failed {e}")))?; } } } diff --git a/src/ws/trades.rs b/src/ws/trades.rs index ce63975..8ad650f 100644 --- a/src/ws/trades.rs +++ b/src/ws/trades.rs @@ -28,8 +28,9 @@ fn str_as_f32_as_str_formatted<'de, D>(deserializer: D) -> Result, { - let s = <&str>::deserialize(deserializer)?; - let f = s.parse::().map_err(de::Error::custom)?; + let f: f32 = <&str>::deserialize(deserializer)? + .parse() + .map_err(de::Error::custom)?; Ok(format!("{f:.2}")) } @@ -38,9 +39,12 @@ fn u64_as_time_formatted<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { - let i = ::deserialize(deserializer)?; - let timestamp = i64::try_from(i).map_err(de::Error::custom)?; + let timestamp: i64 = ::deserialize(deserializer)? + .try_into() + .map_err(de::Error::custom)?; + let dt = chrono::DateTime::from_timestamp(timestamp / 1000, 0).unwrap(); + Ok(dt.format("%H:%M:%S").to_string()) } From 7a7795e04ad7358c6a3cac895cc5eb7c92d84e25 Mon Sep 17 00:00:00 2001 From: Eugene Date: Sat, 4 May 2024 01:00:00 +0400 Subject: [PATCH 5/7] typo --- src/ws/listener.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ws/listener.rs b/src/ws/listener.rs index 0d1ddc8..8718fbd 100644 --- a/src/ws/listener.rs +++ b/src/ws/listener.rs @@ -11,7 +11,7 @@ use tracing::info; use super::{WsEvent, WsHandle, WsMessage}; -const PING_INTEVAL: u64 = 5; +const PING_INTERVAL: u64 = 5; async fn event_loop( ws: WebSockets<'_, WE>, @@ -26,7 +26,7 @@ where let (socket, _) = ws.socket.expect("socket not connected"); let (mut tx, mut rx) = socket.split(); - let mut interval = tokio::time::interval(Duration::from_secs(PING_INTEVAL)); + let mut interval = tokio::time::interval(Duration::from_secs(PING_INTERVAL)); let mut last_pong = Instant::now(); loop { @@ -53,16 +53,16 @@ where } } _ = interval.tick() => { - if last_pong.elapsed().as_secs() > PING_INTEVAL * 2 { + if last_pong.elapsed().as_secs() > PING_INTERVAL * 2 { return Err(Error::Msg( - format!("Did not receive ping in the last {} seconds)", PING_INTEVAL * 2) + format!("Did not receive ping in the last {} seconds)", PING_INTERVAL * 2) )); } let msg = Message::Ping(Vec::new()); // NOTE: unsure if timeout is needed here. This does not time out on internet // disconnect - timeout(Duration::from_secs(PING_INTEVAL), tx.send(msg)) + timeout(Duration::from_secs(PING_INTERVAL), tx.send(msg)) .await .map_err(|e| Error::Msg(format!("Ping send timed out {e}")))? .map_err(|e| Error::Msg(format!("Ping send failed {e}")))?; From 63b5ba09828eeea30a9bb6dad4496c8f0d5f2af9 Mon Sep 17 00:00:00 2001 From: Eugene Date: Sun, 5 May 2024 15:20:58 +0400 Subject: [PATCH 6/7] fix default-features flag --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2dd5fc5..b46db89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ identifier = "io.github.me.dynasty" icon = ["assets/dynasty.icns"] [dependencies] -binance-rs-async = { version = "1.3.3", default_features = false, features = ["rustls-tls", "wallet_api"] } +binance-rs-async = { version = "1.3.3", default-features = false, features = ["rustls-tls", "wallet_api"] } chrono = "0.4.31" iced = { version = "0.12.0", features = ["tokio", "debug", "lazy", "svg", "image", "advanced", "canvas"] } serde = { version = "1.0.197", features = ["derive"] } @@ -33,7 +33,7 @@ lyon_algorithms = "1.0.4" # websocket iced_futures = "0.12.0" -tungstenite = { version = "0.21.0", default_featurs = false } +tungstenite = { version = "0.21.0", default-features = false } [features] default = ["calculator_meval"] From 22d82cc0e93f4d4c42afb714bd6060a65e5d9d87 Mon Sep 17 00:00:00 2001 From: Eugene Date: Sun, 5 May 2024 15:24:32 +0400 Subject: [PATCH 7/7] pin on stack --- src/ws/listener.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ws/listener.rs b/src/ws/listener.rs index 8718fbd..4ca7988 100644 --- a/src/ws/listener.rs +++ b/src/ws/listener.rs @@ -47,7 +47,7 @@ where } Message::Pong(_) => last_pong = Instant::now(), Message::Close(e) => { - return Err(Error::Msg(format!("Disconnected {e:?}"))); + return Err(Error::Msg(format!("Disconnected: {e:?}"))); } Message::Binary(_) | Message::Frame(_) => {} } @@ -64,8 +64,8 @@ where // disconnect timeout(Duration::from_secs(PING_INTERVAL), tx.send(msg)) .await - .map_err(|e| Error::Msg(format!("Ping send timed out {e}")))? - .map_err(|e| Error::Msg(format!("Ping send failed {e}")))?; + .map_err(|e| Error::Msg(format!("Ping send timed out: {e}")))? + .map_err(|e| Error::Msg(format!("Ping send failed: {e}")))?; } } } @@ -131,7 +131,8 @@ pub(crate) trait WsListener { let connected = self.message(WsEvent::Connected); let _ = output.send(connected).await; - let mut ws_loop = Box::pin(event_loop(web_socket, &mut tx)); + let ws_loop = event_loop(web_socket, &mut tx); + tokio::pin!(ws_loop); loop { tokio::select! {