From 75dfbce88c20dd250bd8fbc4771a08ddf4c38167 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Fri, 24 Jan 2020 16:02:21 +0300 Subject: [PATCH 001/224] Migrate server to Tonic, 'medea-control-api-proto' building, convertations --- Cargo.lock | 456 +- Cargo.toml | 1 + proto/control-api/Cargo.toml | 9 +- proto/control-api/build.rs | 18 +- proto/control-api/src/grpc/api.rs | 4020 ----------------- proto/control-api/src/grpc/api_grpc.rs | 127 - proto/control-api/src/grpc/callback.rs | 902 ---- proto/control-api/src/grpc/callback_grpc.rs | 71 - proto/control-api/src/grpc/medea.rs | 241 + proto/control-api/src/grpc/medea_callback.rs | 54 + proto/control-api/src/grpc/mod.rs | 6 +- src/api/control/callback/clients/grpc.rs | 14 +- src/api/control/callback/mod.rs | 6 +- src/api/control/endpoints/mod.rs | 16 +- .../control/endpoints/webrtc_play_endpoint.rs | 2 +- .../endpoints/webrtc_publish_endpoint.rs | 4 +- src/api/control/error_codes.rs | 2 +- src/api/control/grpc/server.rs | 177 +- src/api/control/member.rs | 6 +- src/api/control/room.rs | 4 +- src/signalling/elements/endpoints/mod.rs | 2 +- .../endpoints/webrtc/play_endpoint.rs | 4 +- .../endpoints/webrtc/publish_endpoint.rs | 4 +- src/signalling/elements/member.rs | 4 +- src/signalling/room.rs | 2 +- src/signalling/room_service.rs | 2 +- 26 files changed, 835 insertions(+), 5319 deletions(-) delete mode 100644 proto/control-api/src/grpc/api.rs delete mode 100644 proto/control-api/src/grpc/api_grpc.rs delete mode 100644 proto/control-api/src/grpc/callback.rs delete mode 100644 proto/control-api/src/grpc/callback_grpc.rs create mode 100644 proto/control-api/src/grpc/medea.rs create mode 100644 proto/control-api/src/grpc/medea_callback.rs diff --git a/Cargo.lock b/Cargo.lock index f8e1148d4..afaa81162 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -642,6 +642,25 @@ name = "ascii" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "async-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "async-stream-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "async-stream-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "async-trait" version = "0.1.22" @@ -1248,6 +1267,11 @@ dependencies = [ "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fixedbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "flate2" version = "1.0.13" @@ -1420,15 +1444,6 @@ dependencies = [ "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "grpcio-compiler" -version = "0.5.0-alpha.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "grpcio-sys" version = "0.4.7" @@ -1534,6 +1549,15 @@ dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "http-body" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "httparse" version = "1.3.4" @@ -1556,6 +1580,29 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hyper" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1608,6 +1655,14 @@ dependencies = [ "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itertools" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.4" @@ -1768,6 +1823,7 @@ dependencies = [ "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1807,10 +1863,9 @@ dependencies = [ name = "medea-control-api-proto" version = "0.1.0-dev" dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protoc-grpcio 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tonic-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1978,6 +2033,11 @@ dependencies = [ "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "multimap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "net2" version = "0.2.33" @@ -2132,6 +2192,15 @@ name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "petgraph" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pin-project" version = "0.4.7" @@ -2228,39 +2297,57 @@ dependencies = [ ] [[package]] -name = "protobuf" -version = "2.10.1" +name = "prost" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "protobuf-codegen" -version = "2.10.1" +name = "prost-build" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "multimap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "protoc" -version = "2.10.1" +name = "prost-derive" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "protoc-grpcio" -version = "1.1.0" +name = "prost-types" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio-compiler 0.5.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf-codegen 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "protoc 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "protobuf" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quick-error" version = "1.2.3" @@ -2331,6 +2418,7 @@ dependencies = [ "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2428,6 +2516,14 @@ dependencies = [ "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_xorshift" version = "0.1.1" @@ -3114,6 +3210,209 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tonic" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-balance 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-make 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-futures 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tonic-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-buffer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-limit 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-load-shed 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-retry 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-timeout 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-util 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-balance" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-make 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-ready-cache 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-buffer" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-discover" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-layer" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "tower-limit" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-load" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-load-shed" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-make" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-ready-cache" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-retry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-service" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "tower-timeout" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tower-util" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tracerr" version = "0.1.1" @@ -3122,6 +3421,43 @@ dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tracing" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tracing-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tracing-futures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "treeline" version = "0.1.0" @@ -3206,6 +3542,11 @@ dependencies = [ "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "try-lock" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-bidi" version = "0.3.4" @@ -3285,6 +3626,15 @@ name = "void" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -3420,6 +3770,14 @@ dependencies = [ "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "which" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "widestring" version = "0.4.0" @@ -3532,6 +3890,8 @@ dependencies = [ "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" "checksum ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" +"checksum async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58982858be7540a465c790b95aaea6710e5139bf8956b1d1344d014fa40100b0" +"checksum async-stream-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393356ed99aa7bff0ac486dde592633b83ab02bd254d8c209d5b9f1d0f533480" "checksum async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c" "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" @@ -3598,6 +3958,7 @@ dependencies = [ "checksum enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "900a6c7fbe523f4c2884eaf26b57b81bb69b6810a01a236390a7ac021d09492e" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" +"checksum fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" "checksum float-cmp 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75224bec9bfe1a65e2d34132933f2de7fe79900c96a0174307554244ece8150e" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" @@ -3619,7 +3980,6 @@ dependencies = [ "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9ac757a85603e4f8c40a9f94be06a5ad412acab80b39b4e8895ca931b6619910" -"checksum grpcio-compiler 0.5.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3c8c6f6d181ac240958853a3b95a4eac9b23816a0a922b9d30b991142938b9ff" "checksum grpcio-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "7b2f22fb0327f153acccedbe91894dd0fb15bb6f202d8195665cd206af0402b0" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" @@ -3630,15 +3990,18 @@ dependencies = [ "checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" "checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" "checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" +"checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" "checksum humantime-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f59e8a805c18bc9ded3f4e596cb5f0157d88a235e875480a7593b5926f95065" +"checksum hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf49cfb32edee45d890537d9057d1b02ed55f53b7b6a30bae83a38c9231749e" "checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f" +"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" @@ -3668,6 +4031,7 @@ dependencies = [ "checksum mockall 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b95a7e7cfbce0e99ebbf5356a085d3b5e320a7ef300f77cd50a7148aa362e7c2" "checksum mockall_derive 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a26211f315c132a546ed185f3a17f7617a8e58d8511025d5f8665017194cf8be" "checksum mockall_derive 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5a615a1ad92048ad5d9633251edb7492b8abc057d7a679a9898476aef173935" +"checksum multimap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a97fbd5d00e0e37bfb10f433af8f5aaf631e739368dc9fc28286ca81ca4948dc" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" @@ -3685,6 +4049,7 @@ dependencies = [ "checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +"checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" "checksum pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "75fca1c4ff21f60ca2d37b80d72b63dab823a9d19d3cda3a81d18bc03f0ba8c5" "checksum pin-project-internal 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6544cd4e4ecace61075a6ec78074beeef98d58aa9a3d07d053d993b2946a90d6" "checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" @@ -3698,10 +4063,11 @@ dependencies = [ "checksum proc-macro-nested 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "369a6ed065f249a159e06c45752c780bda2fb53c995718f9e484d08daa9eb42e" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +"checksum prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce49aefe0a6144a45de32927c77bd2859a5f7677b55f220ae5b744e87389c212" +"checksum prost-build 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "02b10678c913ecbd69350e8535c3aef91a8676c0773fc1d7b95cdd196d7f2f26" +"checksum prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" +"checksum prost-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1834f67c0697c001304b75be76f67add9c89742eda3a085ad8ee0bb38c3417aa" "checksum protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6686ddd96a8dbe2687b5f2a687b2cfb520854010ec480f2d74c32e7c9873d3c5" -"checksum protobuf-codegen 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6456421eecf7fc72905868cd760c3e35848ded3552e480cfe67726ed4dbd8d23" -"checksum protoc 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd83d2547a9e2c8bc6016607281b3ec7ef4871c55be6930915481d80350ab88" -"checksum protoc-grpcio 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e7bb9b76be44d96453f528030c03713f57fa725565036cc9d72037ad75babadf" "checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" @@ -3720,6 +4086,7 @@ dependencies = [ "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +"checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d69c054daeca01bc1bee4af75b04dffa3458d6702cb7a74c2f38518c130fb624" @@ -3795,12 +4162,33 @@ dependencies = [ "checksum tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" "checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +"checksum tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08283643b1d483eb7f3fc77069e63b5cba3e4db93514b3d45470e67f123e4e48" +"checksum tonic-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0436413ba71545bcc6c2b9a0f9d78d72deb0123c6a75ccdfe7c056f9930f5e52" +"checksum tower 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd3169017c090b7a28fce80abaad0ab4f5566423677c9331bb320af7e49cfe62" +"checksum tower-balance 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a792277613b7052448851efcf98a2c433e6f1d01460832dc60bef676bc275d4c" +"checksum tower-buffer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c4887dc2a65d464c8b9b66e0e4d51c2fd6cf5b3373afc72805b0a60bce00446a" +"checksum tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6b5000c3c54d269cc695dff28136bb33d08cbf1df2c48129e143ab65bf3c2a" +"checksum tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a35d656f2638b288b33495d1053ea74c40dc05ec0b92084dd71ca5566c4ed1dc" +"checksum tower-limit 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a4030a1dc1ab99ec6fc9475fc18c62f6cc4da035d370fcbd22fe342f9dd16cd" +"checksum tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8cc79fc3afd07492b7966d7efa7c6c50f8ed58d768a6075dd7ae6591c5d2017b" +"checksum tower-load-shed 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f021e23900173dc315feb4b6922510dae3e79c689b74c089112066c11f0ae4e" +"checksum tower-make 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce50370d644a0364bf4877ffd4f76404156a248d104e2cc234cd391ea5cdc965" +"checksum tower-ready-cache 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b2183d0a00b68a41c0af9e281cf51f40c7de2e1d4af4a43f92a5c35bbe7728d7" +"checksum tower-retry 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e6727956aaa2f8957d4d9232b308fe8e4e65d99db30f42b225646e86c9b6a952" +"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" +"checksum tower-timeout 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "127b8924b357be938823eaaec0608c482d40add25609481027b96198b2e4b31e" +"checksum tower-util 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5702d7890e35b2aae6ee420e8a762547505dbed30c075fbc84ec069a0aa18314" "checksum tracerr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64ee75bed80b548ecaede0ed297636fa16e05d7407aefdc64cb214ad3b8ebd53" +"checksum tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e213bd24252abeb86a0b7060e02df677d367ce6cb772cef17e9214b8390a8d3" +"checksum tracing-attributes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04cfd395def5a60236e187e1ff905cb55668a59f29928dec05e6e1b1fd2ac1f3" +"checksum tracing-core 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "13a46f11e372b8bd4b4398ea54353412fdd7fd42a8370c7e543e218cf7661978" +"checksum tracing-futures 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33848db47a7c848ab48b66aab3293cb9c61ea879a3586ecfcd17302fcea0baf1" "checksum treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" "checksum trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2a7f3a2ab8a919f5eca52a468866a67ed7d3efa265d48a652a9a3452272b413f" "checksum trust-dns-proto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5559ebdf6c2368ddd11e20b11d6bbaf9e46deb803acd7815e93f5a7b4a6d2901" "checksum trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c9992e58dba365798803c0b91018ff6c8d3fc77e06977c4539af2a6bfe0a039" "checksum trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6f90b1502b226f8b2514c6d5b37bafa8c200d7ca4102d57dc36ee0f3b7a04a2f" +"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" @@ -3813,6 +4201,7 @@ dependencies = [ "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" "checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" "checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" @@ -3826,6 +4215,7 @@ dependencies = [ "checksum web-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf97caf6aa8c2b1dac90faf0db529d9d63c93846cca4911856f78a83cebf53b" "checksum wee_alloc 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" +"checksum which 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8" "checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" diff --git a/Cargo.toml b/Cargo.toml index ac67ac4d8..c75584d66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ slog-scope = "4.1" slog-stdlog = "4.0" smart-default = "0.6" tokio = { version = "0.2", features = ["signal", "time"] } +tonic = "0.1" toml = "0.5" url = "2.1" [dependencies.slog] diff --git a/proto/control-api/Cargo.toml b/proto/control-api/Cargo.toml index 306c6a787..20ea026b5 100644 --- a/proto/control-api/Cargo.toml +++ b/proto/control-api/Cargo.toml @@ -14,12 +14,11 @@ categories = ["api-bindings", "network-programming"] [features] default = ["grpc"] -grpc = ["futures", "grpcio", "protobuf", "protoc-grpcio"] +grpc = ["prost", "tonic-build", "tonic"] [dependencies] -futures = { version = "0.1", optional = true } -grpcio = { version = "0.4", optional = true } -protobuf = { version = "2.8", optional = true } +prost = { version = "0.6", optional = true } +tonic = { version = "0.1", optional = true } [build-dependencies] -protoc-grpcio = { version = "1.1", optional = true } +tonic-build = { version = "0.1", optional = true} diff --git a/proto/control-api/build.rs b/proto/control-api/build.rs index e3a4ead07..e3bba248c 100644 --- a/proto/control-api/build.rs +++ b/proto/control-api/build.rs @@ -39,12 +39,18 @@ mod grpc { for filename in &out_files { if let Err(e) = fs::File::open(filename) { if let io::ErrorKind::NotFound = e.kind() { - protoc_grpcio::compile_grpc_protos( - &grpc_spec_files, - &[GRPC_DIR], - &GRPC_DIR, - None, - )?; + tonic_build::configure() + .out_dir(GRPC_DIR) + .format(false) + .build_client(true) + .build_server(true) + .compile(&grpc_spec_files, &[GRPC_DIR.to_string()])?; +// protoc_grpcio::compile_grpc_protos( +// &grpc_spec_files, +// &[GRPC_DIR], +// &GRPC_DIR, +// None, +// )?; break; } else { panic!("{}", e); diff --git a/proto/control-api/src/grpc/api.rs b/proto/control-api/src/grpc/api.rs deleted file mode 100644 index 65d84ceb8..000000000 --- a/proto/control-api/src/grpc/api.rs +++ /dev/null @@ -1,4020 +0,0 @@ -// This file is generated by rust-protobuf 2.10.1. Do not edit -// @generated - -// https://github.com/rust-lang/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![cfg_attr(rustfmt, rustfmt_skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unsafe_code)] -#![allow(unused_imports)] -#![allow(unused_results)] -//! Generated file from `api.proto` - -use protobuf::Message as Message_imported_for_functions; -use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions; - -/// Generated files are compatible only with the same version -/// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_10_1; - -#[derive(PartialEq,Clone,Default)] -pub struct CreateRequest { - // message fields - pub parent_fid: ::std::string::String, - // message oneof groups - pub el: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CreateRequest { - fn default() -> &'a CreateRequest { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum CreateRequest_oneof_el { - member(Member), - room(Room), - webrtc_play(WebRtcPlayEndpoint), - webrtc_pub(WebRtcPublishEndpoint), -} - -impl CreateRequest { - pub fn new() -> CreateRequest { - ::std::default::Default::default() - } - - // string parent_fid = 1; - - - pub fn get_parent_fid(&self) -> &str { - &self.parent_fid - } - pub fn clear_parent_fid(&mut self) { - self.parent_fid.clear(); - } - - // Param is passed by value, moved - pub fn set_parent_fid(&mut self, v: ::std::string::String) { - self.parent_fid = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_parent_fid(&mut self) -> &mut ::std::string::String { - &mut self.parent_fid - } - - // Take field - pub fn take_parent_fid(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.parent_fid, ::std::string::String::new()) - } - - // .medea.Member member = 2; - - - pub fn get_member(&self) -> &Member { - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::member(ref v)) => v, - _ => Member::default_instance(), - } - } - pub fn clear_member(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_member(&self) -> bool { - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::member(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_member(&mut self, v: Member) { - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::member(v)) - } - - // Mutable pointer to the field. - pub fn mut_member(&mut self) -> &mut Member { - if let ::std::option::Option::Some(CreateRequest_oneof_el::member(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::member(Member::new())); - } - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::member(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_member(&mut self) -> Member { - if self.has_member() { - match self.el.take() { - ::std::option::Option::Some(CreateRequest_oneof_el::member(v)) => v, - _ => panic!(), - } - } else { - Member::new() - } - } - - // .medea.Room room = 3; - - - pub fn get_room(&self) -> &Room { - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::room(ref v)) => v, - _ => Room::default_instance(), - } - } - pub fn clear_room(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_room(&self) -> bool { - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::room(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_room(&mut self, v: Room) { - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::room(v)) - } - - // Mutable pointer to the field. - pub fn mut_room(&mut self) -> &mut Room { - if let ::std::option::Option::Some(CreateRequest_oneof_el::room(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::room(Room::new())); - } - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::room(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_room(&mut self) -> Room { - if self.has_room() { - match self.el.take() { - ::std::option::Option::Some(CreateRequest_oneof_el::room(v)) => v, - _ => panic!(), - } - } else { - Room::new() - } - } - - // .medea.WebRtcPlayEndpoint webrtc_play = 4; - - - pub fn get_webrtc_play(&self) -> &WebRtcPlayEndpoint { - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_play(ref v)) => v, - _ => WebRtcPlayEndpoint::default_instance(), - } - } - pub fn clear_webrtc_play(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_webrtc_play(&self) -> bool { - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_play(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_webrtc_play(&mut self, v: WebRtcPlayEndpoint) { - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_play(v)) - } - - // Mutable pointer to the field. - pub fn mut_webrtc_play(&mut self) -> &mut WebRtcPlayEndpoint { - if let ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_play(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_play(WebRtcPlayEndpoint::new())); - } - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_play(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_webrtc_play(&mut self) -> WebRtcPlayEndpoint { - if self.has_webrtc_play() { - match self.el.take() { - ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_play(v)) => v, - _ => panic!(), - } - } else { - WebRtcPlayEndpoint::new() - } - } - - // .medea.WebRtcPublishEndpoint webrtc_pub = 5; - - - pub fn get_webrtc_pub(&self) -> &WebRtcPublishEndpoint { - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_pub(ref v)) => v, - _ => WebRtcPublishEndpoint::default_instance(), - } - } - pub fn clear_webrtc_pub(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_webrtc_pub(&self) -> bool { - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_pub(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_webrtc_pub(&mut self, v: WebRtcPublishEndpoint) { - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_pub(v)) - } - - // Mutable pointer to the field. - pub fn mut_webrtc_pub(&mut self) -> &mut WebRtcPublishEndpoint { - if let ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_pub(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_pub(WebRtcPublishEndpoint::new())); - } - match self.el { - ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_pub(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_webrtc_pub(&mut self) -> WebRtcPublishEndpoint { - if self.has_webrtc_pub() { - match self.el.take() { - ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_pub(v)) => v, - _ => panic!(), - } - } else { - WebRtcPublishEndpoint::new() - } - } -} - -impl ::protobuf::Message for CreateRequest { - fn is_initialized(&self) -> bool { - if let Some(CreateRequest_oneof_el::member(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - if let Some(CreateRequest_oneof_el::room(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - if let Some(CreateRequest_oneof_el::webrtc_play(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - if let Some(CreateRequest_oneof_el::webrtc_pub(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.parent_fid)?; - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::member(is.read_message()?)); - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::room(is.read_message()?)); - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_play(is.read_message()?)); - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(CreateRequest_oneof_el::webrtc_pub(is.read_message()?)); - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.parent_fid.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.parent_fid); - } - if let ::std::option::Option::Some(ref v) = self.el { - match v { - &CreateRequest_oneof_el::member(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &CreateRequest_oneof_el::room(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &CreateRequest_oneof_el::webrtc_play(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &CreateRequest_oneof_el::webrtc_pub(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.parent_fid.is_empty() { - os.write_string(1, &self.parent_fid)?; - } - if let ::std::option::Option::Some(ref v) = self.el { - match v { - &CreateRequest_oneof_el::member(ref v) => { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &CreateRequest_oneof_el::room(ref v) => { - os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &CreateRequest_oneof_el::webrtc_play(ref v) => { - os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &CreateRequest_oneof_el::webrtc_pub(ref v) => { - os.write_tag(5, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> CreateRequest { - CreateRequest::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "parent_fid", - |m: &CreateRequest| { &m.parent_fid }, - |m: &mut CreateRequest| { &mut m.parent_fid }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, Member>( - "member", - CreateRequest::has_member, - CreateRequest::get_member, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, Room>( - "room", - CreateRequest::has_room, - CreateRequest::get_room, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, WebRtcPlayEndpoint>( - "webrtc_play", - CreateRequest::has_webrtc_play, - CreateRequest::get_webrtc_play, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, WebRtcPublishEndpoint>( - "webrtc_pub", - CreateRequest::has_webrtc_pub, - CreateRequest::get_webrtc_pub, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "CreateRequest", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static CreateRequest { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const CreateRequest, - }; - unsafe { - instance.get(CreateRequest::new) - } - } -} - -impl ::protobuf::Clear for CreateRequest { - fn clear(&mut self) { - self.parent_fid.clear(); - self.el = ::std::option::Option::None; - self.el = ::std::option::Option::None; - self.el = ::std::option::Option::None; - self.el = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CreateRequest { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CreateRequest { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct IdRequest { - // message fields - pub fid: ::protobuf::RepeatedField<::std::string::String>, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a IdRequest { - fn default() -> &'a IdRequest { - ::default_instance() - } -} - -impl IdRequest { - pub fn new() -> IdRequest { - ::std::default::Default::default() - } - - // repeated string fid = 1; - - - pub fn get_fid(&self) -> &[::std::string::String] { - &self.fid - } - pub fn clear_fid(&mut self) { - self.fid.clear(); - } - - // Param is passed by value, moved - pub fn set_fid(&mut self, v: ::protobuf::RepeatedField<::std::string::String>) { - self.fid = v; - } - - // Mutable pointer to the field. - pub fn mut_fid(&mut self) -> &mut ::protobuf::RepeatedField<::std::string::String> { - &mut self.fid - } - - // Take field - pub fn take_fid(&mut self) -> ::protobuf::RepeatedField<::std::string::String> { - ::std::mem::replace(&mut self.fid, ::protobuf::RepeatedField::new()) - } -} - -impl ::protobuf::Message for IdRequest { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_repeated_string_into(wire_type, is, &mut self.fid)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - for value in &self.fid { - my_size += ::protobuf::rt::string_size(1, &value); - }; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - for v in &self.fid { - os.write_string(1, &v)?; - }; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> IdRequest { - IdRequest::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_repeated_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "fid", - |m: &IdRequest| { &m.fid }, - |m: &mut IdRequest| { &mut m.fid }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "IdRequest", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static IdRequest { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const IdRequest, - }; - unsafe { - instance.get(IdRequest::new) - } - } -} - -impl ::protobuf::Clear for IdRequest { - fn clear(&mut self) { - self.fid.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for IdRequest { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for IdRequest { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Response { - // message fields - pub error: ::protobuf::SingularPtrField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Response { - fn default() -> &'a Response { - ::default_instance() - } -} - -impl Response { - pub fn new() -> Response { - ::std::default::Default::default() - } - - // .medea.Error error = 1; - - - pub fn get_error(&self) -> &Error { - self.error.as_ref().unwrap_or_else(|| Error::default_instance()) - } - pub fn clear_error(&mut self) { - self.error.clear(); - } - - pub fn has_error(&self) -> bool { - self.error.is_some() - } - - // Param is passed by value, moved - pub fn set_error(&mut self, v: Error) { - self.error = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_error(&mut self) -> &mut Error { - if self.error.is_none() { - self.error.set_default(); - } - self.error.as_mut().unwrap() - } - - // Take field - pub fn take_error(&mut self) -> Error { - self.error.take().unwrap_or_else(|| Error::new()) - } -} - -impl ::protobuf::Message for Response { - fn is_initialized(&self) -> bool { - for v in &self.error { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.error)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if let Some(ref v) = self.error.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if let Some(ref v) = self.error.as_ref() { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Response { - Response::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "error", - |m: &Response| { &m.error }, - |m: &mut Response| { &mut m.error }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "Response", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static Response { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const Response, - }; - unsafe { - instance.get(Response::new) - } - } -} - -impl ::protobuf::Clear for Response { - fn clear(&mut self) { - self.error.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Response { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Response { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct CreateResponse { - // message fields - pub sid: ::std::collections::HashMap<::std::string::String, ::std::string::String>, - pub error: ::protobuf::SingularPtrField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a CreateResponse { - fn default() -> &'a CreateResponse { - ::default_instance() - } -} - -impl CreateResponse { - pub fn new() -> CreateResponse { - ::std::default::Default::default() - } - - // repeated .medea.CreateResponse.SidEntry sid = 1; - - - pub fn get_sid(&self) -> &::std::collections::HashMap<::std::string::String, ::std::string::String> { - &self.sid - } - pub fn clear_sid(&mut self) { - self.sid.clear(); - } - - // Param is passed by value, moved - pub fn set_sid(&mut self, v: ::std::collections::HashMap<::std::string::String, ::std::string::String>) { - self.sid = v; - } - - // Mutable pointer to the field. - pub fn mut_sid(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, ::std::string::String> { - &mut self.sid - } - - // Take field - pub fn take_sid(&mut self) -> ::std::collections::HashMap<::std::string::String, ::std::string::String> { - ::std::mem::replace(&mut self.sid, ::std::collections::HashMap::new()) - } - - // .medea.Error error = 2; - - - pub fn get_error(&self) -> &Error { - self.error.as_ref().unwrap_or_else(|| Error::default_instance()) - } - pub fn clear_error(&mut self) { - self.error.clear(); - } - - pub fn has_error(&self) -> bool { - self.error.is_some() - } - - // Param is passed by value, moved - pub fn set_error(&mut self, v: Error) { - self.error = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_error(&mut self) -> &mut Error { - if self.error.is_none() { - self.error.set_default(); - } - self.error.as_mut().unwrap() - } - - // Take field - pub fn take_error(&mut self) -> Error { - self.error.take().unwrap_or_else(|| Error::new()) - } -} - -impl ::protobuf::Message for CreateResponse { - fn is_initialized(&self) -> bool { - for v in &self.error { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(wire_type, is, &mut self.sid)?; - }, - 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.error)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(1, &self.sid); - if let Some(ref v) = self.error.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>(1, &self.sid, os)?; - if let Some(ref v) = self.error.as_ref() { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> CreateResponse { - CreateResponse::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeString>( - "sid", - |m: &CreateResponse| { &m.sid }, - |m: &mut CreateResponse| { &mut m.sid }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "error", - |m: &CreateResponse| { &m.error }, - |m: &mut CreateResponse| { &mut m.error }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "CreateResponse", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static CreateResponse { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const CreateResponse, - }; - unsafe { - instance.get(CreateResponse::new) - } - } -} - -impl ::protobuf::Clear for CreateResponse { - fn clear(&mut self) { - self.sid.clear(); - self.error.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for CreateResponse { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for CreateResponse { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct GetResponse { - // message fields - pub elements: ::std::collections::HashMap<::std::string::String, Element>, - pub error: ::protobuf::SingularPtrField, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a GetResponse { - fn default() -> &'a GetResponse { - ::default_instance() - } -} - -impl GetResponse { - pub fn new() -> GetResponse { - ::std::default::Default::default() - } - - // repeated .medea.GetResponse.ElementsEntry elements = 1; - - - pub fn get_elements(&self) -> &::std::collections::HashMap<::std::string::String, Element> { - &self.elements - } - pub fn clear_elements(&mut self) { - self.elements.clear(); - } - - // Param is passed by value, moved - pub fn set_elements(&mut self, v: ::std::collections::HashMap<::std::string::String, Element>) { - self.elements = v; - } - - // Mutable pointer to the field. - pub fn mut_elements(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, Element> { - &mut self.elements - } - - // Take field - pub fn take_elements(&mut self) -> ::std::collections::HashMap<::std::string::String, Element> { - ::std::mem::replace(&mut self.elements, ::std::collections::HashMap::new()) - } - - // .medea.Error error = 2; - - - pub fn get_error(&self) -> &Error { - self.error.as_ref().unwrap_or_else(|| Error::default_instance()) - } - pub fn clear_error(&mut self) { - self.error.clear(); - } - - pub fn has_error(&self) -> bool { - self.error.is_some() - } - - // Param is passed by value, moved - pub fn set_error(&mut self, v: Error) { - self.error = ::protobuf::SingularPtrField::some(v); - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_error(&mut self) -> &mut Error { - if self.error.is_none() { - self.error.set_default(); - } - self.error.as_mut().unwrap() - } - - // Take field - pub fn take_error(&mut self) -> Error { - self.error.take().unwrap_or_else(|| Error::new()) - } -} - -impl ::protobuf::Message for GetResponse { - fn is_initialized(&self) -> bool { - for v in &self.error { - if !v.is_initialized() { - return false; - } - }; - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.elements)?; - }, - 2 => { - ::protobuf::rt::read_singular_message_into(wire_type, is, &mut self.error)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(1, &self.elements); - if let Some(ref v) = self.error.as_ref() { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(1, &self.elements, os)?; - if let Some(ref v) = self.error.as_ref() { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> GetResponse { - GetResponse::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( - "elements", - |m: &GetResponse| { &m.elements }, - |m: &mut GetResponse| { &mut m.elements }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_ptr_field_accessor::<_, ::protobuf::types::ProtobufTypeMessage>( - "error", - |m: &GetResponse| { &m.error }, - |m: &mut GetResponse| { &mut m.error }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "GetResponse", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static GetResponse { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const GetResponse, - }; - unsafe { - instance.get(GetResponse::new) - } - } -} - -impl ::protobuf::Clear for GetResponse { - fn clear(&mut self) { - self.elements.clear(); - self.error.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for GetResponse { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for GetResponse { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Error { - // message fields - pub code: u32, - pub text: ::std::string::String, - pub doc: ::std::string::String, - pub element: ::std::string::String, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Error { - fn default() -> &'a Error { - ::default_instance() - } -} - -impl Error { - pub fn new() -> Error { - ::std::default::Default::default() - } - - // uint32 code = 1; - - - pub fn get_code(&self) -> u32 { - self.code - } - pub fn clear_code(&mut self) { - self.code = 0; - } - - // Param is passed by value, moved - pub fn set_code(&mut self, v: u32) { - self.code = v; - } - - // string text = 2; - - - pub fn get_text(&self) -> &str { - &self.text - } - pub fn clear_text(&mut self) { - self.text.clear(); - } - - // Param is passed by value, moved - pub fn set_text(&mut self, v: ::std::string::String) { - self.text = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_text(&mut self) -> &mut ::std::string::String { - &mut self.text - } - - // Take field - pub fn take_text(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.text, ::std::string::String::new()) - } - - // string doc = 3; - - - pub fn get_doc(&self) -> &str { - &self.doc - } - pub fn clear_doc(&mut self) { - self.doc.clear(); - } - - // Param is passed by value, moved - pub fn set_doc(&mut self, v: ::std::string::String) { - self.doc = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_doc(&mut self) -> &mut ::std::string::String { - &mut self.doc - } - - // Take field - pub fn take_doc(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.doc, ::std::string::String::new()) - } - - // string element = 4; - - - pub fn get_element(&self) -> &str { - &self.element - } - pub fn clear_element(&mut self) { - self.element.clear(); - } - - // Param is passed by value, moved - pub fn set_element(&mut self, v: ::std::string::String) { - self.element = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_element(&mut self) -> &mut ::std::string::String { - &mut self.element - } - - // Take field - pub fn take_element(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.element, ::std::string::String::new()) - } -} - -impl ::protobuf::Message for Error { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_uint32()?; - self.code = tmp; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.text)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.doc)?; - }, - 4 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.element)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.code != 0 { - my_size += ::protobuf::rt::value_size(1, self.code, ::protobuf::wire_format::WireTypeVarint); - } - if !self.text.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.text); - } - if !self.doc.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.doc); - } - if !self.element.is_empty() { - my_size += ::protobuf::rt::string_size(4, &self.element); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.code != 0 { - os.write_uint32(1, self.code)?; - } - if !self.text.is_empty() { - os.write_string(2, &self.text)?; - } - if !self.doc.is_empty() { - os.write_string(3, &self.doc)?; - } - if !self.element.is_empty() { - os.write_string(4, &self.element)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Error { - Error::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeUint32>( - "code", - |m: &Error| { &m.code }, - |m: &mut Error| { &mut m.code }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "text", - |m: &Error| { &m.text }, - |m: &mut Error| { &mut m.text }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "doc", - |m: &Error| { &m.doc }, - |m: &mut Error| { &mut m.doc }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "element", - |m: &Error| { &m.element }, - |m: &mut Error| { &mut m.element }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "Error", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static Error { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const Error, - }; - unsafe { - instance.get(Error::new) - } - } -} - -impl ::protobuf::Clear for Error { - fn clear(&mut self) { - self.code = 0; - self.text.clear(); - self.doc.clear(); - self.element.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Error { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Error { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Element { - // message oneof groups - pub el: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Element { - fn default() -> &'a Element { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum Element_oneof_el { - member(Member), - room(Room), - webrtc_play(WebRtcPlayEndpoint), - webrtc_pub(WebRtcPublishEndpoint), -} - -impl Element { - pub fn new() -> Element { - ::std::default::Default::default() - } - - // .medea.Member member = 1; - - - pub fn get_member(&self) -> &Member { - match self.el { - ::std::option::Option::Some(Element_oneof_el::member(ref v)) => v, - _ => Member::default_instance(), - } - } - pub fn clear_member(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_member(&self) -> bool { - match self.el { - ::std::option::Option::Some(Element_oneof_el::member(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_member(&mut self, v: Member) { - self.el = ::std::option::Option::Some(Element_oneof_el::member(v)) - } - - // Mutable pointer to the field. - pub fn mut_member(&mut self) -> &mut Member { - if let ::std::option::Option::Some(Element_oneof_el::member(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(Element_oneof_el::member(Member::new())); - } - match self.el { - ::std::option::Option::Some(Element_oneof_el::member(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_member(&mut self) -> Member { - if self.has_member() { - match self.el.take() { - ::std::option::Option::Some(Element_oneof_el::member(v)) => v, - _ => panic!(), - } - } else { - Member::new() - } - } - - // .medea.Room room = 2; - - - pub fn get_room(&self) -> &Room { - match self.el { - ::std::option::Option::Some(Element_oneof_el::room(ref v)) => v, - _ => Room::default_instance(), - } - } - pub fn clear_room(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_room(&self) -> bool { - match self.el { - ::std::option::Option::Some(Element_oneof_el::room(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_room(&mut self, v: Room) { - self.el = ::std::option::Option::Some(Element_oneof_el::room(v)) - } - - // Mutable pointer to the field. - pub fn mut_room(&mut self) -> &mut Room { - if let ::std::option::Option::Some(Element_oneof_el::room(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(Element_oneof_el::room(Room::new())); - } - match self.el { - ::std::option::Option::Some(Element_oneof_el::room(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_room(&mut self) -> Room { - if self.has_room() { - match self.el.take() { - ::std::option::Option::Some(Element_oneof_el::room(v)) => v, - _ => panic!(), - } - } else { - Room::new() - } - } - - // .medea.WebRtcPlayEndpoint webrtc_play = 3; - - - pub fn get_webrtc_play(&self) -> &WebRtcPlayEndpoint { - match self.el { - ::std::option::Option::Some(Element_oneof_el::webrtc_play(ref v)) => v, - _ => WebRtcPlayEndpoint::default_instance(), - } - } - pub fn clear_webrtc_play(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_webrtc_play(&self) -> bool { - match self.el { - ::std::option::Option::Some(Element_oneof_el::webrtc_play(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_webrtc_play(&mut self, v: WebRtcPlayEndpoint) { - self.el = ::std::option::Option::Some(Element_oneof_el::webrtc_play(v)) - } - - // Mutable pointer to the field. - pub fn mut_webrtc_play(&mut self) -> &mut WebRtcPlayEndpoint { - if let ::std::option::Option::Some(Element_oneof_el::webrtc_play(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(Element_oneof_el::webrtc_play(WebRtcPlayEndpoint::new())); - } - match self.el { - ::std::option::Option::Some(Element_oneof_el::webrtc_play(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_webrtc_play(&mut self) -> WebRtcPlayEndpoint { - if self.has_webrtc_play() { - match self.el.take() { - ::std::option::Option::Some(Element_oneof_el::webrtc_play(v)) => v, - _ => panic!(), - } - } else { - WebRtcPlayEndpoint::new() - } - } - - // .medea.WebRtcPublishEndpoint webrtc_pub = 4; - - - pub fn get_webrtc_pub(&self) -> &WebRtcPublishEndpoint { - match self.el { - ::std::option::Option::Some(Element_oneof_el::webrtc_pub(ref v)) => v, - _ => WebRtcPublishEndpoint::default_instance(), - } - } - pub fn clear_webrtc_pub(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_webrtc_pub(&self) -> bool { - match self.el { - ::std::option::Option::Some(Element_oneof_el::webrtc_pub(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_webrtc_pub(&mut self, v: WebRtcPublishEndpoint) { - self.el = ::std::option::Option::Some(Element_oneof_el::webrtc_pub(v)) - } - - // Mutable pointer to the field. - pub fn mut_webrtc_pub(&mut self) -> &mut WebRtcPublishEndpoint { - if let ::std::option::Option::Some(Element_oneof_el::webrtc_pub(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(Element_oneof_el::webrtc_pub(WebRtcPublishEndpoint::new())); - } - match self.el { - ::std::option::Option::Some(Element_oneof_el::webrtc_pub(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_webrtc_pub(&mut self) -> WebRtcPublishEndpoint { - if self.has_webrtc_pub() { - match self.el.take() { - ::std::option::Option::Some(Element_oneof_el::webrtc_pub(v)) => v, - _ => panic!(), - } - } else { - WebRtcPublishEndpoint::new() - } - } -} - -impl ::protobuf::Message for Element { - fn is_initialized(&self) -> bool { - if let Some(Element_oneof_el::member(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - if let Some(Element_oneof_el::room(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - if let Some(Element_oneof_el::webrtc_play(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - if let Some(Element_oneof_el::webrtc_pub(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(Element_oneof_el::member(is.read_message()?)); - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(Element_oneof_el::room(is.read_message()?)); - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(Element_oneof_el::webrtc_play(is.read_message()?)); - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(Element_oneof_el::webrtc_pub(is.read_message()?)); - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if let ::std::option::Option::Some(ref v) = self.el { - match v { - &Element_oneof_el::member(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &Element_oneof_el::room(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &Element_oneof_el::webrtc_play(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &Element_oneof_el::webrtc_pub(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if let ::std::option::Option::Some(ref v) = self.el { - match v { - &Element_oneof_el::member(ref v) => { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &Element_oneof_el::room(ref v) => { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &Element_oneof_el::webrtc_play(ref v) => { - os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &Element_oneof_el::webrtc_pub(ref v) => { - os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Element { - Element::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, Member>( - "member", - Element::has_member, - Element::get_member, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, Room>( - "room", - Element::has_room, - Element::get_room, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, WebRtcPlayEndpoint>( - "webrtc_play", - Element::has_webrtc_play, - Element::get_webrtc_play, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, WebRtcPublishEndpoint>( - "webrtc_pub", - Element::has_webrtc_pub, - Element::get_webrtc_pub, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "Element", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static Element { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const Element, - }; - unsafe { - instance.get(Element::new) - } - } -} - -impl ::protobuf::Clear for Element { - fn clear(&mut self) { - self.el = ::std::option::Option::None; - self.el = ::std::option::Option::None; - self.el = ::std::option::Option::None; - self.el = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Element { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Element { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Room { - // message fields - pub id: ::std::string::String, - pub pipeline: ::std::collections::HashMap<::std::string::String, Room_Element>, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Room { - fn default() -> &'a Room { - ::default_instance() - } -} - -impl Room { - pub fn new() -> Room { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // repeated .medea.Room.PipelineEntry pipeline = 2; - - - pub fn get_pipeline(&self) -> &::std::collections::HashMap<::std::string::String, Room_Element> { - &self.pipeline - } - pub fn clear_pipeline(&mut self) { - self.pipeline.clear(); - } - - // Param is passed by value, moved - pub fn set_pipeline(&mut self, v: ::std::collections::HashMap<::std::string::String, Room_Element>) { - self.pipeline = v; - } - - // Mutable pointer to the field. - pub fn mut_pipeline(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, Room_Element> { - &mut self.pipeline - } - - // Take field - pub fn take_pipeline(&mut self) -> ::std::collections::HashMap<::std::string::String, Room_Element> { - ::std::mem::replace(&mut self.pipeline, ::std::collections::HashMap::new()) - } -} - -impl ::protobuf::Message for Room { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.pipeline)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(2, &self.pipeline); - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(2, &self.pipeline, os)?; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Room { - Room::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &Room| { &m.id }, - |m: &mut Room| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( - "pipeline", - |m: &Room| { &m.pipeline }, - |m: &mut Room| { &mut m.pipeline }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "Room", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static Room { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const Room, - }; - unsafe { - instance.get(Room::new) - } - } -} - -impl ::protobuf::Clear for Room { - fn clear(&mut self) { - self.id.clear(); - self.pipeline.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Room { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Room { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Room_Element { - // message oneof groups - pub el: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Room_Element { - fn default() -> &'a Room_Element { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum Room_Element_oneof_el { - member(Member), - webrtc_play(WebRtcPlayEndpoint), - webrtc_pub(WebRtcPublishEndpoint), -} - -impl Room_Element { - pub fn new() -> Room_Element { - ::std::default::Default::default() - } - - // .medea.Member member = 1; - - - pub fn get_member(&self) -> &Member { - match self.el { - ::std::option::Option::Some(Room_Element_oneof_el::member(ref v)) => v, - _ => Member::default_instance(), - } - } - pub fn clear_member(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_member(&self) -> bool { - match self.el { - ::std::option::Option::Some(Room_Element_oneof_el::member(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_member(&mut self, v: Member) { - self.el = ::std::option::Option::Some(Room_Element_oneof_el::member(v)) - } - - // Mutable pointer to the field. - pub fn mut_member(&mut self) -> &mut Member { - if let ::std::option::Option::Some(Room_Element_oneof_el::member(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(Room_Element_oneof_el::member(Member::new())); - } - match self.el { - ::std::option::Option::Some(Room_Element_oneof_el::member(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_member(&mut self) -> Member { - if self.has_member() { - match self.el.take() { - ::std::option::Option::Some(Room_Element_oneof_el::member(v)) => v, - _ => panic!(), - } - } else { - Member::new() - } - } - - // .medea.WebRtcPlayEndpoint webrtc_play = 2; - - - pub fn get_webrtc_play(&self) -> &WebRtcPlayEndpoint { - match self.el { - ::std::option::Option::Some(Room_Element_oneof_el::webrtc_play(ref v)) => v, - _ => WebRtcPlayEndpoint::default_instance(), - } - } - pub fn clear_webrtc_play(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_webrtc_play(&self) -> bool { - match self.el { - ::std::option::Option::Some(Room_Element_oneof_el::webrtc_play(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_webrtc_play(&mut self, v: WebRtcPlayEndpoint) { - self.el = ::std::option::Option::Some(Room_Element_oneof_el::webrtc_play(v)) - } - - // Mutable pointer to the field. - pub fn mut_webrtc_play(&mut self) -> &mut WebRtcPlayEndpoint { - if let ::std::option::Option::Some(Room_Element_oneof_el::webrtc_play(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(Room_Element_oneof_el::webrtc_play(WebRtcPlayEndpoint::new())); - } - match self.el { - ::std::option::Option::Some(Room_Element_oneof_el::webrtc_play(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_webrtc_play(&mut self) -> WebRtcPlayEndpoint { - if self.has_webrtc_play() { - match self.el.take() { - ::std::option::Option::Some(Room_Element_oneof_el::webrtc_play(v)) => v, - _ => panic!(), - } - } else { - WebRtcPlayEndpoint::new() - } - } - - // .medea.WebRtcPublishEndpoint webrtc_pub = 3; - - - pub fn get_webrtc_pub(&self) -> &WebRtcPublishEndpoint { - match self.el { - ::std::option::Option::Some(Room_Element_oneof_el::webrtc_pub(ref v)) => v, - _ => WebRtcPublishEndpoint::default_instance(), - } - } - pub fn clear_webrtc_pub(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_webrtc_pub(&self) -> bool { - match self.el { - ::std::option::Option::Some(Room_Element_oneof_el::webrtc_pub(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_webrtc_pub(&mut self, v: WebRtcPublishEndpoint) { - self.el = ::std::option::Option::Some(Room_Element_oneof_el::webrtc_pub(v)) - } - - // Mutable pointer to the field. - pub fn mut_webrtc_pub(&mut self) -> &mut WebRtcPublishEndpoint { - if let ::std::option::Option::Some(Room_Element_oneof_el::webrtc_pub(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(Room_Element_oneof_el::webrtc_pub(WebRtcPublishEndpoint::new())); - } - match self.el { - ::std::option::Option::Some(Room_Element_oneof_el::webrtc_pub(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_webrtc_pub(&mut self) -> WebRtcPublishEndpoint { - if self.has_webrtc_pub() { - match self.el.take() { - ::std::option::Option::Some(Room_Element_oneof_el::webrtc_pub(v)) => v, - _ => panic!(), - } - } else { - WebRtcPublishEndpoint::new() - } - } -} - -impl ::protobuf::Message for Room_Element { - fn is_initialized(&self) -> bool { - if let Some(Room_Element_oneof_el::member(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - if let Some(Room_Element_oneof_el::webrtc_play(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - if let Some(Room_Element_oneof_el::webrtc_pub(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(Room_Element_oneof_el::member(is.read_message()?)); - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(Room_Element_oneof_el::webrtc_play(is.read_message()?)); - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(Room_Element_oneof_el::webrtc_pub(is.read_message()?)); - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if let ::std::option::Option::Some(ref v) = self.el { - match v { - &Room_Element_oneof_el::member(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &Room_Element_oneof_el::webrtc_play(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &Room_Element_oneof_el::webrtc_pub(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if let ::std::option::Option::Some(ref v) = self.el { - match v { - &Room_Element_oneof_el::member(ref v) => { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &Room_Element_oneof_el::webrtc_play(ref v) => { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &Room_Element_oneof_el::webrtc_pub(ref v) => { - os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Room_Element { - Room_Element::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, Member>( - "member", - Room_Element::has_member, - Room_Element::get_member, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, WebRtcPlayEndpoint>( - "webrtc_play", - Room_Element::has_webrtc_play, - Room_Element::get_webrtc_play, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, WebRtcPublishEndpoint>( - "webrtc_pub", - Room_Element::has_webrtc_pub, - Room_Element::get_webrtc_pub, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "Room_Element", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static Room_Element { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const Room_Element, - }; - unsafe { - instance.get(Room_Element::new) - } - } -} - -impl ::protobuf::Clear for Room_Element { - fn clear(&mut self) { - self.el = ::std::option::Option::None; - self.el = ::std::option::Option::None; - self.el = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Room_Element { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Room_Element { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Member { - // message fields - pub id: ::std::string::String, - pub on_join: ::std::string::String, - pub on_leave: ::std::string::String, - pub credentials: ::std::string::String, - pub pipeline: ::std::collections::HashMap<::std::string::String, Member_Element>, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Member { - fn default() -> &'a Member { - ::default_instance() - } -} - -impl Member { - pub fn new() -> Member { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string on_join = 2; - - - pub fn get_on_join(&self) -> &str { - &self.on_join - } - pub fn clear_on_join(&mut self) { - self.on_join.clear(); - } - - // Param is passed by value, moved - pub fn set_on_join(&mut self, v: ::std::string::String) { - self.on_join = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_on_join(&mut self) -> &mut ::std::string::String { - &mut self.on_join - } - - // Take field - pub fn take_on_join(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.on_join, ::std::string::String::new()) - } - - // string on_leave = 3; - - - pub fn get_on_leave(&self) -> &str { - &self.on_leave - } - pub fn clear_on_leave(&mut self) { - self.on_leave.clear(); - } - - // Param is passed by value, moved - pub fn set_on_leave(&mut self, v: ::std::string::String) { - self.on_leave = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_on_leave(&mut self) -> &mut ::std::string::String { - &mut self.on_leave - } - - // Take field - pub fn take_on_leave(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.on_leave, ::std::string::String::new()) - } - - // string credentials = 4; - - - pub fn get_credentials(&self) -> &str { - &self.credentials - } - pub fn clear_credentials(&mut self) { - self.credentials.clear(); - } - - // Param is passed by value, moved - pub fn set_credentials(&mut self, v: ::std::string::String) { - self.credentials = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_credentials(&mut self) -> &mut ::std::string::String { - &mut self.credentials - } - - // Take field - pub fn take_credentials(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.credentials, ::std::string::String::new()) - } - - // repeated .medea.Member.PipelineEntry pipeline = 5; - - - pub fn get_pipeline(&self) -> &::std::collections::HashMap<::std::string::String, Member_Element> { - &self.pipeline - } - pub fn clear_pipeline(&mut self) { - self.pipeline.clear(); - } - - // Param is passed by value, moved - pub fn set_pipeline(&mut self, v: ::std::collections::HashMap<::std::string::String, Member_Element>) { - self.pipeline = v; - } - - // Mutable pointer to the field. - pub fn mut_pipeline(&mut self) -> &mut ::std::collections::HashMap<::std::string::String, Member_Element> { - &mut self.pipeline - } - - // Take field - pub fn take_pipeline(&mut self) -> ::std::collections::HashMap<::std::string::String, Member_Element> { - ::std::mem::replace(&mut self.pipeline, ::std::collections::HashMap::new()) - } -} - -impl ::protobuf::Message for Member { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.on_join)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.on_leave)?; - }, - 4 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.credentials)?; - }, - 5 => { - ::protobuf::rt::read_map_into::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(wire_type, is, &mut self.pipeline)?; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.on_join.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.on_join); - } - if !self.on_leave.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.on_leave); - } - if !self.credentials.is_empty() { - my_size += ::protobuf::rt::string_size(4, &self.credentials); - } - my_size += ::protobuf::rt::compute_map_size::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(5, &self.pipeline); - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.on_join.is_empty() { - os.write_string(2, &self.on_join)?; - } - if !self.on_leave.is_empty() { - os.write_string(3, &self.on_leave)?; - } - if !self.credentials.is_empty() { - os.write_string(4, &self.credentials)?; - } - ::protobuf::rt::write_map_with_cached_sizes::<::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>(5, &self.pipeline, os)?; - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Member { - Member::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &Member| { &m.id }, - |m: &mut Member| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "on_join", - |m: &Member| { &m.on_join }, - |m: &mut Member| { &mut m.on_join }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "on_leave", - |m: &Member| { &m.on_leave }, - |m: &mut Member| { &mut m.on_leave }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "credentials", - |m: &Member| { &m.credentials }, - |m: &mut Member| { &mut m.credentials }, - )); - fields.push(::protobuf::reflect::accessor::make_map_accessor::<_, ::protobuf::types::ProtobufTypeString, ::protobuf::types::ProtobufTypeMessage>( - "pipeline", - |m: &Member| { &m.pipeline }, - |m: &mut Member| { &mut m.pipeline }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "Member", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static Member { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const Member, - }; - unsafe { - instance.get(Member::new) - } - } -} - -impl ::protobuf::Clear for Member { - fn clear(&mut self) { - self.id.clear(); - self.on_join.clear(); - self.on_leave.clear(); - self.credentials.clear(); - self.pipeline.clear(); - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Member { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Member { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Member_Element { - // message oneof groups - pub el: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Member_Element { - fn default() -> &'a Member_Element { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum Member_Element_oneof_el { - webrtc_play(WebRtcPlayEndpoint), - webrtc_pub(WebRtcPublishEndpoint), -} - -impl Member_Element { - pub fn new() -> Member_Element { - ::std::default::Default::default() - } - - // .medea.WebRtcPlayEndpoint webrtc_play = 1; - - - pub fn get_webrtc_play(&self) -> &WebRtcPlayEndpoint { - match self.el { - ::std::option::Option::Some(Member_Element_oneof_el::webrtc_play(ref v)) => v, - _ => WebRtcPlayEndpoint::default_instance(), - } - } - pub fn clear_webrtc_play(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_webrtc_play(&self) -> bool { - match self.el { - ::std::option::Option::Some(Member_Element_oneof_el::webrtc_play(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_webrtc_play(&mut self, v: WebRtcPlayEndpoint) { - self.el = ::std::option::Option::Some(Member_Element_oneof_el::webrtc_play(v)) - } - - // Mutable pointer to the field. - pub fn mut_webrtc_play(&mut self) -> &mut WebRtcPlayEndpoint { - if let ::std::option::Option::Some(Member_Element_oneof_el::webrtc_play(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(Member_Element_oneof_el::webrtc_play(WebRtcPlayEndpoint::new())); - } - match self.el { - ::std::option::Option::Some(Member_Element_oneof_el::webrtc_play(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_webrtc_play(&mut self) -> WebRtcPlayEndpoint { - if self.has_webrtc_play() { - match self.el.take() { - ::std::option::Option::Some(Member_Element_oneof_el::webrtc_play(v)) => v, - _ => panic!(), - } - } else { - WebRtcPlayEndpoint::new() - } - } - - // .medea.WebRtcPublishEndpoint webrtc_pub = 2; - - - pub fn get_webrtc_pub(&self) -> &WebRtcPublishEndpoint { - match self.el { - ::std::option::Option::Some(Member_Element_oneof_el::webrtc_pub(ref v)) => v, - _ => WebRtcPublishEndpoint::default_instance(), - } - } - pub fn clear_webrtc_pub(&mut self) { - self.el = ::std::option::Option::None; - } - - pub fn has_webrtc_pub(&self) -> bool { - match self.el { - ::std::option::Option::Some(Member_Element_oneof_el::webrtc_pub(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_webrtc_pub(&mut self, v: WebRtcPublishEndpoint) { - self.el = ::std::option::Option::Some(Member_Element_oneof_el::webrtc_pub(v)) - } - - // Mutable pointer to the field. - pub fn mut_webrtc_pub(&mut self) -> &mut WebRtcPublishEndpoint { - if let ::std::option::Option::Some(Member_Element_oneof_el::webrtc_pub(_)) = self.el { - } else { - self.el = ::std::option::Option::Some(Member_Element_oneof_el::webrtc_pub(WebRtcPublishEndpoint::new())); - } - match self.el { - ::std::option::Option::Some(Member_Element_oneof_el::webrtc_pub(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_webrtc_pub(&mut self) -> WebRtcPublishEndpoint { - if self.has_webrtc_pub() { - match self.el.take() { - ::std::option::Option::Some(Member_Element_oneof_el::webrtc_pub(v)) => v, - _ => panic!(), - } - } else { - WebRtcPublishEndpoint::new() - } - } -} - -impl ::protobuf::Message for Member_Element { - fn is_initialized(&self) -> bool { - if let Some(Member_Element_oneof_el::webrtc_play(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - if let Some(Member_Element_oneof_el::webrtc_pub(ref v)) = self.el { - if !v.is_initialized() { - return false; - } - } - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(Member_Element_oneof_el::webrtc_play(is.read_message()?)); - }, - 2 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.el = ::std::option::Option::Some(Member_Element_oneof_el::webrtc_pub(is.read_message()?)); - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if let ::std::option::Option::Some(ref v) = self.el { - match v { - &Member_Element_oneof_el::webrtc_play(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &Member_Element_oneof_el::webrtc_pub(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if let ::std::option::Option::Some(ref v) = self.el { - match v { - &Member_Element_oneof_el::webrtc_play(ref v) => { - os.write_tag(1, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &Member_Element_oneof_el::webrtc_pub(ref v) => { - os.write_tag(2, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Member_Element { - Member_Element::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, WebRtcPlayEndpoint>( - "webrtc_play", - Member_Element::has_webrtc_play, - Member_Element::get_webrtc_play, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, WebRtcPublishEndpoint>( - "webrtc_pub", - Member_Element::has_webrtc_pub, - Member_Element::get_webrtc_pub, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "Member_Element", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static Member_Element { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const Member_Element, - }; - unsafe { - instance.get(Member_Element::new) - } - } -} - -impl ::protobuf::Clear for Member_Element { - fn clear(&mut self) { - self.el = ::std::option::Option::None; - self.el = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Member_Element { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Member_Element { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct WebRtcPublishEndpoint { - // message fields - pub id: ::std::string::String, - pub p2p: WebRtcPublishEndpoint_P2P, - pub on_start: ::std::string::String, - pub on_stop: ::std::string::String, - pub force_relay: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a WebRtcPublishEndpoint { - fn default() -> &'a WebRtcPublishEndpoint { - ::default_instance() - } -} - -impl WebRtcPublishEndpoint { - pub fn new() -> WebRtcPublishEndpoint { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // .medea.WebRtcPublishEndpoint.P2P p2p = 2; - - - pub fn get_p2p(&self) -> WebRtcPublishEndpoint_P2P { - self.p2p - } - pub fn clear_p2p(&mut self) { - self.p2p = WebRtcPublishEndpoint_P2P::NEVER; - } - - // Param is passed by value, moved - pub fn set_p2p(&mut self, v: WebRtcPublishEndpoint_P2P) { - self.p2p = v; - } - - // string on_start = 3; - - - pub fn get_on_start(&self) -> &str { - &self.on_start - } - pub fn clear_on_start(&mut self) { - self.on_start.clear(); - } - - // Param is passed by value, moved - pub fn set_on_start(&mut self, v: ::std::string::String) { - self.on_start = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_on_start(&mut self) -> &mut ::std::string::String { - &mut self.on_start - } - - // Take field - pub fn take_on_start(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.on_start, ::std::string::String::new()) - } - - // string on_stop = 4; - - - pub fn get_on_stop(&self) -> &str { - &self.on_stop - } - pub fn clear_on_stop(&mut self) { - self.on_stop.clear(); - } - - // Param is passed by value, moved - pub fn set_on_stop(&mut self, v: ::std::string::String) { - self.on_stop = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_on_stop(&mut self) -> &mut ::std::string::String { - &mut self.on_stop - } - - // Take field - pub fn take_on_stop(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.on_stop, ::std::string::String::new()) - } - - // bool force_relay = 5; - - - pub fn get_force_relay(&self) -> bool { - self.force_relay - } - pub fn clear_force_relay(&mut self) { - self.force_relay = false; - } - - // Param is passed by value, moved - pub fn set_force_relay(&mut self, v: bool) { - self.force_relay = v; - } -} - -impl ::protobuf::Message for WebRtcPublishEndpoint { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.p2p, 2, &mut self.unknown_fields)? - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.on_start)?; - }, - 4 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.on_stop)?; - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.force_relay = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if self.p2p != WebRtcPublishEndpoint_P2P::NEVER { - my_size += ::protobuf::rt::enum_size(2, self.p2p); - } - if !self.on_start.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.on_start); - } - if !self.on_stop.is_empty() { - my_size += ::protobuf::rt::string_size(4, &self.on_stop); - } - if self.force_relay != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if self.p2p != WebRtcPublishEndpoint_P2P::NEVER { - os.write_enum(2, self.p2p.value())?; - } - if !self.on_start.is_empty() { - os.write_string(3, &self.on_start)?; - } - if !self.on_stop.is_empty() { - os.write_string(4, &self.on_stop)?; - } - if self.force_relay != false { - os.write_bool(5, self.force_relay)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> WebRtcPublishEndpoint { - WebRtcPublishEndpoint::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &WebRtcPublishEndpoint| { &m.id }, - |m: &mut WebRtcPublishEndpoint| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "p2p", - |m: &WebRtcPublishEndpoint| { &m.p2p }, - |m: &mut WebRtcPublishEndpoint| { &mut m.p2p }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "on_start", - |m: &WebRtcPublishEndpoint| { &m.on_start }, - |m: &mut WebRtcPublishEndpoint| { &mut m.on_start }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "on_stop", - |m: &WebRtcPublishEndpoint| { &m.on_stop }, - |m: &mut WebRtcPublishEndpoint| { &mut m.on_stop }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "force_relay", - |m: &WebRtcPublishEndpoint| { &m.force_relay }, - |m: &mut WebRtcPublishEndpoint| { &mut m.force_relay }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "WebRtcPublishEndpoint", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static WebRtcPublishEndpoint { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const WebRtcPublishEndpoint, - }; - unsafe { - instance.get(WebRtcPublishEndpoint::new) - } - } -} - -impl ::protobuf::Clear for WebRtcPublishEndpoint { - fn clear(&mut self) { - self.id.clear(); - self.p2p = WebRtcPublishEndpoint_P2P::NEVER; - self.on_start.clear(); - self.on_stop.clear(); - self.force_relay = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for WebRtcPublishEndpoint { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for WebRtcPublishEndpoint { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum WebRtcPublishEndpoint_P2P { - NEVER = 0, - IF_POSSIBLE = 1, - ALWAYS = 2, -} - -impl ::protobuf::ProtobufEnum for WebRtcPublishEndpoint_P2P { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(WebRtcPublishEndpoint_P2P::NEVER), - 1 => ::std::option::Option::Some(WebRtcPublishEndpoint_P2P::IF_POSSIBLE), - 2 => ::std::option::Option::Some(WebRtcPublishEndpoint_P2P::ALWAYS), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [WebRtcPublishEndpoint_P2P] = &[ - WebRtcPublishEndpoint_P2P::NEVER, - WebRtcPublishEndpoint_P2P::IF_POSSIBLE, - WebRtcPublishEndpoint_P2P::ALWAYS, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, - }; - unsafe { - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new("WebRtcPublishEndpoint_P2P", file_descriptor_proto()) - }) - } - } -} - -impl ::std::marker::Copy for WebRtcPublishEndpoint_P2P { -} - -impl ::std::default::Default for WebRtcPublishEndpoint_P2P { - fn default() -> Self { - WebRtcPublishEndpoint_P2P::NEVER - } -} - -impl ::protobuf::reflect::ProtobufValue for WebRtcPublishEndpoint_P2P { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct WebRtcPlayEndpoint { - // message fields - pub id: ::std::string::String, - pub src: ::std::string::String, - pub on_start: ::std::string::String, - pub on_stop: ::std::string::String, - pub force_relay: bool, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a WebRtcPlayEndpoint { - fn default() -> &'a WebRtcPlayEndpoint { - ::default_instance() - } -} - -impl WebRtcPlayEndpoint { - pub fn new() -> WebRtcPlayEndpoint { - ::std::default::Default::default() - } - - // string id = 1; - - - pub fn get_id(&self) -> &str { - &self.id - } - pub fn clear_id(&mut self) { - self.id.clear(); - } - - // Param is passed by value, moved - pub fn set_id(&mut self, v: ::std::string::String) { - self.id = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_id(&mut self) -> &mut ::std::string::String { - &mut self.id - } - - // Take field - pub fn take_id(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.id, ::std::string::String::new()) - } - - // string src = 2; - - - pub fn get_src(&self) -> &str { - &self.src - } - pub fn clear_src(&mut self) { - self.src.clear(); - } - - // Param is passed by value, moved - pub fn set_src(&mut self, v: ::std::string::String) { - self.src = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_src(&mut self) -> &mut ::std::string::String { - &mut self.src - } - - // Take field - pub fn take_src(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.src, ::std::string::String::new()) - } - - // string on_start = 3; - - - pub fn get_on_start(&self) -> &str { - &self.on_start - } - pub fn clear_on_start(&mut self) { - self.on_start.clear(); - } - - // Param is passed by value, moved - pub fn set_on_start(&mut self, v: ::std::string::String) { - self.on_start = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_on_start(&mut self) -> &mut ::std::string::String { - &mut self.on_start - } - - // Take field - pub fn take_on_start(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.on_start, ::std::string::String::new()) - } - - // string on_stop = 4; - - - pub fn get_on_stop(&self) -> &str { - &self.on_stop - } - pub fn clear_on_stop(&mut self) { - self.on_stop.clear(); - } - - // Param is passed by value, moved - pub fn set_on_stop(&mut self, v: ::std::string::String) { - self.on_stop = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_on_stop(&mut self) -> &mut ::std::string::String { - &mut self.on_stop - } - - // Take field - pub fn take_on_stop(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.on_stop, ::std::string::String::new()) - } - - // bool force_relay = 5; - - - pub fn get_force_relay(&self) -> bool { - self.force_relay - } - pub fn clear_force_relay(&mut self) { - self.force_relay = false; - } - - // Param is passed by value, moved - pub fn set_force_relay(&mut self, v: bool) { - self.force_relay = v; - } -} - -impl ::protobuf::Message for WebRtcPlayEndpoint { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.id)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.src)?; - }, - 3 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.on_start)?; - }, - 4 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.on_stop)?; - }, - 5 => { - if wire_type != ::protobuf::wire_format::WireTypeVarint { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - let tmp = is.read_bool()?; - self.force_relay = tmp; - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.id.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.id); - } - if !self.src.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.src); - } - if !self.on_start.is_empty() { - my_size += ::protobuf::rt::string_size(3, &self.on_start); - } - if !self.on_stop.is_empty() { - my_size += ::protobuf::rt::string_size(4, &self.on_stop); - } - if self.force_relay != false { - my_size += 2; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.id.is_empty() { - os.write_string(1, &self.id)?; - } - if !self.src.is_empty() { - os.write_string(2, &self.src)?; - } - if !self.on_start.is_empty() { - os.write_string(3, &self.on_start)?; - } - if !self.on_stop.is_empty() { - os.write_string(4, &self.on_stop)?; - } - if self.force_relay != false { - os.write_bool(5, self.force_relay)?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> WebRtcPlayEndpoint { - WebRtcPlayEndpoint::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "id", - |m: &WebRtcPlayEndpoint| { &m.id }, - |m: &mut WebRtcPlayEndpoint| { &mut m.id }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "src", - |m: &WebRtcPlayEndpoint| { &m.src }, - |m: &mut WebRtcPlayEndpoint| { &mut m.src }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "on_start", - |m: &WebRtcPlayEndpoint| { &m.on_start }, - |m: &mut WebRtcPlayEndpoint| { &mut m.on_start }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "on_stop", - |m: &WebRtcPlayEndpoint| { &m.on_stop }, - |m: &mut WebRtcPlayEndpoint| { &mut m.on_stop }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeBool>( - "force_relay", - |m: &WebRtcPlayEndpoint| { &m.force_relay }, - |m: &mut WebRtcPlayEndpoint| { &mut m.force_relay }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "WebRtcPlayEndpoint", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static WebRtcPlayEndpoint { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const WebRtcPlayEndpoint, - }; - unsafe { - instance.get(WebRtcPlayEndpoint::new) - } - } -} - -impl ::protobuf::Clear for WebRtcPlayEndpoint { - fn clear(&mut self) { - self.id.clear(); - self.src.clear(); - self.on_start.clear(); - self.on_stop.clear(); - self.force_relay = false; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for WebRtcPlayEndpoint { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for WebRtcPlayEndpoint { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\tapi.proto\x12\x05medea\"\xfd\x01\n\rCreateRequest\x12\x1d\n\nparent_\ - fid\x18\x01\x20\x01(\tR\tparentFid\x12'\n\x06member\x18\x02\x20\x01(\x0b\ - 2\r.medea.MemberH\0R\x06member\x12!\n\x04room\x18\x03\x20\x01(\x0b2\x0b.\ - medea.RoomH\0R\x04room\x12<\n\x0bwebrtc_play\x18\x04\x20\x01(\x0b2\x19.m\ - edea.WebRtcPlayEndpointH\0R\nwebrtcPlay\x12=\n\nwebrtc_pub\x18\x05\x20\ - \x01(\x0b2\x1c.medea.WebRtcPublishEndpointH\0R\twebrtcPubB\x04\n\x02el\"\ - \x1d\n\tIdRequest\x12\x10\n\x03fid\x18\x01\x20\x03(\tR\x03fid\".\n\x08Re\ - sponse\x12\"\n\x05error\x18\x01\x20\x01(\x0b2\x0c.medea.ErrorR\x05error\ - \"\x9e\x01\n\x0eCreateResponse\x120\n\x03sid\x18\x01\x20\x03(\x0b2\x1e.m\ - edea.CreateResponse.SidEntryR\x03sid\x12\"\n\x05error\x18\x02\x20\x01(\ - \x0b2\x0c.medea.ErrorR\x05error\x1a6\n\x08SidEntry\x12\x10\n\x03key\x18\ - \x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\tR\x05value:\ - \x028\x01\"\xbc\x01\n\x0bGetResponse\x12<\n\x08elements\x18\x01\x20\x03(\ - \x0b2\x20.medea.GetResponse.ElementsEntryR\x08elements\x12\"\n\x05error\ - \x18\x02\x20\x01(\x0b2\x0c.medea.ErrorR\x05error\x1aK\n\rElementsEntry\ - \x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12$\n\x05value\x18\x02\x20\ - \x01(\x0b2\x0e.medea.ElementR\x05value:\x028\x01\"[\n\x05Error\x12\x12\n\ - \x04code\x18\x01\x20\x01(\rR\x04code\x12\x12\n\x04text\x18\x02\x20\x01(\ - \tR\x04text\x12\x10\n\x03doc\x18\x03\x20\x01(\tR\x03doc\x12\x18\n\x07ele\ - ment\x18\x04\x20\x01(\tR\x07element\"\xd8\x01\n\x07Element\x12'\n\x06mem\ - ber\x18\x01\x20\x01(\x0b2\r.medea.MemberH\0R\x06member\x12!\n\x04room\ - \x18\x02\x20\x01(\x0b2\x0b.medea.RoomH\0R\x04room\x12<\n\x0bwebrtc_play\ - \x18\x03\x20\x01(\x0b2\x19.medea.WebRtcPlayEndpointH\0R\nwebrtcPlay\x12=\ - \n\nwebrtc_pub\x18\x04\x20\x01(\x0b2\x1c.medea.WebRtcPublishEndpointH\0R\ - \twebrtcPubB\x04\n\x02el\"\xd7\x02\n\x04Room\x12\x0e\n\x02id\x18\x01\x20\ - \x01(\tR\x02id\x125\n\x08pipeline\x18\x02\x20\x03(\x0b2\x19.medea.Room.P\ - ipelineEntryR\x08pipeline\x1aP\n\rPipelineEntry\x12\x10\n\x03key\x18\x01\ - \x20\x01(\tR\x03key\x12)\n\x05value\x18\x02\x20\x01(\x0b2\x13.medea.Room\ - .ElementR\x05value:\x028\x01\x1a\xb5\x01\n\x07Element\x12'\n\x06member\ - \x18\x01\x20\x01(\x0b2\r.medea.MemberH\0R\x06member\x12<\n\x0bwebrtc_pla\ - y\x18\x02\x20\x01(\x0b2\x19.medea.WebRtcPlayEndpointH\0R\nwebrtcPlay\x12\ - =\n\nwebrtc_pub\x18\x03\x20\x01(\x0b2\x1c.medea.WebRtcPublishEndpointH\0\ - R\twebrtcPubB\x04\n\x02el\"\x8a\x03\n\x06Member\x12\x0e\n\x02id\x18\x01\ - \x20\x01(\tR\x02id\x12\x17\n\x07on_join\x18\x02\x20\x01(\tR\x06onJoin\ - \x12\x19\n\x08on_leave\x18\x03\x20\x01(\tR\x07onLeave\x12\x20\n\x0bcrede\ - ntials\x18\x04\x20\x01(\tR\x0bcredentials\x127\n\x08pipeline\x18\x05\x20\ - \x03(\x0b2\x1b.medea.Member.PipelineEntryR\x08pipeline\x1aR\n\rPipelineE\ - ntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12+\n\x05value\x18\x02\ - \x20\x01(\x0b2\x15.medea.Member.ElementR\x05value:\x028\x01\x1a\x8c\x01\ - \n\x07Element\x12<\n\x0bwebrtc_play\x18\x01\x20\x01(\x0b2\x19.medea.WebR\ - tcPlayEndpointH\0R\nwebrtcPlay\x12=\n\nwebrtc_pub\x18\x02\x20\x01(\x0b2\ - \x1c.medea.WebRtcPublishEndpointH\0R\twebrtcPubB\x04\n\x02el\"\xdf\x01\n\ - \x15WebRtcPublishEndpoint\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x122\ - \n\x03p2p\x18\x02\x20\x01(\x0e2\x20.medea.WebRtcPublishEndpoint.P2PR\x03\ - p2p\x12\x19\n\x08on_start\x18\x03\x20\x01(\tR\x07onStart\x12\x17\n\x07on\ - _stop\x18\x04\x20\x01(\tR\x06onStop\x12\x1f\n\x0bforce_relay\x18\x05\x20\ - \x01(\x08R\nforceRelay\"-\n\x03P2P\x12\t\n\x05NEVER\x10\0\x12\x0f\n\x0bI\ - F_POSSIBLE\x10\x01\x12\n\n\x06ALWAYS\x10\x02\"\x8b\x01\n\x12WebRtcPlayEn\ - dpoint\x12\x0e\n\x02id\x18\x01\x20\x01(\tR\x02id\x12\x10\n\x03src\x18\ - \x02\x20\x01(\tR\x03src\x12\x19\n\x08on_start\x18\x03\x20\x01(\tR\x07onS\ - tart\x12\x17\n\x07on_stop\x18\x04\x20\x01(\tR\x06onStop\x12\x1f\n\x0bfor\ - ce_relay\x18\x05\x20\x01(\x08R\nforceRelay2\x9d\x01\n\nControlApi\x125\n\ - \x06Create\x12\x14.medea.CreateRequest\x1a\x15.medea.CreateResponse\x12+\ - \n\x06Delete\x12\x10.medea.IdRequest\x1a\x0f.medea.Response\x12+\n\x03Ge\ - t\x12\x10.medea.IdRequest\x1a\x12.medea.GetResponseb\x06proto3\ -"; - -static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto, -}; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - unsafe { - file_descriptor_proto_lazy.get(|| { - parse_descriptor_proto() - }) - } -} diff --git a/proto/control-api/src/grpc/api_grpc.rs b/proto/control-api/src/grpc/api_grpc.rs deleted file mode 100644 index aa3260cfa..000000000 --- a/proto/control-api/src/grpc/api_grpc.rs +++ /dev/null @@ -1,127 +0,0 @@ -// This file is generated. Do not edit -// @generated - -// https://github.com/Manishearth/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![cfg_attr(rustfmt, rustfmt_skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unsafe_code)] -#![allow(unused_imports)] -#![allow(unused_results)] - -const METHOD_CONTROL_API_CREATE: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/medea.ControlApi/Create", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_CONTROL_API_DELETE: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/medea.ControlApi/Delete", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -const METHOD_CONTROL_API_GET: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/medea.ControlApi/Get", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -#[derive(Clone)] -pub struct ControlApiClient { - client: ::grpcio::Client, -} - -impl ControlApiClient { - pub fn new(channel: ::grpcio::Channel) -> Self { - ControlApiClient { - client: ::grpcio::Client::new(channel), - } - } - - pub fn create_opt(&self, req: &super::api::CreateRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_CONTROL_API_CREATE, req, opt) - } - - pub fn create(&self, req: &super::api::CreateRequest) -> ::grpcio::Result { - self.create_opt(req, ::grpcio::CallOption::default()) - } - - pub fn create_async_opt(&self, req: &super::api::CreateRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_CONTROL_API_CREATE, req, opt) - } - - pub fn create_async(&self, req: &super::api::CreateRequest) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.create_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn delete_opt(&self, req: &super::api::IdRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_CONTROL_API_DELETE, req, opt) - } - - pub fn delete(&self, req: &super::api::IdRequest) -> ::grpcio::Result { - self.delete_opt(req, ::grpcio::CallOption::default()) - } - - pub fn delete_async_opt(&self, req: &super::api::IdRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_CONTROL_API_DELETE, req, opt) - } - - pub fn delete_async(&self, req: &super::api::IdRequest) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.delete_async_opt(req, ::grpcio::CallOption::default()) - } - - pub fn get_opt(&self, req: &super::api::IdRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_CONTROL_API_GET, req, opt) - } - - pub fn get(&self, req: &super::api::IdRequest) -> ::grpcio::Result { - self.get_opt(req, ::grpcio::CallOption::default()) - } - - pub fn get_async_opt(&self, req: &super::api::IdRequest, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_CONTROL_API_GET, req, opt) - } - - pub fn get_async(&self, req: &super::api::IdRequest) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.get_async_opt(req, ::grpcio::CallOption::default()) - } - pub fn spawn(&self, f: F) where F: ::futures::Future + Send + 'static { - self.client.spawn(f) - } -} - -pub trait ControlApi { - fn create(&mut self, ctx: ::grpcio::RpcContext, req: super::api::CreateRequest, sink: ::grpcio::UnarySink); - fn delete(&mut self, ctx: ::grpcio::RpcContext, req: super::api::IdRequest, sink: ::grpcio::UnarySink); - fn get(&mut self, ctx: ::grpcio::RpcContext, req: super::api::IdRequest, sink: ::grpcio::UnarySink); -} - -pub fn create_control_api(s: S) -> ::grpcio::Service { - let mut builder = ::grpcio::ServiceBuilder::new(); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_CONTROL_API_CREATE, move |ctx, req, resp| { - instance.create(ctx, req, resp) - }); - let mut instance = s.clone(); - builder = builder.add_unary_handler(&METHOD_CONTROL_API_DELETE, move |ctx, req, resp| { - instance.delete(ctx, req, resp) - }); - let mut instance = s; - builder = builder.add_unary_handler(&METHOD_CONTROL_API_GET, move |ctx, req, resp| { - instance.get(ctx, req, resp) - }); - builder.build() -} diff --git a/proto/control-api/src/grpc/callback.rs b/proto/control-api/src/grpc/callback.rs deleted file mode 100644 index 764fcf226..000000000 --- a/proto/control-api/src/grpc/callback.rs +++ /dev/null @@ -1,902 +0,0 @@ -// This file is generated by rust-protobuf 2.10.1. Do not edit -// @generated - -// https://github.com/rust-lang/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![cfg_attr(rustfmt, rustfmt_skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unsafe_code)] -#![allow(unused_imports)] -#![allow(unused_results)] -//! Generated file from `callback.proto` - -use protobuf::Message as Message_imported_for_functions; -use protobuf::ProtobufEnum as ProtobufEnum_imported_for_functions; - -/// Generated files are compatible only with the same version -/// of protobuf runtime. -// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_10_1; - -#[derive(PartialEq,Clone,Default)] -pub struct Request { - // message fields - pub fid: ::std::string::String, - pub at: ::std::string::String, - // message oneof groups - pub event: ::std::option::Option, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Request { - fn default() -> &'a Request { - ::default_instance() - } -} - -#[derive(Clone,PartialEq,Debug)] -pub enum Request_oneof_event { - on_join(OnJoin), - on_leave(OnLeave), -} - -impl Request { - pub fn new() -> Request { - ::std::default::Default::default() - } - - // string fid = 1; - - - pub fn get_fid(&self) -> &str { - &self.fid - } - pub fn clear_fid(&mut self) { - self.fid.clear(); - } - - // Param is passed by value, moved - pub fn set_fid(&mut self, v: ::std::string::String) { - self.fid = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_fid(&mut self) -> &mut ::std::string::String { - &mut self.fid - } - - // Take field - pub fn take_fid(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.fid, ::std::string::String::new()) - } - - // string at = 2; - - - pub fn get_at(&self) -> &str { - &self.at - } - pub fn clear_at(&mut self) { - self.at.clear(); - } - - // Param is passed by value, moved - pub fn set_at(&mut self, v: ::std::string::String) { - self.at = v; - } - - // Mutable pointer to the field. - // If field is not initialized, it is initialized with default value first. - pub fn mut_at(&mut self) -> &mut ::std::string::String { - &mut self.at - } - - // Take field - pub fn take_at(&mut self) -> ::std::string::String { - ::std::mem::replace(&mut self.at, ::std::string::String::new()) - } - - // .medea_callback.OnJoin on_join = 3; - - - pub fn get_on_join(&self) -> &OnJoin { - match self.event { - ::std::option::Option::Some(Request_oneof_event::on_join(ref v)) => v, - _ => OnJoin::default_instance(), - } - } - pub fn clear_on_join(&mut self) { - self.event = ::std::option::Option::None; - } - - pub fn has_on_join(&self) -> bool { - match self.event { - ::std::option::Option::Some(Request_oneof_event::on_join(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_on_join(&mut self, v: OnJoin) { - self.event = ::std::option::Option::Some(Request_oneof_event::on_join(v)) - } - - // Mutable pointer to the field. - pub fn mut_on_join(&mut self) -> &mut OnJoin { - if let ::std::option::Option::Some(Request_oneof_event::on_join(_)) = self.event { - } else { - self.event = ::std::option::Option::Some(Request_oneof_event::on_join(OnJoin::new())); - } - match self.event { - ::std::option::Option::Some(Request_oneof_event::on_join(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_on_join(&mut self) -> OnJoin { - if self.has_on_join() { - match self.event.take() { - ::std::option::Option::Some(Request_oneof_event::on_join(v)) => v, - _ => panic!(), - } - } else { - OnJoin::new() - } - } - - // .medea_callback.OnLeave on_leave = 4; - - - pub fn get_on_leave(&self) -> &OnLeave { - match self.event { - ::std::option::Option::Some(Request_oneof_event::on_leave(ref v)) => v, - _ => OnLeave::default_instance(), - } - } - pub fn clear_on_leave(&mut self) { - self.event = ::std::option::Option::None; - } - - pub fn has_on_leave(&self) -> bool { - match self.event { - ::std::option::Option::Some(Request_oneof_event::on_leave(..)) => true, - _ => false, - } - } - - // Param is passed by value, moved - pub fn set_on_leave(&mut self, v: OnLeave) { - self.event = ::std::option::Option::Some(Request_oneof_event::on_leave(v)) - } - - // Mutable pointer to the field. - pub fn mut_on_leave(&mut self) -> &mut OnLeave { - if let ::std::option::Option::Some(Request_oneof_event::on_leave(_)) = self.event { - } else { - self.event = ::std::option::Option::Some(Request_oneof_event::on_leave(OnLeave::new())); - } - match self.event { - ::std::option::Option::Some(Request_oneof_event::on_leave(ref mut v)) => v, - _ => panic!(), - } - } - - // Take field - pub fn take_on_leave(&mut self) -> OnLeave { - if self.has_on_leave() { - match self.event.take() { - ::std::option::Option::Some(Request_oneof_event::on_leave(v)) => v, - _ => panic!(), - } - } else { - OnLeave::new() - } - } -} - -impl ::protobuf::Message for Request { - fn is_initialized(&self) -> bool { - if let Some(Request_oneof_event::on_join(ref v)) = self.event { - if !v.is_initialized() { - return false; - } - } - if let Some(Request_oneof_event::on_leave(ref v)) = self.event { - if !v.is_initialized() { - return false; - } - } - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.fid)?; - }, - 2 => { - ::protobuf::rt::read_singular_proto3_string_into(wire_type, is, &mut self.at)?; - }, - 3 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.event = ::std::option::Option::Some(Request_oneof_event::on_join(is.read_message()?)); - }, - 4 => { - if wire_type != ::protobuf::wire_format::WireTypeLengthDelimited { - return ::std::result::Result::Err(::protobuf::rt::unexpected_wire_type(wire_type)); - } - self.event = ::std::option::Option::Some(Request_oneof_event::on_leave(is.read_message()?)); - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if !self.fid.is_empty() { - my_size += ::protobuf::rt::string_size(1, &self.fid); - } - if !self.at.is_empty() { - my_size += ::protobuf::rt::string_size(2, &self.at); - } - if let ::std::option::Option::Some(ref v) = self.event { - match v { - &Request_oneof_event::on_join(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - &Request_oneof_event::on_leave(ref v) => { - let len = v.compute_size(); - my_size += 1 + ::protobuf::rt::compute_raw_varint32_size(len) + len; - }, - }; - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if !self.fid.is_empty() { - os.write_string(1, &self.fid)?; - } - if !self.at.is_empty() { - os.write_string(2, &self.at)?; - } - if let ::std::option::Option::Some(ref v) = self.event { - match v { - &Request_oneof_event::on_join(ref v) => { - os.write_tag(3, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - &Request_oneof_event::on_leave(ref v) => { - os.write_tag(4, ::protobuf::wire_format::WireTypeLengthDelimited)?; - os.write_raw_varint32(v.get_cached_size())?; - v.write_to_with_cached_sizes(os)?; - }, - }; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Request { - Request::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "fid", - |m: &Request| { &m.fid }, - |m: &mut Request| { &mut m.fid }, - )); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeString>( - "at", - |m: &Request| { &m.at }, - |m: &mut Request| { &mut m.at }, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, OnJoin>( - "on_join", - Request::has_on_join, - Request::get_on_join, - )); - fields.push(::protobuf::reflect::accessor::make_singular_message_accessor::<_, OnLeave>( - "on_leave", - Request::has_on_leave, - Request::get_on_leave, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "Request", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static Request { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const Request, - }; - unsafe { - instance.get(Request::new) - } - } -} - -impl ::protobuf::Clear for Request { - fn clear(&mut self) { - self.fid.clear(); - self.at.clear(); - self.event = ::std::option::Option::None; - self.event = ::std::option::Option::None; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Request { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Request { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct Response { - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a Response { - fn default() -> &'a Response { - ::default_instance() - } -} - -impl Response { - pub fn new() -> Response { - ::std::default::Default::default() - } -} - -impl ::protobuf::Message for Response { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> Response { - Response::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let fields = ::std::vec::Vec::new(); - ::protobuf::reflect::MessageDescriptor::new::( - "Response", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static Response { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const Response, - }; - unsafe { - instance.get(Response::new) - } - } -} - -impl ::protobuf::Clear for Response { - fn clear(&mut self) { - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for Response { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for Response { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct OnJoin { - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a OnJoin { - fn default() -> &'a OnJoin { - ::default_instance() - } -} - -impl OnJoin { - pub fn new() -> OnJoin { - ::std::default::Default::default() - } -} - -impl ::protobuf::Message for OnJoin { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> OnJoin { - OnJoin::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let fields = ::std::vec::Vec::new(); - ::protobuf::reflect::MessageDescriptor::new::( - "OnJoin", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static OnJoin { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const OnJoin, - }; - unsafe { - instance.get(OnJoin::new) - } - } -} - -impl ::protobuf::Clear for OnJoin { - fn clear(&mut self) { - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for OnJoin { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for OnJoin { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(PartialEq,Clone,Default)] -pub struct OnLeave { - // message fields - pub reason: OnLeave_Reason, - // special fields - pub unknown_fields: ::protobuf::UnknownFields, - pub cached_size: ::protobuf::CachedSize, -} - -impl<'a> ::std::default::Default for &'a OnLeave { - fn default() -> &'a OnLeave { - ::default_instance() - } -} - -impl OnLeave { - pub fn new() -> OnLeave { - ::std::default::Default::default() - } - - // .medea_callback.OnLeave.Reason reason = 1; - - - pub fn get_reason(&self) -> OnLeave_Reason { - self.reason - } - pub fn clear_reason(&mut self) { - self.reason = OnLeave_Reason::DISCONNECTED; - } - - // Param is passed by value, moved - pub fn set_reason(&mut self, v: OnLeave_Reason) { - self.reason = v; - } -} - -impl ::protobuf::Message for OnLeave { - fn is_initialized(&self) -> bool { - true - } - - fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::ProtobufResult<()> { - while !is.eof()? { - let (field_number, wire_type) = is.read_tag_unpack()?; - match field_number { - 1 => { - ::protobuf::rt::read_proto3_enum_with_unknown_fields_into(wire_type, is, &mut self.reason, 1, &mut self.unknown_fields)? - }, - _ => { - ::protobuf::rt::read_unknown_or_skip_group(field_number, wire_type, is, self.mut_unknown_fields())?; - }, - }; - } - ::std::result::Result::Ok(()) - } - - // Compute sizes of nested messages - #[allow(unused_variables)] - fn compute_size(&self) -> u32 { - let mut my_size = 0; - if self.reason != OnLeave_Reason::DISCONNECTED { - my_size += ::protobuf::rt::enum_size(1, self.reason); - } - my_size += ::protobuf::rt::unknown_fields_size(self.get_unknown_fields()); - self.cached_size.set(my_size); - my_size - } - - fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.reason != OnLeave_Reason::DISCONNECTED { - os.write_enum(1, self.reason.value())?; - } - os.write_unknown_fields(self.get_unknown_fields())?; - ::std::result::Result::Ok(()) - } - - fn get_cached_size(&self) -> u32 { - self.cached_size.get() - } - - fn get_unknown_fields(&self) -> &::protobuf::UnknownFields { - &self.unknown_fields - } - - fn mut_unknown_fields(&mut self) -> &mut ::protobuf::UnknownFields { - &mut self.unknown_fields - } - - fn as_any(&self) -> &dyn (::std::any::Any) { - self as &dyn (::std::any::Any) - } - fn as_any_mut(&mut self) -> &mut dyn (::std::any::Any) { - self as &mut dyn (::std::any::Any) - } - fn into_any(self: Box) -> ::std::boxed::Box { - self - } - - fn descriptor(&self) -> &'static ::protobuf::reflect::MessageDescriptor { - Self::descriptor_static() - } - - fn new() -> OnLeave { - OnLeave::new() - } - - fn descriptor_static() -> &'static ::protobuf::reflect::MessageDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::MessageDescriptor, - }; - unsafe { - descriptor.get(|| { - let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( - "reason", - |m: &OnLeave| { &m.reason }, - |m: &mut OnLeave| { &mut m.reason }, - )); - ::protobuf::reflect::MessageDescriptor::new::( - "OnLeave", - fields, - file_descriptor_proto() - ) - }) - } - } - - fn default_instance() -> &'static OnLeave { - static mut instance: ::protobuf::lazy::Lazy = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const OnLeave, - }; - unsafe { - instance.get(OnLeave::new) - } - } -} - -impl ::protobuf::Clear for OnLeave { - fn clear(&mut self) { - self.reason = OnLeave_Reason::DISCONNECTED; - self.unknown_fields.clear(); - } -} - -impl ::std::fmt::Debug for OnLeave { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - ::protobuf::text_format::fmt(self, f) - } -} - -impl ::protobuf::reflect::ProtobufValue for OnLeave { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Message(self) - } -} - -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum OnLeave_Reason { - DISCONNECTED = 0, - LOST_CONNECTION = 1, - SERVER_SHUTDOWN = 2, -} - -impl ::protobuf::ProtobufEnum for OnLeave_Reason { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(OnLeave_Reason::DISCONNECTED), - 1 => ::std::option::Option::Some(OnLeave_Reason::LOST_CONNECTION), - 2 => ::std::option::Option::Some(OnLeave_Reason::SERVER_SHUTDOWN), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [OnLeave_Reason] = &[ - OnLeave_Reason::DISCONNECTED, - OnLeave_Reason::LOST_CONNECTION, - OnLeave_Reason::SERVER_SHUTDOWN, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static mut descriptor: ::protobuf::lazy::Lazy<::protobuf::reflect::EnumDescriptor> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::reflect::EnumDescriptor, - }; - unsafe { - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new("OnLeave_Reason", file_descriptor_proto()) - }) - } - } -} - -impl ::std::marker::Copy for OnLeave_Reason { -} - -impl ::std::default::Default for OnLeave_Reason { - fn default() -> Self { - OnLeave_Reason::DISCONNECTED - } -} - -impl ::protobuf::reflect::ProtobufValue for OnLeave_Reason { - fn as_ref(&self) -> ::protobuf::reflect::ProtobufValueRef { - ::protobuf::reflect::ProtobufValueRef::Enum(self.descriptor()) - } -} - -static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0ecallback.proto\x12\x0emedea_callback\"\x9d\x01\n\x07Request\x12\ - \x10\n\x03fid\x18\x01\x20\x01(\tR\x03fid\x12\x0e\n\x02at\x18\x02\x20\x01\ - (\tR\x02at\x121\n\x07on_join\x18\x03\x20\x01(\x0b2\x16.medea_callback.On\ - JoinH\0R\x06onJoin\x124\n\x08on_leave\x18\x04\x20\x01(\x0b2\x17.medea_ca\ - llback.OnLeaveH\0R\x07onLeaveB\x07\n\x05event\"\n\n\x08Response\"\x08\n\ - \x06OnJoin\"\x87\x01\n\x07OnLeave\x126\n\x06reason\x18\x01\x20\x01(\x0e2\ - \x1e.medea_callback.OnLeave.ReasonR\x06reason\"D\n\x06Reason\x12\x10\n\ - \x0cDISCONNECTED\x10\0\x12\x13\n\x0fLOST_CONNECTION\x10\x01\x12\x13\n\ - \x0fSERVER_SHUTDOWN\x10\x022H\n\x08Callback\x12<\n\x07OnEvent\x12\x17.me\ - dea_callback.Request\x1a\x18.medea_callback.Responseb\x06proto3\ -"; - -static mut file_descriptor_proto_lazy: ::protobuf::lazy::Lazy<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::lazy::Lazy { - lock: ::protobuf::lazy::ONCE_INIT, - ptr: 0 as *const ::protobuf::descriptor::FileDescriptorProto, -}; - -fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { - ::protobuf::parse_from_bytes(file_descriptor_proto_data).unwrap() -} - -pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { - unsafe { - file_descriptor_proto_lazy.get(|| { - parse_descriptor_proto() - }) - } -} diff --git a/proto/control-api/src/grpc/callback_grpc.rs b/proto/control-api/src/grpc/callback_grpc.rs deleted file mode 100644 index 0f659cf45..000000000 --- a/proto/control-api/src/grpc/callback_grpc.rs +++ /dev/null @@ -1,71 +0,0 @@ -// This file is generated. Do not edit -// @generated - -// https://github.com/Manishearth/rust-clippy/issues/702 -#![allow(unknown_lints)] -#![allow(clippy::all)] - -#![cfg_attr(rustfmt, rustfmt_skip)] - -#![allow(box_pointers)] -#![allow(dead_code)] -#![allow(missing_docs)] -#![allow(non_camel_case_types)] -#![allow(non_snake_case)] -#![allow(non_upper_case_globals)] -#![allow(trivial_casts)] -#![allow(unsafe_code)] -#![allow(unused_imports)] -#![allow(unused_results)] - -const METHOD_CALLBACK_ON_EVENT: ::grpcio::Method = ::grpcio::Method { - ty: ::grpcio::MethodType::Unary, - name: "/medea_callback.Callback/OnEvent", - req_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, - resp_mar: ::grpcio::Marshaller { ser: ::grpcio::pb_ser, de: ::grpcio::pb_de }, -}; - -#[derive(Clone)] -pub struct CallbackClient { - client: ::grpcio::Client, -} - -impl CallbackClient { - pub fn new(channel: ::grpcio::Channel) -> Self { - CallbackClient { - client: ::grpcio::Client::new(channel), - } - } - - pub fn on_event_opt(&self, req: &super::callback::Request, opt: ::grpcio::CallOption) -> ::grpcio::Result { - self.client.unary_call(&METHOD_CALLBACK_ON_EVENT, req, opt) - } - - pub fn on_event(&self, req: &super::callback::Request) -> ::grpcio::Result { - self.on_event_opt(req, ::grpcio::CallOption::default()) - } - - pub fn on_event_async_opt(&self, req: &super::callback::Request, opt: ::grpcio::CallOption) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.client.unary_call_async(&METHOD_CALLBACK_ON_EVENT, req, opt) - } - - pub fn on_event_async(&self, req: &super::callback::Request) -> ::grpcio::Result<::grpcio::ClientUnaryReceiver> { - self.on_event_async_opt(req, ::grpcio::CallOption::default()) - } - pub fn spawn(&self, f: F) where F: ::futures::Future + Send + 'static { - self.client.spawn(f) - } -} - -pub trait Callback { - fn on_event(&mut self, ctx: ::grpcio::RpcContext, req: super::callback::Request, sink: ::grpcio::UnarySink); -} - -pub fn create_callback(s: S) -> ::grpcio::Service { - let mut builder = ::grpcio::ServiceBuilder::new(); - let mut instance = s; - builder = builder.add_unary_handler(&METHOD_CALLBACK_ON_EVENT, move |ctx, req, resp| { - instance.on_event(ctx, req, resp) - }); - builder.build() -} diff --git a/proto/control-api/src/grpc/medea.rs b/proto/control-api/src/grpc/medea.rs new file mode 100644 index 000000000..92f518732 --- /dev/null +++ b/proto/control-api/src/grpc/medea.rs @@ -0,0 +1,241 @@ +/// Request of creating new Element with in element with a given FID (full ID). +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateRequest { + /// FID (full ID) of the Element in which the provided Element will be created. + #[prost(string, tag="1")] + pub parent_fid: std::string::String, + /// Spec of the created Element. + #[prost(oneof="create_request::El", tags="2, 3, 4, 5")] + pub el: ::std::option::Option, +} +pub mod create_request { + /// Spec of the created Element. + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum El { + #[prost(message, tag="2")] + Member(super::Member), + #[prost(message, tag="3")] + Room(super::Room), + #[prost(message, tag="4")] + WebrtcPlay(super::WebRtcPlayEndpoint), + #[prost(message, tag="5")] + WebrtcPub(super::WebRtcPublishEndpoint), + } +} +/// Request with many FIDs (full IDs) of Elements. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct IdRequest { + /// List of Elements FIDs. + #[prost(string, repeated, tag="1")] + pub fid: ::std::vec::Vec, +} +/// Response which doesn't return anything on successful result, +/// but is fallible with an Error. +/// +/// If operation fails then an Error will be returned. +/// The response is considered successful only if it does not contain Error. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Response { + /// Error of the Response. + #[prost(message, optional, tag="1")] + pub error: ::std::option::Option, +} +/// Response of Create RPC method. +/// +/// If operation fails then an Error will be returned. +/// The response is considered successful only if it does not contain Error. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CreateResponse { + /// Hashmap with IDs (key) and URIs (value) of Elements, which should be used + /// by clients to connect to a media server via Client API. + /// + /// Returned only if CreateResponse is successful. + #[prost(map="string, string", tag="1")] + pub sid: ::std::collections::HashMap, + /// Error of the CreateResponse. + #[prost(message, optional, tag="2")] + pub error: ::std::option::Option, +} +/// Response of Get RPC method. +/// +/// If operation fails then an Error will be returned. +/// The response is considered successful only if it does not contain Error. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct GetResponse { + /// Hashmap with IDs (key) and specs (value) of the requested Elements. + /// + /// Returned only if GetResponse is successful. + #[prost(map="string, message", tag="1")] + pub elements: ::std::collections::HashMap, + /// Error of the GetResponse. + #[prost(message, optional, tag="2")] + pub error: ::std::option::Option, +} +/// Error of failed request. +/// +/// If the Error is not returned then request is considered as successful. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Error { + /// Concrete unique code of the Error. + #[prost(uint32, tag="1")] + pub code: u32, + /// Human-readable text description of the Error. + #[prost(string, tag="2")] + pub text: std::string::String, + /// Link to online documentation of the Error. + /// + /// Optional field. + #[prost(string, tag="3")] + pub doc: std::string::String, + /// Full ID of Element that the Error is related to. + /// Some Errors are not related to any Element and in such case + /// this field is empty. + /// + /// Optional field. + #[prost(string, tag="4")] + pub element: std::string::String, +} +/// Media element which can be used in a media pipeline. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Element { + #[prost(oneof="element::El", tags="1, 2, 3, 4")] + pub el: ::std::option::Option, +} +pub mod element { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum El { + #[prost(message, tag="1")] + Member(super::Member), + #[prost(message, tag="2")] + Room(super::Room), + #[prost(message, tag="3")] + WebrtcPlay(super::WebRtcPlayEndpoint), + #[prost(message, tag="4")] + WebrtcPub(super::WebRtcPublishEndpoint), + } +} +/// Media element which represents a single space where multiple Members can +/// interact with each other. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Room { + /// ID of this Room. + #[prost(string, tag="1")] + pub id: std::string::String, + /// Pipeline of this Room. + #[prost(map="string, message", tag="2")] + pub pipeline: ::std::collections::HashMap, +} +pub mod room { + /// Elements which Room's pipeline can contain. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Element { + #[prost(oneof="element::El", tags="1, 2, 3")] + pub el: ::std::option::Option, + } + pub mod element { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum El { + #[prost(message, tag="1")] + Member(super::super::Member), + #[prost(message, tag="2")] + WebrtcPlay(super::super::WebRtcPlayEndpoint), + #[prost(message, tag="3")] + WebrtcPub(super::super::WebRtcPublishEndpoint), + } + } +} +/// Media element which represents a client authorized to participate +/// in a some bigger media pipeline. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Member { + /// ID of this Member. + #[prost(string, tag="1")] + pub id: std::string::String, + /// Callback which fires when the Member establishes persistent connection + /// with a media server via Client API. + #[prost(string, tag="2")] + pub on_join: std::string::String, + /// Callback which fires when the Member finishes persistent connection + /// with a media server via Client API. + #[prost(string, tag="3")] + pub on_leave: std::string::String, + /// Credentials of the Member to authorize via Client API with. + #[prost(string, tag="4")] + pub credentials: std::string::String, + /// Pipeline of this Member. + #[prost(map="string, message", tag="5")] + pub pipeline: ::std::collections::HashMap, +} +pub mod member { + /// Elements which Member's pipeline can contain. + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct Element { + #[prost(oneof="element::El", tags="1, 2")] + pub el: ::std::option::Option, + } + pub mod element { + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum El { + #[prost(message, tag="1")] + WebrtcPlay(super::super::WebRtcPlayEndpoint), + #[prost(message, tag="2")] + WebrtcPub(super::super::WebRtcPublishEndpoint), + } + } +} +/// Media element which is able to receive media data from a client via WebRTC +/// (allows to publish media data). +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct WebRtcPublishEndpoint { + /// ID of this WebRtcPublishEndpoint. + #[prost(string, tag="1")] + pub id: std::string::String, + /// P2P mode for this element. + #[prost(enumeration="web_rtc_publish_endpoint::P2p", tag="2")] + pub p2p: i32, + /// Callback which fires when a client starts publishing media data. + #[prost(string, tag="3")] + pub on_start: std::string::String, + /// Callback which fires when a client stops publishing media data. + #[prost(string, tag="4")] + pub on_stop: std::string::String, + /// Option to relay all media through a TURN server forcibly. + #[prost(bool, tag="5")] + pub force_relay: bool, +} +pub mod web_rtc_publish_endpoint { + /// P2P mode of WebRTC interaction. + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum P2p { + /// Always send media data through a media server. + Never = 0, + /// Send media data peer-to-peer directly if it's possible, + /// otherwise through a media server. + IfPossible = 1, + /// Send media data peer-to-peer only without a media server. + Always = 2, + } +} +/// Media element which is able to play media data for a client via WebRTC. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct WebRtcPlayEndpoint { + /// ID of this WebRtcPlayEndpoint. + #[prost(string, tag="1")] + pub id: std::string::String, + /// The source to get media data from. + #[prost(string, tag="2")] + pub src: std::string::String, + /// Callback which fires when a client starts playing media data + /// from the source. + #[prost(string, tag="3")] + pub on_start: std::string::String, + /// Callback which fires when a client stops playing media data + /// from the source. + #[prost(string, tag="4")] + pub on_stop: std::string::String, + /// Option to relay all media through a TURN server forcibly. + #[prost(bool, tag="5")] + pub force_relay: bool, +} +# [ doc = r" Generated client implementations." ] pub mod control_api_client { # ! [ allow ( unused_variables , dead_code , missing_docs ) ] use tonic :: codegen :: * ; # [ doc = " Media server's Control API service." ] pub struct ControlApiClient < T > { inner : tonic :: client :: Grpc < T > , } impl ControlApiClient < tonic :: transport :: Channel > { # [ doc = r" Attempt to create a new client by connecting to a given endpoint." ] pub async fn connect < D > ( dst : D ) -> Result < Self , tonic :: transport :: Error > where D : std :: convert :: TryInto < tonic :: transport :: Endpoint > , D :: Error : Into < StdError > , { let conn = tonic :: transport :: Endpoint :: new ( dst ) ? . connect ( ) . await ? ; Ok ( Self :: new ( conn ) ) } } impl < T > ControlApiClient < T > where T : tonic :: client :: GrpcService < tonic :: body :: BoxBody > , T :: ResponseBody : Body + HttpBody + Send + 'static , T :: Error : Into < StdError > , < T :: ResponseBody as HttpBody > :: Error : Into < StdError > + Send , { pub fn new ( inner : T ) -> Self { let inner = tonic :: client :: Grpc :: new ( inner ) ; Self { inner } } pub fn with_interceptor ( inner : T , interceptor : impl Into < tonic :: Interceptor > ) -> Self { let inner = tonic :: client :: Grpc :: with_interceptor ( inner , interceptor ) ; Self { inner } } # [ doc = " Creates new Element with a given ID." ] # [ doc = "" ] # [ doc = " Not idempotent. Errors if an Element with the same ID already exists." ] pub async fn create ( & mut self , request : impl tonic :: IntoRequest < super :: CreateRequest > , ) -> Result < tonic :: Response < super :: CreateResponse > , tonic :: Status > { self . inner . ready ( ) . await . map_err ( | e | { tonic :: Status :: new ( tonic :: Code :: Unknown , format ! ( "Service was not ready: {}" , e . into ( ) ) ) } ) ? ; let codec = tonic :: codec :: ProstCodec :: default ( ) ; let path = http :: uri :: PathAndQuery :: from_static ( "/medea.ControlApi/Create" ) ; self . inner . unary ( request . into_request ( ) , path , codec ) . await } # [ doc = " Removes Element by its ID." ] # [ doc = " Allows referring multiple Elements on the last two levels." ] # [ doc = "" ] # [ doc = " Idempotent. If no Elements with such IDs exist, then succeeds." ] pub async fn delete ( & mut self , request : impl tonic :: IntoRequest < super :: IdRequest > , ) -> Result < tonic :: Response < super :: Response > , tonic :: Status > { self . inner . ready ( ) . await . map_err ( | e | { tonic :: Status :: new ( tonic :: Code :: Unknown , format ! ( "Service was not ready: {}" , e . into ( ) ) ) } ) ? ; let codec = tonic :: codec :: ProstCodec :: default ( ) ; let path = http :: uri :: PathAndQuery :: from_static ( "/medea.ControlApi/Delete" ) ; self . inner . unary ( request . into_request ( ) , path , codec ) . await } # [ doc = " Returns Element by its ID." ] # [ doc = " Allows referring multiple Elements." ] # [ doc = " If no ID specified, returns all Elements declared." ] pub async fn get ( & mut self , request : impl tonic :: IntoRequest < super :: IdRequest > , ) -> Result < tonic :: Response < super :: GetResponse > , tonic :: Status > { self . inner . ready ( ) . await . map_err ( | e | { tonic :: Status :: new ( tonic :: Code :: Unknown , format ! ( "Service was not ready: {}" , e . into ( ) ) ) } ) ? ; let codec = tonic :: codec :: ProstCodec :: default ( ) ; let path = http :: uri :: PathAndQuery :: from_static ( "/medea.ControlApi/Get" ) ; self . inner . unary ( request . into_request ( ) , path , codec ) . await } } impl < T : Clone > Clone for ControlApiClient < T > { fn clone ( & self ) -> Self { Self { inner : self . inner . clone ( ) , } } } }# [ doc = r" Generated server implementations." ] pub mod control_api_server { # ! [ allow ( unused_variables , dead_code , missing_docs ) ] use tonic :: codegen :: * ; # [ doc = "Generated trait containing gRPC methods that should be implemented for use with ControlApiServer." ] # [ async_trait ] pub trait ControlApi : Send + Sync + 'static { # [ doc = " Creates new Element with a given ID." ] # [ doc = "" ] # [ doc = " Not idempotent. Errors if an Element with the same ID already exists." ] async fn create ( & self , request : tonic :: Request < super :: CreateRequest > ) -> Result < tonic :: Response < super :: CreateResponse > , tonic :: Status > ; # [ doc = " Removes Element by its ID." ] # [ doc = " Allows referring multiple Elements on the last two levels." ] # [ doc = "" ] # [ doc = " Idempotent. If no Elements with such IDs exist, then succeeds." ] async fn delete ( & self , request : tonic :: Request < super :: IdRequest > ) -> Result < tonic :: Response < super :: Response > , tonic :: Status > ; # [ doc = " Returns Element by its ID." ] # [ doc = " Allows referring multiple Elements." ] # [ doc = " If no ID specified, returns all Elements declared." ] async fn get ( & self , request : tonic :: Request < super :: IdRequest > ) -> Result < tonic :: Response < super :: GetResponse > , tonic :: Status > ; } # [ doc = " Media server's Control API service." ] # [ derive ( Debug ) ] # [ doc ( hidden ) ] pub struct ControlApiServer < T : ControlApi > { inner : _Inner < T > , } struct _Inner < T > ( Arc < T > , Option < tonic :: Interceptor > ) ; impl < T : ControlApi > ControlApiServer < T > { pub fn new ( inner : T ) -> Self { let inner = Arc :: new ( inner ) ; let inner = _Inner ( inner , None ) ; Self { inner } } pub fn with_interceptor ( inner : T , interceptor : impl Into < tonic :: Interceptor > ) -> Self { let inner = Arc :: new ( inner ) ; let inner = _Inner ( inner , Some ( interceptor . into ( ) ) ) ; Self { inner } } } impl < T : ControlApi > Service < http :: Request < HyperBody >> for ControlApiServer < T > { type Response = http :: Response < tonic :: body :: BoxBody > ; type Error = Never ; type Future = BoxFuture < Self :: Response , Self :: Error > ; fn poll_ready ( & mut self , _cx : & mut Context < '_ > ) -> Poll < Result < ( ) , Self :: Error >> { Poll :: Ready ( Ok ( ( ) ) ) } fn call ( & mut self , req : http :: Request < HyperBody > ) -> Self :: Future { let inner = self . inner . clone ( ) ; match req . uri ( ) . path ( ) { "/medea.ControlApi/Create" => { struct CreateSvc < T : ControlApi > ( pub Arc < T > ) ; impl < T : ControlApi > tonic :: server :: UnaryService < super :: CreateRequest > for CreateSvc < T > { type Response = super :: CreateResponse ; type Future = BoxFuture < tonic :: Response < Self :: Response > , tonic :: Status > ; fn call ( & mut self , request : tonic :: Request < super :: CreateRequest > ) -> Self :: Future { let inner = self . 0 . clone ( ) ; let fut = async move { inner . create ( request ) . await } ; Box :: pin ( fut ) } } let inner = self . inner . clone ( ) ; let fut = async move { let interceptor = inner . 1 . clone ( ) ; let inner = inner . 0 ; let method = CreateSvc ( inner ) ; let codec = tonic :: codec :: ProstCodec :: default ( ) ; let mut grpc = if let Some ( interceptor ) = interceptor { tonic :: server :: Grpc :: with_interceptor ( codec , interceptor ) } else { tonic :: server :: Grpc :: new ( codec ) } ; let res = grpc . unary ( method , req ) . await ; Ok ( res ) } ; Box :: pin ( fut ) } "/medea.ControlApi/Delete" => { struct DeleteSvc < T : ControlApi > ( pub Arc < T > ) ; impl < T : ControlApi > tonic :: server :: UnaryService < super :: IdRequest > for DeleteSvc < T > { type Response = super :: Response ; type Future = BoxFuture < tonic :: Response < Self :: Response > , tonic :: Status > ; fn call ( & mut self , request : tonic :: Request < super :: IdRequest > ) -> Self :: Future { let inner = self . 0 . clone ( ) ; let fut = async move { inner . delete ( request ) . await } ; Box :: pin ( fut ) } } let inner = self . inner . clone ( ) ; let fut = async move { let interceptor = inner . 1 . clone ( ) ; let inner = inner . 0 ; let method = DeleteSvc ( inner ) ; let codec = tonic :: codec :: ProstCodec :: default ( ) ; let mut grpc = if let Some ( interceptor ) = interceptor { tonic :: server :: Grpc :: with_interceptor ( codec , interceptor ) } else { tonic :: server :: Grpc :: new ( codec ) } ; let res = grpc . unary ( method , req ) . await ; Ok ( res ) } ; Box :: pin ( fut ) } "/medea.ControlApi/Get" => { struct GetSvc < T : ControlApi > ( pub Arc < T > ) ; impl < T : ControlApi > tonic :: server :: UnaryService < super :: IdRequest > for GetSvc < T > { type Response = super :: GetResponse ; type Future = BoxFuture < tonic :: Response < Self :: Response > , tonic :: Status > ; fn call ( & mut self , request : tonic :: Request < super :: IdRequest > ) -> Self :: Future { let inner = self . 0 . clone ( ) ; let fut = async move { inner . get ( request ) . await } ; Box :: pin ( fut ) } } let inner = self . inner . clone ( ) ; let fut = async move { let interceptor = inner . 1 . clone ( ) ; let inner = inner . 0 ; let method = GetSvc ( inner ) ; let codec = tonic :: codec :: ProstCodec :: default ( ) ; let mut grpc = if let Some ( interceptor ) = interceptor { tonic :: server :: Grpc :: with_interceptor ( codec , interceptor ) } else { tonic :: server :: Grpc :: new ( codec ) } ; let res = grpc . unary ( method , req ) . await ; Ok ( res ) } ; Box :: pin ( fut ) } _ => Box :: pin ( async move { Ok ( http :: Response :: builder ( ) . status ( 200 ) . header ( "grpc-status" , "12" ) . body ( tonic :: body :: BoxBody :: empty ( ) ) . unwrap ( ) ) } ) , } } } impl < T : ControlApi > Clone for ControlApiServer < T > { fn clone ( & self ) -> Self { let inner = self . inner . clone ( ) ; Self { inner } } } impl < T : ControlApi > Clone for _Inner < T > { fn clone ( & self ) -> Self { Self ( self . 0 . clone ( ) , self . 1 . clone ( ) ) } } impl < T : std :: fmt :: Debug > std :: fmt :: Debug for _Inner < T > { fn fmt ( & self , f : & mut std :: fmt :: Formatter < '_ > ) -> std :: fmt :: Result { write ! ( f , "{:?}" , self . 0 ) } } impl < T : ControlApi > tonic :: transport :: NamedService for ControlApiServer < T > { const NAME : & 'static str = "medea.ControlApi" ; } } \ No newline at end of file diff --git a/proto/control-api/src/grpc/medea_callback.rs b/proto/control-api/src/grpc/medea_callback.rs new file mode 100644 index 000000000..0790cf18e --- /dev/null +++ b/proto/control-api/src/grpc/medea_callback.rs @@ -0,0 +1,54 @@ +/// Request with a fired callback event and some meta information. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Request { + /// FID (Full ID) of the element that event was occurred with. + #[prost(string, tag="1")] + pub fid: std::string::String, + /// Time of event occurring. + #[prost(string, tag="2")] + pub at: std::string::String, + /// Occurred callback event. + #[prost(oneof="request::Event", tags="3, 4")] + pub event: ::std::option::Option, +} +pub mod request { + /// Occurred callback event. + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Event { + #[prost(message, tag="3")] + OnJoin(super::OnJoin), + #[prost(message, tag="4")] + OnLeave(super::OnLeave), + } +} +/// Empty response of the Callback service. +/// +/// We don't use 'google.protobuf.Empty' to be able to add +/// some fields (if necessary) in the future. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Response { +} +/// Event that fires when Member joins a Room. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct OnJoin { +} +/// Event that fires when Member leaves its Room. +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct OnLeave { + /// Reason of why Member leaves the Room. + #[prost(enumeration="on_leave::Reason", tag="1")] + pub reason: i32, +} +pub mod on_leave { + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] + #[repr(i32)] + pub enum Reason { + /// Member was normally disconnected. + Disconnected = 0, + /// Connection with Member was lost. + LostConnection = 1, + /// Medea media server is shutting down. + ServerShutdown = 2, + } +} +# [ doc = r" Generated client implementations." ] pub mod callback_client { # ! [ allow ( unused_variables , dead_code , missing_docs ) ] use tonic :: codegen :: * ; # [ doc = " Service for receiving callbacks from Medea media server." ] pub struct CallbackClient < T > { inner : tonic :: client :: Grpc < T > , } impl CallbackClient < tonic :: transport :: Channel > { # [ doc = r" Attempt to create a new client by connecting to a given endpoint." ] pub async fn connect < D > ( dst : D ) -> Result < Self , tonic :: transport :: Error > where D : std :: convert :: TryInto < tonic :: transport :: Endpoint > , D :: Error : Into < StdError > , { let conn = tonic :: transport :: Endpoint :: new ( dst ) ? . connect ( ) . await ? ; Ok ( Self :: new ( conn ) ) } } impl < T > CallbackClient < T > where T : tonic :: client :: GrpcService < tonic :: body :: BoxBody > , T :: ResponseBody : Body + HttpBody + Send + 'static , T :: Error : Into < StdError > , < T :: ResponseBody as HttpBody > :: Error : Into < StdError > + Send , { pub fn new ( inner : T ) -> Self { let inner = tonic :: client :: Grpc :: new ( inner ) ; Self { inner } } pub fn with_interceptor ( inner : T , interceptor : impl Into < tonic :: Interceptor > ) -> Self { let inner = tonic :: client :: Grpc :: with_interceptor ( inner , interceptor ) ; Self { inner } } # [ doc = "/ Fires when a certain callback event happens on Medea media server." ] pub async fn on_event ( & mut self , request : impl tonic :: IntoRequest < super :: Request > , ) -> Result < tonic :: Response < super :: Response > , tonic :: Status > { self . inner . ready ( ) . await . map_err ( | e | { tonic :: Status :: new ( tonic :: Code :: Unknown , format ! ( "Service was not ready: {}" , e . into ( ) ) ) } ) ? ; let codec = tonic :: codec :: ProstCodec :: default ( ) ; let path = http :: uri :: PathAndQuery :: from_static ( "/medea_callback.Callback/OnEvent" ) ; self . inner . unary ( request . into_request ( ) , path , codec ) . await } } impl < T : Clone > Clone for CallbackClient < T > { fn clone ( & self ) -> Self { Self { inner : self . inner . clone ( ) , } } } }# [ doc = r" Generated server implementations." ] pub mod callback_server { # ! [ allow ( unused_variables , dead_code , missing_docs ) ] use tonic :: codegen :: * ; # [ doc = "Generated trait containing gRPC methods that should be implemented for use with CallbackServer." ] # [ async_trait ] pub trait Callback : Send + Sync + 'static { # [ doc = "/ Fires when a certain callback event happens on Medea media server." ] async fn on_event ( & self , request : tonic :: Request < super :: Request > ) -> Result < tonic :: Response < super :: Response > , tonic :: Status > ; } # [ doc = " Service for receiving callbacks from Medea media server." ] # [ derive ( Debug ) ] # [ doc ( hidden ) ] pub struct CallbackServer < T : Callback > { inner : _Inner < T > , } struct _Inner < T > ( Arc < T > , Option < tonic :: Interceptor > ) ; impl < T : Callback > CallbackServer < T > { pub fn new ( inner : T ) -> Self { let inner = Arc :: new ( inner ) ; let inner = _Inner ( inner , None ) ; Self { inner } } pub fn with_interceptor ( inner : T , interceptor : impl Into < tonic :: Interceptor > ) -> Self { let inner = Arc :: new ( inner ) ; let inner = _Inner ( inner , Some ( interceptor . into ( ) ) ) ; Self { inner } } } impl < T : Callback > Service < http :: Request < HyperBody >> for CallbackServer < T > { type Response = http :: Response < tonic :: body :: BoxBody > ; type Error = Never ; type Future = BoxFuture < Self :: Response , Self :: Error > ; fn poll_ready ( & mut self , _cx : & mut Context < '_ > ) -> Poll < Result < ( ) , Self :: Error >> { Poll :: Ready ( Ok ( ( ) ) ) } fn call ( & mut self , req : http :: Request < HyperBody > ) -> Self :: Future { let inner = self . inner . clone ( ) ; match req . uri ( ) . path ( ) { "/medea_callback.Callback/OnEvent" => { struct OnEventSvc < T : Callback > ( pub Arc < T > ) ; impl < T : Callback > tonic :: server :: UnaryService < super :: Request > for OnEventSvc < T > { type Response = super :: Response ; type Future = BoxFuture < tonic :: Response < Self :: Response > , tonic :: Status > ; fn call ( & mut self , request : tonic :: Request < super :: Request > ) -> Self :: Future { let inner = self . 0 . clone ( ) ; let fut = async move { inner . on_event ( request ) . await } ; Box :: pin ( fut ) } } let inner = self . inner . clone ( ) ; let fut = async move { let interceptor = inner . 1 . clone ( ) ; let inner = inner . 0 ; let method = OnEventSvc ( inner ) ; let codec = tonic :: codec :: ProstCodec :: default ( ) ; let mut grpc = if let Some ( interceptor ) = interceptor { tonic :: server :: Grpc :: with_interceptor ( codec , interceptor ) } else { tonic :: server :: Grpc :: new ( codec ) } ; let res = grpc . unary ( method , req ) . await ; Ok ( res ) } ; Box :: pin ( fut ) } _ => Box :: pin ( async move { Ok ( http :: Response :: builder ( ) . status ( 200 ) . header ( "grpc-status" , "12" ) . body ( tonic :: body :: BoxBody :: empty ( ) ) . unwrap ( ) ) } ) , } } } impl < T : Callback > Clone for CallbackServer < T > { fn clone ( & self ) -> Self { let inner = self . inner . clone ( ) ; Self { inner } } } impl < T : Callback > Clone for _Inner < T > { fn clone ( & self ) -> Self { Self ( self . 0 . clone ( ) , self . 1 . clone ( ) ) } } impl < T : std :: fmt :: Debug > std :: fmt :: Debug for _Inner < T > { fn fmt ( & self , f : & mut std :: fmt :: Formatter < '_ > ) -> std :: fmt :: Result { write ! ( f , "{:?}" , self . 0 ) } } impl < T : Callback > tonic :: transport :: NamedService for CallbackServer < T > { const NAME : & 'static str = "medea_callback.Callback" ; } } \ No newline at end of file diff --git a/proto/control-api/src/grpc/mod.rs b/proto/control-api/src/grpc/mod.rs index 9b44f5a52..fd40f062d 100644 --- a/proto/control-api/src/grpc/mod.rs +++ b/proto/control-api/src/grpc/mod.rs @@ -5,7 +5,5 @@ clippy::pedantic, )] -pub mod api; -pub mod api_grpc; -pub mod callback; -pub mod callback_grpc; +pub mod medea; +pub mod medea_callback; diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index ff182c27c..ba420e2ca 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -8,8 +8,8 @@ use futures::{ }; use grpcio::{ChannelBuilder, EnvBuilder}; #[rustfmt::skip] -use medea_control_api_proto::grpc::callback_grpc::{ - CallbackClient as ProtoCallbackClient +use medea_control_api_proto::grpc::medea_callback::{ + callback_client::CallbackClient as ProtoCallbackClient }; use crate::api::control::callback::{ @@ -17,11 +17,12 @@ use crate::api::control::callback::{ url::GrpcCallbackUrl, CallbackRequest, }; +use tonic::transport::Channel; /// gRPC client for sending [`CallbackRequest`]s. pub struct GrpcCallbackClient { /// [`grpcio`] gRPC client of Control API Callback service. - client: ProtoCallbackClient, + client: ProtoCallbackClient, } impl fmt::Debug for GrpcCallbackClient { @@ -37,10 +38,9 @@ impl GrpcCallbackClient { /// /// Note that this function doesn't check availability of gRPC server on /// provided [`GrpcCallbackUrl`]. - pub fn new(addr: &GrpcCallbackUrl) -> Self { - let env = Arc::new(EnvBuilder::new().build()); - let ch = ChannelBuilder::new(env).connect(addr.addr()); - let client = ProtoCallbackClient::new(ch); + pub async fn new(addr: &GrpcCallbackUrl) -> Self { + let addr = addr.addr().to_string(); + let client = ProtoCallbackClient::connect(addr).await.unwrap(); Self { client } } diff --git a/src/api/control/callback/mod.rs b/src/api/control/callback/mod.rs index 7fb74c68b..8ac78d090 100644 --- a/src/api/control/callback/mod.rs +++ b/src/api/control/callback/mod.rs @@ -6,10 +6,10 @@ pub mod url; use chrono::{DateTime, Utc}; use derive_more::From; -use medea_control_api_proto::grpc::callback::{ +use medea_control_api_proto::grpc::medea_callback::{ OnJoin as OnJoinProto, OnJoin, OnLeave as OnLeaveProto, - OnLeave_Reason as OnLeaveReasonProto, Request as CallbackRequestProto, - Request_oneof_event as RequestOneofEventProto, + on_leave::Reason as OnLeaveReasonProto, Request as CallbackRequestProto, + request::Event as RequestOneofEventProto, }; use crate::api::control::refs::StatefulFid; diff --git a/src/api/control/endpoints/mod.rs b/src/api/control/endpoints/mod.rs index 08f913ade..37fdbf411 100644 --- a/src/api/control/endpoints/mod.rs +++ b/src/api/control/endpoints/mod.rs @@ -10,9 +10,9 @@ use std::convert::TryFrom; use derive_more::{Display, From, Into}; use serde::Deserialize; -use medea_control_api_proto::grpc::api::{ - CreateRequest_oneof_el as ElementProto, - Member_Element_oneof_el as MemberElementProto, +use medea_control_api_proto::grpc::medea::{ + create_request::El as ElementProto, + member::element::El as MemberElementProto, }; use super::{member::MemberElement, TryFromProtobufError}; @@ -78,11 +78,11 @@ impl TryFrom<(Id, MemberElementProto)> for EndpointSpec { ) -> Result { use MemberElementProto::*; match proto { - webrtc_play(elem) => { + WebrtcPlay(elem) => { let play = WebRtcPlayEndpoint::try_from(&elem)?; Ok(Self::WebRtcPlay(play)) } - webrtc_pub(elem) => { + WebrtcPub(elem) => { let publish = WebRtcPublishEndpoint::from(&elem); Ok(Self::WebRtcPublish(publish)) } @@ -96,15 +96,15 @@ impl TryFrom<(Id, ElementProto)> for EndpointSpec { fn try_from((id, proto): (Id, ElementProto)) -> Result { use ElementProto::*; match proto { - webrtc_play(elem) => { + WebrtcPlay(elem) => { let play = WebRtcPlayEndpoint::try_from(&elem)?; Ok(Self::WebRtcPlay(play)) } - webrtc_pub(elem) => { + WebrtcPub(elem) => { let publish = WebRtcPublishEndpoint::from(&elem); Ok(Self::WebRtcPublish(publish)) } - member(_) | room(_) => { + Member(_) | Room(_) => { Err(TryFromProtobufError::ExpectedOtherElement( String::from("Endpoint"), id.0, diff --git a/src/api/control/endpoints/webrtc_play_endpoint.rs b/src/api/control/endpoints/webrtc_play_endpoint.rs index ef29f4a83..4f5bc12f9 100644 --- a/src/api/control/endpoints/webrtc_play_endpoint.rs +++ b/src/api/control/endpoints/webrtc_play_endpoint.rs @@ -5,7 +5,7 @@ use std::convert::TryFrom; use derive_more::{Display, From, Into}; -use medea_control_api_proto::grpc::api as medea_grpc_control_api; +use medea_control_api_proto::grpc::medea as medea_grpc_control_api; use medea_grpc_control_api::WebRtcPlayEndpoint as WebRtcPlayEndpointProto; use serde::Deserialize; diff --git a/src/api/control/endpoints/webrtc_publish_endpoint.rs b/src/api/control/endpoints/webrtc_publish_endpoint.rs index f1eb7b64c..01449c26b 100644 --- a/src/api/control/endpoints/webrtc_publish_endpoint.rs +++ b/src/api/control/endpoints/webrtc_publish_endpoint.rs @@ -5,9 +5,9 @@ use derive_more::{Display, From, Into}; use serde::Deserialize; -use medea_control_api_proto::grpc::api::{ +use medea_control_api_proto::grpc::medea::{ WebRtcPublishEndpoint as WebRtcPublishEndpointProto, - WebRtcPublishEndpoint_P2P as WebRtcPublishEndpointP2pProto, + web_rtc_publish_endpoint::P2p as WebRtcPublishEndpointP2pProto, }; /// ID of [`WebRtcPublishEndpoint`]. diff --git a/src/api/control/error_codes.rs b/src/api/control/error_codes.rs index 98df4f364..7481f9422 100644 --- a/src/api/control/error_codes.rs +++ b/src/api/control/error_codes.rs @@ -7,7 +7,7 @@ use std::string::ToString; use derive_more::Display; -use medea_control_api_proto::grpc::api::Error as ErrorProto; +use medea_control_api_proto::grpc::medea::Error as ErrorProto; use crate::{ api::control::{ diff --git a/src/api/control/grpc/server.rs b/src/api/control/grpc/server.rs index 7c2d61088..7add10cd8 100644 --- a/src/api/control/grpc/server.rs +++ b/src/api/control/grpc/server.rs @@ -15,13 +15,15 @@ use futures::{ compat::Future01CompatExt as _, future::{self, BoxFuture, FutureExt as _, TryFutureExt as _}, }; -use grpcio::{Environment, RpcContext, Server, ServerBuilder, UnarySink}; +use tonic::{ + transport::Server +}; use medea_control_api_proto::grpc::{ - api::{ - CreateRequest, CreateRequest_oneof_el as CreateRequestOneof, + medea::{ + CreateRequest, create_request::El as CreateRequestOneof, CreateResponse, Element, GetResponse, IdRequest, Response, + control_api_server::{ControlApi, ControlApiServer}, }, - api_grpc::{create_control_api, ControlApi}, }; use crate::{ @@ -45,6 +47,7 @@ use crate::{ utils::ResponseAnyFuture, AppContext, }; +use tonic::{Status, Request}; /// Errors which can happen while processing requests to gRPC [Control API]. /// @@ -230,7 +233,7 @@ impl ControlApiService { let room_service = self.room_service.clone(); async move { let mut delete_elements_msg = DeleteElements::new(); - for id in req.take_fid().into_iter() { + for id in req.fid.into_iter() { let fid = StatefulFid::try_from(id)?; delete_elements_msg.add_fid(fid); } @@ -256,7 +259,7 @@ impl ControlApiService { let room_service = self.room_service.clone(); async move { let mut fids = Vec::new(); - for id in req.take_fid().into_iter() { + for id in req.fid.into_iter() { let fid = StatefulFid::try_from(id)?; fids.push(fid); } @@ -277,102 +280,57 @@ impl ControlApiService { } } +#[tonic::async_trait] impl ControlApi for ControlApiService { - /// Implementation for `Create` method of gRPC [Control API]. - /// - /// [Control API]: https://tinyurl.com/yxsqplq7 - fn create( - &mut self, - ctx: RpcContext, - req: CreateRequest, - sink: UnarySink, - ) { - let creating = self.create_element(req); - ctx.spawn( - async { - let mut response = CreateResponse::new(); - match creating.await { - Ok(sid) => { - response.set_sid(sid); - } - Err(e) => response.set_error(e.into()), + async fn create(&self, request: tonic::Request) -> Result, Status> { + let create_response = match self.create_element(request.into_inner()).await { + Ok(sid) => { + CreateResponse { + sid, + error: None, } - if let Err(err) = sink.success(response).compat().await { - warn!( - "Error while sending Create response by gRPC. {:?}", - err, - ) + } + Err(err) => { + CreateResponse { + sid: HashMap::new(), + error: Some(err.into()), } - Ok(()) } - .boxed() - .compat(), - ); + }; + + Ok(tonic::Response::new(create_response)) } - /// Implementation for `Delete` method of gRPC [Control API]. - /// - /// [Control API]: https://tinyurl.com/yxsqplq7 - fn delete( - &mut self, - ctx: RpcContext, - req: IdRequest, - sink: UnarySink, - ) { - let deleting = self.delete_element(req); - ctx.spawn( - async { - let mut response = Response::new(); - if let Err(e) = deleting.await { - response.set_error(e.into()); - } - if let Err(err) = sink.success(response).compat().await { - warn!( - "Error while sending response on 'Delete' request by \ - gRPC: {:?}", - err, - ) - } - Ok(()) - } - .boxed() - .compat(), - ); + async fn delete(&self, request: tonic::Request) -> Result, Status> { + let response = match self.delete_element(request.into_inner()).await { + Ok(_) => Response { + error: None, + }, + Err(e) => Response { + error: Some(e.into()) + }, + }; + + Ok(tonic::Response::new(response)) } - /// Implementation for `Get` method of gRPC [Control API]. - /// - /// [Control API]: https://tinyurl.com/yxsqplq7 - fn get( - &mut self, - ctx: RpcContext, - req: IdRequest, - sink: UnarySink, - ) { - let getting = self.get_element(req); - ctx.spawn( - async { - let mut response = GetResponse::new(); - match getting.await { - Ok(elements) => { - response.set_elements(elements); - } - Err(e) => { - response.set_error(e.into()); - } + async fn get(&self, request: tonic::Request) -> Result, Status> { + let response = match self.get_element(request.into_inner()).await { + Ok(elements) => { + GetResponse { + elements, + error: None } - if let Err(err) = sink.success(response).compat().await { - warn!( - "Error while sending response on 'Get' request by \ - gRPC: {:?}", - err - ) + } + Err(e) => { + GetResponse { + elements: HashMap::new(), + error: None, } - Ok(()) } - .boxed() - .compat(), - ); + }; + + Ok(tonic::Response::new(response)) } } @@ -380,7 +338,7 @@ impl ControlApi for ControlApiService { /// API]. /// /// [Control API]: https://tinyurl.com/yxsqplq7 -pub struct GrpcServer(Server); +pub struct GrpcServer(Option>); impl Actor for GrpcServer { type Context = Context; @@ -392,7 +350,7 @@ impl Actor for GrpcServer { } impl Handler for GrpcServer { - type Result = ResponseAnyFuture<()>; + type Result = (); fn handle( &mut self, @@ -403,44 +361,33 @@ impl Handler for GrpcServer { "gRPC Control API server received ShutdownGracefully message so \ shutting down.", ); - ResponseAnyFuture( - self.0 - .shutdown() - .compat() - .map_err(|e| { - warn!( - "Error while graceful shutdown of gRPC Control API \ - server: {:?}", - e, - ) - }) - .map(|_| ()) - .boxed_local(), - ) + if let Some(mut grpc_shutdown) = self.0.take() { + grpc_shutdown.send(()).unwrap(); + } } } /// Run gRPC [Control API] server in actix actor. /// /// [Control API]: https://tinyurl.com/yxsqplq7 -pub fn run(room_repo: Addr, app: &AppContext) -> Addr { +pub async fn run(room_repo: Addr, app: &AppContext) -> Addr { let bind_ip = app.config.server.control.grpc.bind_ip.to_string(); let bind_port = app.config.server.control.grpc.bind_port; - let cq_count = 2; let service = create_control_api(ControlApiService { public_url: app.config.server.client.http.public_url.clone(), room_service: room_repo, }); - let env = Arc::new(Environment::new(cq_count)); info!("Starting gRPC server on {}:{}", bind_ip, bind_port); - let server = ServerBuilder::new(env) - .register_service(service) - .bind(bind_ip, bind_port) - .build() + let (grpc_shutdown_tx, grpc_shutdown_rx) = futures::channel::oneshot::channel(); + + let server = Server::builder() + .add_service(service) + .serve_with_shutdown(format!("{}:{}", bind_ip, bind_port).parse().unwrap(), async move { grpc_shutdown_rx.await; }) + .await .unwrap(); - GrpcServer::start_in_arbiter(&Arbiter::new(), move |_| GrpcServer(server)) + GrpcServer::start_in_arbiter(&Arbiter::new(), move |_| GrpcServer(Some(grpc_shutdown_tx))) } diff --git a/src/api/control/member.rs b/src/api/control/member.rs index c33ea3018..01b69f6b4 100644 --- a/src/api/control/member.rs +++ b/src/api/control/member.rs @@ -5,9 +5,9 @@ use std::{collections::HashMap, convert::TryFrom}; use derive_more::{Display, From}; -use medea_control_api_proto::grpc::api::{ - CreateRequest_oneof_el as ElementProto, Member as MemberProto, - Room_Element_oneof_el as RoomElementProto, +use medea_control_api_proto::grpc::medea::{ + create_request::El as ElementProto, Member as MemberProto, + room::element::El as RoomElementProto, }; use rand::{distributions::Alphanumeric, Rng}; use serde::Deserialize; diff --git a/src/api/control/room.rs b/src/api/control/room.rs index 541460002..88a59ed65 100644 --- a/src/api/control/room.rs +++ b/src/api/control/room.rs @@ -6,8 +6,8 @@ use std::{collections::HashMap, convert::TryFrom}; use derive_more::{Display, From}; #[rustfmt::skip] -use medea_control_api_proto::grpc::api::{ - CreateRequest_oneof_el as ElementProto, +use medea_control_api_proto::grpc::medea::{ + create_request::El as ElementProto, }; use serde::Deserialize; diff --git a/src/signalling/elements/endpoints/mod.rs b/src/signalling/elements/endpoints/mod.rs index 9e27c655a..832828b00 100644 --- a/src/signalling/elements/endpoints/mod.rs +++ b/src/signalling/elements/endpoints/mod.rs @@ -5,7 +5,7 @@ pub mod webrtc; use derive_more::From; -use medea_control_api_proto::grpc::api::Element as RootElementProto; +use medea_control_api_proto::grpc::medea::Element as RootElementProto; /// Enum which can store all kinds of [Medea] endpoints. /// diff --git a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs index 5ef907ab2..5f0faeca1 100644 --- a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs @@ -6,8 +6,8 @@ use std::{ }; use medea_client_api_proto::PeerId; -use medea_control_api_proto::grpc::api::{ - Element as RootElementProto, Member_Element as ElementProto, +use medea_control_api_proto::grpc::medea::{ + Element as RootElementProto, member::Element as ElementProto, WebRtcPlayEndpoint as WebRtcPlayEndpointProto, }; diff --git a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs index 627f5b6b8..bdc9b7e7c 100644 --- a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs @@ -7,8 +7,8 @@ use std::{ }; use medea_client_api_proto::PeerId; -use medea_control_api_proto::grpc::api::{ - Element as RootElementProto, Member_Element as ElementProto, +use medea_control_api_proto::grpc::medea::{ + Element as RootElementProto, member::Element as ElementProto, WebRtcPublishEndpoint as WebRtcPublishEndpointProto, }; diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index 11a3e4300..833b2f497 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -12,9 +12,9 @@ use std::{ use derive_more::Display; use failure::Fail; use medea_client_api_proto::{IceServer, PeerId}; -use medea_control_api_proto::grpc::api::{ +use medea_control_api_proto::grpc::medea::{ Element as RootElementProto, Member as MemberProto, - Room_Element as ElementProto, + room::Element as ElementProto, }; use crate::{ diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 13c544d89..fa8ee63c9 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -15,7 +15,7 @@ use futures::future::{self, FutureExt as _, LocalBoxFuture}; use medea_client_api_proto::{ Command, CommandHandler, Event, IceCandidate, PeerId, PeerMetrics, TrackId, }; -use medea_control_api_proto::grpc::api::{ +use medea_control_api_proto::grpc::medea::{ Element as ElementProto, Room as RoomProto, }; diff --git a/src/signalling/room_service.rs b/src/signalling/room_service.rs index a97adb73a..f21fe4ac4 100644 --- a/src/signalling/room_service.rs +++ b/src/signalling/room_service.rs @@ -10,7 +10,7 @@ use failure::Fail; use futures::future::{ self, FutureExt as _, LocalBoxFuture, TryFutureExt as _, }; -use medea_control_api_proto::grpc::api::Element as ElementProto; +use medea_control_api_proto::grpc::medea::Element as ElementProto; use crate::{ api::control::{ From ec6a76cb08830ca31b920232dd35b55356e217b7 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Fri, 24 Jan 2020 21:22:17 +0300 Subject: [PATCH 002/224] Update rustfmt [run ci] --- Cargo.lock | 70 +++++++------- proto/control-api/build.rs | 12 +-- src/api/control/callback/mod.rs | 6 +- .../endpoints/webrtc_publish_endpoint.rs | 2 +- src/api/control/grpc/server.rs | 94 ++++++++++--------- src/api/control/member.rs | 4 +- .../endpoints/webrtc/play_endpoint.rs | 2 +- .../endpoints/webrtc/publish_endpoint.rs | 2 +- src/signalling/elements/member.rs | 4 +- 9 files changed, 100 insertions(+), 96 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index afaa81162..ee7c46b65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,7 +44,7 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix_derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -77,7 +77,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -169,7 +169,7 @@ dependencies = [ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -194,7 +194,7 @@ dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -219,7 +219,7 @@ dependencies = [ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -449,7 +449,7 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -485,7 +485,7 @@ dependencies = [ "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -509,7 +509,7 @@ dependencies = [ "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web-codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -520,7 +520,7 @@ dependencies = [ "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -535,7 +535,7 @@ dependencies = [ "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -708,7 +708,7 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -723,7 +723,7 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -731,7 +731,7 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -822,7 +822,7 @@ dependencies = [ [[package]] name = "bytes" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -830,7 +830,7 @@ name = "bytestring" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -913,7 +913,7 @@ dependencies = [ "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde-hjson 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1477,7 +1477,7 @@ name = "h2" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1544,7 +1544,7 @@ name = "http" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1554,7 +1554,7 @@ name = "http-body" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1585,7 +1585,7 @@ name = "hyper" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1809,7 +1809,7 @@ dependencies = [ "redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1834,7 +1834,7 @@ dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "medea-macro 0.2.0-dev", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1883,7 +1883,7 @@ dependencies = [ "mockall 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "tracerr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2301,7 +2301,7 @@ name = "prost" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2310,7 +2310,7 @@ name = "prost-build" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2339,7 +2339,7 @@ name = "prost-types" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2545,7 +2545,7 @@ name = "redis" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2718,7 +2718,7 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2840,7 +2840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3055,7 +3055,7 @@ name = "tokio" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3194,7 +3194,7 @@ name = "tokio-util" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3218,7 +3218,7 @@ dependencies = [ "async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3647,7 +3647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3909,7 +3909,7 @@ dependencies = [ "checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" +"checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" "checksum bytestring 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fc267467f58ef6cc8874064c62a0423eb0d099362c8a23edd1c6d044f46eead4" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" @@ -4111,7 +4111,7 @@ dependencies = [ "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde-hjson 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" +"checksum serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "eab8f15f15d6c41a154c1b128a22f2dfabe350ef53c40953d84e36155c91192b" "checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" "checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" diff --git a/proto/control-api/build.rs b/proto/control-api/build.rs index e3bba248c..2421b201e 100644 --- a/proto/control-api/build.rs +++ b/proto/control-api/build.rs @@ -45,12 +45,12 @@ mod grpc { .build_client(true) .build_server(true) .compile(&grpc_spec_files, &[GRPC_DIR.to_string()])?; -// protoc_grpcio::compile_grpc_protos( -// &grpc_spec_files, -// &[GRPC_DIR], -// &GRPC_DIR, -// None, -// )?; + // protoc_grpcio::compile_grpc_protos( + // &grpc_spec_files, + // &[GRPC_DIR], + // &GRPC_DIR, + // None, + // )?; break; } else { panic!("{}", e); diff --git a/src/api/control/callback/mod.rs b/src/api/control/callback/mod.rs index 8ac78d090..1fe2db940 100644 --- a/src/api/control/callback/mod.rs +++ b/src/api/control/callback/mod.rs @@ -7,9 +7,9 @@ pub mod url; use chrono::{DateTime, Utc}; use derive_more::From; use medea_control_api_proto::grpc::medea_callback::{ - OnJoin as OnJoinProto, OnJoin, OnLeave as OnLeaveProto, - on_leave::Reason as OnLeaveReasonProto, Request as CallbackRequestProto, - request::Event as RequestOneofEventProto, + on_leave::Reason as OnLeaveReasonProto, + request::Event as RequestOneofEventProto, OnJoin as OnJoinProto, OnJoin, + OnLeave as OnLeaveProto, Request as CallbackRequestProto, }; use crate::api::control::refs::StatefulFid; diff --git a/src/api/control/endpoints/webrtc_publish_endpoint.rs b/src/api/control/endpoints/webrtc_publish_endpoint.rs index 01449c26b..9bf194fe5 100644 --- a/src/api/control/endpoints/webrtc_publish_endpoint.rs +++ b/src/api/control/endpoints/webrtc_publish_endpoint.rs @@ -6,8 +6,8 @@ use derive_more::{Display, From, Into}; use serde::Deserialize; use medea_control_api_proto::grpc::medea::{ - WebRtcPublishEndpoint as WebRtcPublishEndpointProto, web_rtc_publish_endpoint::P2p as WebRtcPublishEndpointP2pProto, + WebRtcPublishEndpoint as WebRtcPublishEndpointProto, }; /// ID of [`WebRtcPublishEndpoint`]. diff --git a/src/api/control/grpc/server.rs b/src/api/control/grpc/server.rs index 7add10cd8..1a9fdafe8 100644 --- a/src/api/control/grpc/server.rs +++ b/src/api/control/grpc/server.rs @@ -15,16 +15,12 @@ use futures::{ compat::Future01CompatExt as _, future::{self, BoxFuture, FutureExt as _, TryFutureExt as _}, }; -use tonic::{ - transport::Server -}; -use medea_control_api_proto::grpc::{ - medea::{ - CreateRequest, create_request::El as CreateRequestOneof, - CreateResponse, Element, GetResponse, IdRequest, Response, - control_api_server::{ControlApi, ControlApiServer}, - }, +use medea_control_api_proto::grpc::medea::{ + control_api_server::{ControlApi, ControlApiServer}, + create_request::El as CreateRequestOneof, + CreateRequest, CreateResponse, Element, GetResponse, IdRequest, Response, }; +use tonic::transport::Server; use crate::{ api::control::{ @@ -47,7 +43,7 @@ use crate::{ utils::ResponseAnyFuture, AppContext, }; -use tonic::{Status, Request}; +use tonic::{Request, Status}; /// Errors which can happen while processing requests to gRPC [Control API]. /// @@ -282,52 +278,49 @@ impl ControlApiService { #[tonic::async_trait] impl ControlApi for ControlApiService { - async fn create(&self, request: tonic::Request) -> Result, Status> { - let create_response = match self.create_element(request.into_inner()).await { - Ok(sid) => { - CreateResponse { - sid, - error: None, - } - } - Err(err) => { - CreateResponse { + async fn create( + &self, + request: tonic::Request, + ) -> Result, Status> { + let create_response = + match self.create_element(request.into_inner()).await { + Ok(sid) => CreateResponse { sid, error: None }, + Err(err) => CreateResponse { sid: HashMap::new(), error: Some(err.into()), - } - } - }; + }, + }; Ok(tonic::Response::new(create_response)) } - async fn delete(&self, request: tonic::Request) -> Result, Status> { + async fn delete( + &self, + request: tonic::Request, + ) -> Result, Status> { let response = match self.delete_element(request.into_inner()).await { - Ok(_) => Response { - error: None, - }, + Ok(_) => Response { error: None }, Err(e) => Response { - error: Some(e.into()) + error: Some(e.into()), }, }; Ok(tonic::Response::new(response)) } - async fn get(&self, request: tonic::Request) -> Result, Status> { + async fn get( + &self, + request: tonic::Request, + ) -> Result, Status> { let response = match self.get_element(request.into_inner()).await { - Ok(elements) => { - GetResponse { - elements, - error: None - } - } - Err(e) => { - GetResponse { - elements: HashMap::new(), - error: None, - } - } + Ok(elements) => GetResponse { + elements, + error: None, + }, + Err(e) => GetResponse { + elements: HashMap::new(), + error: None, + }, }; Ok(tonic::Response::new(response)) @@ -370,7 +363,10 @@ impl Handler for GrpcServer { /// Run gRPC [Control API] server in actix actor. /// /// [Control API]: https://tinyurl.com/yxsqplq7 -pub async fn run(room_repo: Addr, app: &AppContext) -> Addr { +pub async fn run( + room_repo: Addr, + app: &AppContext, +) -> Addr { let bind_ip = app.config.server.control.grpc.bind_ip.to_string(); let bind_port = app.config.server.control.grpc.bind_port; @@ -381,13 +377,21 @@ pub async fn run(room_repo: Addr, app: &AppContext) -> Addr Date: Mon, 27 Jan 2020 13:40:43 +0300 Subject: [PATCH 003/224] Fix medea --- src/api/control/callback/clients/grpc.rs | 19 +++-- src/api/control/callback/clients/mod.rs | 8 ++- src/api/control/callback/mod.rs | 29 ++++---- src/api/control/callback/service.rs | 38 +++++----- .../control/endpoints/webrtc_play_endpoint.rs | 4 +- .../endpoints/webrtc_publish_endpoint.rs | 19 ++--- src/api/control/error_codes.rs | 26 +++---- src/api/control/grpc/server.rs | 22 +++--- src/api/control/member.rs | 10 +-- src/api/control/room.rs | 12 ++-- src/main.rs | 3 +- .../endpoints/webrtc/play_endpoint.rs | 36 ++++++---- .../endpoints/webrtc/publish_endpoint.rs | 38 ++++++---- src/signalling/elements/member.rs | 69 ++++++++++--------- src/signalling/room.rs | 25 ++++--- 15 files changed, 197 insertions(+), 161 deletions(-) diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index ba420e2ca..8816d224b 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -17,12 +17,13 @@ use crate::api::control::callback::{ url::GrpcCallbackUrl, CallbackRequest, }; -use tonic::transport::Channel; +use std::sync::Mutex; +use tonic::{transport::Channel, IntoRequest}; /// gRPC client for sending [`CallbackRequest`]s. pub struct GrpcCallbackClient { /// [`grpcio`] gRPC client of Control API Callback service. - client: ProtoCallbackClient, + client: Arc>>, } impl fmt::Debug for GrpcCallbackClient { @@ -40,7 +41,9 @@ impl GrpcCallbackClient { /// provided [`GrpcCallbackUrl`]. pub async fn new(addr: &GrpcCallbackUrl) -> Self { let addr = addr.addr().to_string(); - let client = ProtoCallbackClient::connect(addr).await.unwrap(); + let client = Arc::new(Mutex::new( + ProtoCallbackClient::connect(addr).await.unwrap(), + )); Self { client } } @@ -51,9 +54,13 @@ impl CallbackClient for GrpcCallbackClient { &self, request: CallbackRequest, ) -> LocalBoxFuture<'static, Result<(), CallbackClientError>> { - let request = self.client.on_event_async(&request.into()); - async { - request?.compat().await?; + let client = Arc::clone(&self.client); + async move { + client + .lock() + .unwrap() + .on_event(tonic::Request::new(request.into())) + .await?; Ok(()) } .boxed_local() diff --git a/src/api/control/callback/clients/mod.rs b/src/api/control/callback/clients/mod.rs index 2c8a50fd1..8f916dc6a 100644 --- a/src/api/control/callback/clients/mod.rs +++ b/src/api/control/callback/clients/mod.rs @@ -25,14 +25,16 @@ pub trait CallbackClient: Debug + Send + Sync { #[derive(Debug, From)] pub enum CallbackClientError { /// [`grpcio`] failed to send [`CallbackRequest`]. - Grpcio(grpcio::Error), + Tonic(tonic::Status), } /// Creates [`CallbackClient`] basing on provided [`CallbackUrl`]. #[inline] -pub fn build_client(url: &CallbackUrl) -> impl CallbackClient { +pub async fn build_client(url: &CallbackUrl) -> impl CallbackClient { info!("Creating CallbackClient for url: {}", url); match &url { - CallbackUrl::Grpc(grpc_url) => grpc::GrpcCallbackClient::new(grpc_url), + CallbackUrl::Grpc(grpc_url) => { + grpc::GrpcCallbackClient::new(grpc_url).await + } } } diff --git a/src/api/control/callback/mod.rs b/src/api/control/callback/mod.rs index 1fe2db940..9c7a25a70 100644 --- a/src/api/control/callback/mod.rs +++ b/src/api/control/callback/mod.rs @@ -30,9 +30,10 @@ impl OnLeaveEvent { impl Into for OnLeaveEvent { fn into(self) -> OnLeaveProto { - let mut proto = OnLeaveProto::new(); - proto.set_reason(self.reason.into()); - proto + let on_leave: OnLeaveReasonProto = self.reason.into(); + OnLeaveProto { + reason: on_leave as i32, + } } } @@ -52,9 +53,9 @@ pub enum OnLeaveReason { impl Into for OnLeaveReason { fn into(self) -> OnLeaveReasonProto { match self { - Self::LostConnection => OnLeaveReasonProto::LOST_CONNECTION, - Self::ServerShutdown => OnLeaveReasonProto::SERVER_SHUTDOWN, - Self::Disconnected => OnLeaveReasonProto::DISCONNECTED, + Self::LostConnection => OnLeaveReasonProto::LostConnection, + Self::ServerShutdown => OnLeaveReasonProto::ServerShutdown, + Self::Disconnected => OnLeaveReasonProto::Disconnected, } } } @@ -65,7 +66,7 @@ pub struct OnJoinEvent; impl Into for OnJoinEvent { fn into(self) -> OnJoin { - OnJoinProto::new() + OnJoinProto {} } } @@ -80,10 +81,10 @@ impl Into for CallbackEvent { fn into(self) -> RequestOneofEventProto { match self { Self::OnJoin(on_join) => { - RequestOneofEventProto::on_join(on_join.into()) + RequestOneofEventProto::OnJoin(on_join.into()) } Self::OnLeave(on_leave) => { - RequestOneofEventProto::on_leave(on_leave.into()) + RequestOneofEventProto::OnLeave(on_leave.into()) } } } @@ -121,10 +122,10 @@ impl CallbackRequest { impl Into for CallbackRequest { fn into(self) -> CallbackRequestProto { - let mut proto = CallbackRequestProto::new(); - proto.event = Some(self.event.into()); - proto.set_fid(self.fid.to_string()); - proto.set_at(self.at.to_rfc3339()); - proto + CallbackRequestProto { + event: Some(self.event.into()), + fid: self.fid.to_string(), + at: self.at.to_rfc3339(), + } } } diff --git a/src/api/control/callback/service.rs b/src/api/control/callback/service.rs index cbf997c58..45a33e737 100644 --- a/src/api/control/callback/service.rs +++ b/src/api/control/callback/service.rs @@ -37,33 +37,35 @@ impl CallbackService { /// Will use existing [`CallbackClient`] or create new. // TODO: Add buffering and resending for failed 'Callback' sends. // https://github.com/instrumentisto/medea/issues/61 - pub fn send_callback>( + pub fn send_callback + 'static>( &self, callback_url: CallbackUrl, fid: StatefulFid, event: T, ) { - let req = CallbackRequest::new(fid, event.into()); - info!("Sending CallbackRequest [{:?}] to [{}]", req, callback_url); + let inner = self.0.clone(); + Arbiter::spawn(async move { + let req = CallbackRequest::new(fid, event.into()); + info!("Sending CallbackRequest [{:?}] to [{}]", req, callback_url); - let read_lock = self.0.read().unwrap(); - let send_request = if let Some(client) = read_lock.get(&callback_url) { - client.send(req) - } else { - drop(read_lock); - let new_client = build_client(&callback_url); - let send = new_client.send(req); - self.0 - .write() - .unwrap() - .insert(callback_url, Box::new(new_client)); - send - }; + let read_lock = inner.read().unwrap(); + let send_request = + if let Some(client) = read_lock.get(&callback_url) { + client.send(req) + } else { + drop(read_lock); + let new_client = build_client(&callback_url).await; + let send = new_client.send(req); + inner + .write() + .unwrap() + .insert(callback_url, Box::new(new_client)); + send + }; - Arbiter::spawn(async { if let Err(e) = send_request.await { error!("Failed to send callback because {:?}.", e); } - }); + }) } } diff --git a/src/api/control/endpoints/webrtc_play_endpoint.rs b/src/api/control/endpoints/webrtc_play_endpoint.rs index 4f5bc12f9..5d7d140df 100644 --- a/src/api/control/endpoints/webrtc_play_endpoint.rs +++ b/src/api/control/endpoints/webrtc_play_endpoint.rs @@ -33,8 +33,8 @@ impl TryFrom<&WebRtcPlayEndpointProto> for WebRtcPlayEndpoint { fn try_from(value: &WebRtcPlayEndpointProto) -> Result { Ok(Self { - src: SrcUri::try_from(value.get_src().to_owned())?, - force_relay: value.get_force_relay(), + src: SrcUri::try_from(value.src.clone())?, + force_relay: value.force_relay, }) } } diff --git a/src/api/control/endpoints/webrtc_publish_endpoint.rs b/src/api/control/endpoints/webrtc_publish_endpoint.rs index 9bf194fe5..9622c2c2a 100644 --- a/src/api/control/endpoints/webrtc_publish_endpoint.rs +++ b/src/api/control/endpoints/webrtc_publish_endpoint.rs @@ -32,9 +32,9 @@ pub enum P2pMode { impl From for P2pMode { fn from(value: WebRtcPublishEndpointP2pProto) -> Self { match value { - WebRtcPublishEndpointP2pProto::ALWAYS => Self::Always, - WebRtcPublishEndpointP2pProto::IF_POSSIBLE => Self::IfPossible, - WebRtcPublishEndpointP2pProto::NEVER => Self::Never, + WebRtcPublishEndpointP2pProto::Always => Self::Always, + WebRtcPublishEndpointP2pProto::IfPossible => Self::IfPossible, + WebRtcPublishEndpointP2pProto::Never => Self::Never, } } } @@ -42,9 +42,9 @@ impl From for P2pMode { impl Into for P2pMode { fn into(self) -> WebRtcPublishEndpointP2pProto { match self { - Self::Always => WebRtcPublishEndpointP2pProto::ALWAYS, - Self::IfPossible => WebRtcPublishEndpointP2pProto::IF_POSSIBLE, - Self::Never => WebRtcPublishEndpointP2pProto::NEVER, + Self::Always => WebRtcPublishEndpointP2pProto::Always, + Self::IfPossible => WebRtcPublishEndpointP2pProto::IfPossible, + Self::Never => WebRtcPublishEndpointP2pProto::Never, } } } @@ -64,8 +64,11 @@ pub struct WebRtcPublishEndpoint { impl From<&WebRtcPublishEndpointProto> for WebRtcPublishEndpoint { fn from(value: &WebRtcPublishEndpointProto) -> Self { Self { - p2p: P2pMode::from(value.get_p2p()), - force_relay: value.get_force_relay(), + p2p: P2pMode::from( + WebRtcPublishEndpointP2pProto::from_i32(value.p2p) + .unwrap_or_default(), + ), + force_relay: value.force_relay, } } } diff --git a/src/api/control/error_codes.rs b/src/api/control/error_codes.rs index 7481f9422..9c9a9f52d 100644 --- a/src/api/control/error_codes.rs +++ b/src/api/control/error_codes.rs @@ -103,24 +103,18 @@ impl ErrorResponse { impl Into for ErrorResponse { fn into(self) -> ErrorProto { - let mut error = ErrorProto::new(); - - if let Some(additional_text) = &self.explanation { - error.set_text(format!( - "{} {}", - self.error_code.to_string(), - additional_text - )); + let text = if let Some(additional_text) = &self.explanation { + format!("{} {}", self.error_code.to_string(), additional_text) } else { - error.set_text(self.error_code.to_string()); + self.error_code.to_string() + }; + + ErrorProto { + doc: String::new(), + text, + element: self.element_id.unwrap_or_default(), + code: self.error_code as u32, } - - if let Some(id) = self.element_id { - error.set_element(id); - } - error.set_code(self.error_code as u32); - - error } } diff --git a/src/api/control/grpc/server.rs b/src/api/control/grpc/server.rs index 1a9fdafe8..a5e3e0c82 100644 --- a/src/api/control/grpc/server.rs +++ b/src/api/control/grpc/server.rs @@ -16,7 +16,9 @@ use futures::{ future::{self, BoxFuture, FutureExt as _, TryFutureExt as _}, }; use medea_control_api_proto::grpc::medea::{ - control_api_server::{ControlApi, ControlApiServer}, + control_api_server::{ + ControlApi, ControlApiServer as TonicControlApiServer, + }, create_request::El as CreateRequestOneof, CreateRequest, CreateResponse, Element, GetResponse, IdRequest, Response, }; @@ -34,6 +36,7 @@ use crate::{ EndpointId, EndpointSpec, MemberId, MemberSpec, RoomSpec, TryFromProtobufError, }, + conf::server::ControlApiServer, log::prelude::*, shutdown::ShutdownGracefully, signalling::room_service::{ @@ -140,7 +143,7 @@ impl ControlApiService { &self, mut req: CreateRequest, ) -> BoxFuture<'static, Result> { - let unparsed_parent_fid = req.take_parent_fid(); + let unparsed_parent_fid = req.parent_fid; let elem = if let Some(elem) = req.el { elem } else { @@ -167,8 +170,8 @@ impl ControlApiService { match parent_fid { StatefulFid::Room(parent_fid) => match elem { - CreateRequestOneof::member(mut member) => { - let id: MemberId = member.take_id().into(); + CreateRequestOneof::Member(mut member) => { + let id: MemberId = member.id.clone().into(); match MemberSpec::try_from(member) .map_err(ErrorResponse::from) { @@ -187,15 +190,15 @@ impl ControlApiService { }, StatefulFid::Member(parent_fid) => { let (endpoint, id) = match elem { - CreateRequestOneof::webrtc_play(mut play) => ( + CreateRequestOneof::WebrtcPlay(mut play) => ( WebRtcPlayEndpoint::try_from(&play) .map(EndpointSpec::from), - play.take_id().into(), + play.id.into(), ), - CreateRequestOneof::webrtc_pub(mut publish) => ( + CreateRequestOneof::WebrtcPub(mut publish) => ( Ok(WebRtcPublishEndpoint::from(&publish)) .map(EndpointSpec::from), - publish.take_id().into(), + publish.id.into(), ), _ => { return future::err(ErrorResponse::new( @@ -337,7 +340,6 @@ impl Actor for GrpcServer { type Context = Context; fn started(&mut self, _ctx: &mut Self::Context) { - self.0.start(); info!("gRPC Control API server started."); } } @@ -370,7 +372,7 @@ pub async fn run( let bind_ip = app.config.server.control.grpc.bind_ip.to_string(); let bind_port = app.config.server.control.grpc.bind_port; - let service = create_control_api(ControlApiService { + let service = TonicControlApiServer::new(ControlApiService { public_url: app.config.server.client.http.public_url.clone(), room_service: room_repo, }); diff --git a/src/api/control/member.rs b/src/api/control/member.rs index 5df8d69d7..70c0e49e9 100644 --- a/src/api/control/member.rs +++ b/src/api/control/member.rs @@ -150,7 +150,7 @@ impl TryFrom for MemberSpec { fn try_from(mut member: MemberProto) -> Result { let mut pipeline = HashMap::new(); - for (id, member_element) in member.take_pipeline() { + for (id, member_element) in member.pipeline { if let Some(elem) = member_element.el { let endpoint = EndpointSpec::try_from((EndpointId(id.clone()), elem))?; @@ -160,13 +160,13 @@ impl TryFrom for MemberSpec { } } - let mut credentials = member.take_credentials(); + let mut credentials = member.credentials; if credentials.is_empty() { credentials = generate_member_credentials(); } let on_leave = { - let on_leave = member.take_on_leave(); + let on_leave = member.on_leave; if on_leave.is_empty() { None } else { @@ -174,7 +174,7 @@ impl TryFrom for MemberSpec { } }; let on_join = { - let on_join = member.take_on_join(); + let on_join = member.on_join; if on_join.is_empty() { None } else { @@ -200,7 +200,7 @@ macro_rules! impl_try_from_proto_for_member { (id, proto): (Id, $proto), ) -> Result { match proto { - $proto::member(member) => Self::try_from(member), + $proto::Member(member) => Self::try_from(member), _ => Err(TryFromProtobufError::ExpectedOtherElement( String::from("Member"), id.to_string(), diff --git a/src/api/control/room.rs b/src/api/control/room.rs index 88a59ed65..cdbff4780 100644 --- a/src/api/control/room.rs +++ b/src/api/control/room.rs @@ -59,9 +59,9 @@ impl TryFrom for RoomSpec { fn try_from(proto: ElementProto) -> Result { let id = match proto { - ElementProto::room(mut room) => { + ElementProto::Room(mut room) => { let mut pipeline = HashMap::new(); - for (id, room_element) in room.take_pipeline() { + for (id, room_element) in room.pipeline { if let Some(elem) = room_element.el { let member = MemberSpec::try_from((MemberId(id.clone()), elem))?; @@ -73,13 +73,13 @@ impl TryFrom for RoomSpec { let pipeline = Pipeline::new(pipeline); return Ok(Self { - id: room.take_id().into(), + id: room.id.into(), pipeline, }); } - ElementProto::member(mut member) => member.take_id(), - ElementProto::webrtc_pub(mut webrtc_pub) => webrtc_pub.take_id(), - ElementProto::webrtc_play(mut webrtc_play) => webrtc_play.take_id(), + ElementProto::Member(mut member) => member.id, + ElementProto::WebrtcPub(mut webrtc_pub) => webrtc_pub.id, + ElementProto::WebrtcPlay(mut webrtc_play) => webrtc_play.id, }; Err(TryFromProtobufError::ExpectedOtherElement( diff --git a/src/main.rs b/src/main.rs index 6b435fea4..007e366b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,7 +47,8 @@ fn main() -> Result<(), Error> { medea::api::control::start_static_rooms(&room_service).await?; - let grpc_server = grpc::server::run(room_service, &app_context); + let grpc_server = + grpc::server::run(room_service, &app_context).await; let server = Server::run(room_repo, config)?; shutdown::subscribe( diff --git a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs index a71909855..ffd60c8ee 100644 --- a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs @@ -7,8 +7,9 @@ use std::{ use medea_client_api_proto::PeerId; use medea_control_api_proto::grpc::medea::{ - member::Element as ElementProto, Element as RootElementProto, - WebRtcPlayEndpoint as WebRtcPlayEndpointProto, + element::El as RootElProto, + member::{element::El as MemberElProto, Element as ElementProto}, + Element as RootElementProto, WebRtcPlayEndpoint as WebRtcPlayEndpointProto, }; use crate::{ @@ -22,6 +23,7 @@ use crate::{ }; use super::publish_endpoint::WebRtcPublishEndpoint; +use crate::api::control::RootElement; #[derive(Debug, Clone)] struct WebRtcPlayEndpointInner { @@ -209,24 +211,28 @@ impl WeakWebRtcPlayEndpoint { impl Into for WebRtcPlayEndpoint { fn into(self) -> ElementProto { - let mut element = ElementProto::new(); - let mut play = WebRtcPlayEndpointProto::new(); - play.set_src(self.src_uri().to_string()); - play.set_id(self.id().to_string()); - play.set_force_relay(self.is_force_relayed()); - element.set_webrtc_play(play); + ElementProto { + el: Some(MemberElProto::WebrtcPlay(self.into())), + } + } +} - element +impl Into for WebRtcPlayEndpoint { + fn into(self) -> WebRtcPlayEndpointProto { + WebRtcPlayEndpointProto { + on_start: String::new(), + on_stop: String::new(), + src: self.src_uri().to_string(), + id: self.id().to_string(), + force_relay: self.is_force_relayed(), + } } } impl Into for WebRtcPlayEndpoint { fn into(self) -> RootElementProto { - let mut element = RootElementProto::new(); - let mut member_element: ElementProto = self.into(); - let endpoint = member_element.take_webrtc_play(); - element.set_webrtc_play(endpoint); - - element + RootElementProto { + el: Some(RootElProto::WebrtcPlay(self.into())), + } } } diff --git a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs index e7e7b235b..13d50d654 100644 --- a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs @@ -8,7 +8,10 @@ use std::{ use medea_client_api_proto::PeerId; use medea_control_api_proto::grpc::medea::{ - member::Element as ElementProto, Element as RootElementProto, + element::El as RootElProto, + member::{element::El as MemberElProto, Element as ElementProto}, + web_rtc_publish_endpoint::P2p as WebRtcPublishEndpointP2pProto, + Element as RootElementProto, WebRtcPublishEndpoint as WebRtcPublishEndpointProto, }; @@ -23,6 +26,7 @@ use crate::{ }; use super::play_endpoint::WebRtcPlayEndpoint; +use crate::api::control::error_codes::ErrorCode::ElementIdIsNotLocal; #[derive(Clone, Debug)] struct WebRtcPublishEndpointInner { @@ -242,25 +246,31 @@ impl WeakWebRtcPublishEndpoint { } } +impl Into for WebRtcPublishEndpoint { + fn into(self) -> WebRtcPublishEndpointProto { + let p2p: WebRtcPublishEndpointP2pProto = self.p2p().into(); + WebRtcPublishEndpointProto { + p2p: p2p as i32, + id: self.id().to_string(), + force_relay: self.is_force_relayed(), + on_stop: String::new(), + on_start: String::new(), + } + } +} + impl Into for WebRtcPublishEndpoint { fn into(self) -> ElementProto { - let mut element = ElementProto::new(); - let mut publish = WebRtcPublishEndpointProto::new(); - publish.set_p2p(self.p2p().into()); - publish.set_id(self.id().to_string()); - publish.set_force_relay(self.is_force_relayed()); - element.set_webrtc_pub(publish); - - element + ElementProto { + el: Some(MemberElProto::WebrtcPub(self.into())), + } } } impl Into for WebRtcPublishEndpoint { fn into(self) -> RootElementProto { - let mut element = RootElementProto::new(); - let mut member_element: ElementProto = self.into(); - let endpoint = member_element.take_webrtc_pub(); - element.set_webrtc_pub(endpoint); - element + RootElementProto { + el: Some(RootElProto::WebrtcPub(self.into())), + } } } diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index 66eefb28d..70b0aa73e 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -13,8 +13,9 @@ use derive_more::Display; use failure::Fail; use medea_client_api_proto::{IceServer, PeerId}; use medea_control_api_proto::grpc::medea::{ - room::Element as ElementProto, Element as RootElementProto, - Member as MemberProto, + element::El as RootElProto, + room::{element::El as RoomElProto, Element as ElementProto}, + Element as RootElementProto, Member as MemberProto, }; use crate::{ @@ -33,6 +34,7 @@ use super::endpoints::{ webrtc::{WebRtcPlayEndpoint, WebRtcPublishEndpoint}, Endpoint, }; +use futures::AsyncReadExt; /// Errors which may occur while loading [`Member`]s from [`RoomSpec`]. #[derive(Debug, Display, Fail)] @@ -509,44 +511,47 @@ pub fn parse_members( Ok(members) } -impl Into for Member { - fn into(self) -> ElementProto { - let mut element = ElementProto::new(); - let mut member = MemberProto::new(); - - let mut member_pipeline = HashMap::new(); - for (id, play) in self.sinks() { - member_pipeline.insert(id.to_string(), play.into()); - } - for (id, publish) in self.srcs() { - member_pipeline.insert(id.to_string(), publish.into()); +impl Into for Member { + fn into(self) -> MemberProto { + let member_pipeline = self + .sinks() + .into_iter() + .map(|(id, play)| (id.to_string(), play.into())) + .chain( + self.srcs() + .into_iter() + .map(|(id, publish)| (id.to_string(), publish.into())), + ) + .collect(); + MemberProto { + id: self.id().to_string(), + credentials: self.credentials(), + on_leave: self + .get_on_leave() + .map(|c| c.to_string()) + .unwrap_or_default(), + on_join: self + .get_on_join() + .map(|c| c.to_string()) + .unwrap_or_default(), + pipeline: member_pipeline, } - member.set_pipeline(member_pipeline); + } +} - member.set_id(self.id().to_string()); - member.set_credentials(self.credentials()); - if let Some(on_leave) = self.get_on_leave() { - member.set_on_leave(on_leave.to_string()); - } - if let Some(on_join) = self.get_on_join() { - member.set_on_join(on_join.to_string()); +impl Into for Member { + fn into(self) -> ElementProto { + ElementProto { + el: Some(RoomElProto::Member(self.into())), } - - element.set_member(member); - - element } } impl Into for Member { fn into(self) -> RootElementProto { - let mut member_element: ElementProto = self.into(); - let member = member_element.take_member(); - - let mut element = RootElementProto::new(); - element.set_member(member); - - element + RootElementProto { + el: Some(RootElProto::Member(self.into())), + } } } diff --git a/src/signalling/room.rs b/src/signalling/room.rs index fa8ee63c9..6c20f92ae 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -16,7 +16,7 @@ use medea_client_api_proto::{ Command, CommandHandler, Event, IceCandidate, PeerId, PeerMetrics, TrackId, }; use medea_control_api_proto::grpc::medea::{ - Element as ElementProto, Room as RoomProto, + element::El as RootElProto, Element as ElementProto, Room as RoomProto, }; use crate::{ @@ -927,23 +927,26 @@ impl Actor for Room { } } -impl Into for &mut Room { - fn into(self) -> ElementProto { - let mut element = ElementProto::new(); - let mut room = RoomProto::new(); - +impl Into for &mut Room { + fn into(self) -> RoomProto { let pipeline = self .members .members() .into_iter() .map(|(id, member)| (id.to_string(), member.into())) .collect(); + RoomProto { + id: self.id().to_string(), + pipeline, + } + } +} - room.set_pipeline(pipeline); - room.set_id(self.id().to_string()); - element.set_room(room); - - element +impl Into for &mut Room { + fn into(self) -> ElementProto { + ElementProto { + el: Some(RootElProto::Room(self.into())), + } } } From ecfd202dac374eda3aec247c692ef01eb9097983 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 27 Jan 2020 14:10:18 +0300 Subject: [PATCH 004/224] Fix protos convertations in medea-control-api-mock --- mock/control-api/src/api/endpoint.rs | 74 +++++++++++++------------ mock/control-api/src/api/member.rs | 73 +++++++++--------------- mock/control-api/src/api/mod.rs | 56 +++++++++---------- mock/control-api/src/api/room.rs | 48 ++++++++-------- mock/control-api/src/callback/mod.rs | 28 +++++----- mock/control-api/src/callback/server.rs | 5 +- mock/control-api/src/client.rs | 2 +- 7 files changed, 134 insertions(+), 152 deletions(-) diff --git a/mock/control-api/src/api/endpoint.rs b/mock/control-api/src/api/endpoint.rs index ee4a8329f..13842a38a 100644 --- a/mock/control-api/src/api/endpoint.rs +++ b/mock/control-api/src/api/endpoint.rs @@ -1,11 +1,12 @@ //! `Endpoint` related methods and entities. -use medea_control_api_proto::grpc::api::{ - Member_Element as MemberElementProto, - Member_Element_oneof_el as MemberElementOneOfEl, +use medea_control_api_proto::grpc::medea::{ + member::{ + element::El as MemberElementOneOfEl, Element as MemberElementProto, + }, + web_rtc_publish_endpoint::P2p as P2pModeProto, WebRtcPlayEndpoint as WebRtcPlayEndpointProto, WebRtcPublishEndpoint as WebRtcPublishEndpointProto, - WebRtcPublishEndpoint_P2P as P2pModeProto, }; use serde::{Deserialize, Serialize}; @@ -20,9 +21,9 @@ pub enum P2pMode { impl Into for P2pMode { fn into(self) -> P2pModeProto { match self { - Self::Always => P2pModeProto::ALWAYS, - Self::IfPossible => P2pModeProto::IF_POSSIBLE, - Self::Never => P2pModeProto::NEVER, + Self::Always => P2pModeProto::Always, + Self::IfPossible => P2pModeProto::IfPossible, + Self::Never => P2pModeProto::Never, } } } @@ -30,9 +31,9 @@ impl Into for P2pMode { impl From for P2pMode { fn from(proto: P2pModeProto) -> Self { match proto { - P2pModeProto::ALWAYS => Self::Always, - P2pModeProto::IF_POSSIBLE => Self::IfPossible, - P2pModeProto::NEVER => Self::Never, + P2pModeProto::Always => Self::Always, + P2pModeProto::IfPossible => Self::IfPossible, + P2pModeProto::Never => Self::Never, } } } @@ -58,20 +59,23 @@ impl WebRtcPublishEndpoint { /// [`WebRtcPublishEndpointProto`]. #[must_use] pub fn into_proto(self, id: String) -> WebRtcPublishEndpointProto { - let mut proto = WebRtcPublishEndpointProto::new(); - proto.set_id(id); - proto.set_p2p(self.p2p.into()); - proto.set_force_relay(self.force_relay); - proto + let p2p: P2pModeProto = self.p2p.into(); + WebRtcPublishEndpointProto { + id, + p2p: p2p as i32, + force_relay: self.force_relay, + on_start: String::new(), + on_stop: String::new(), + } } } impl From for WebRtcPublishEndpoint { fn from(mut proto: WebRtcPublishEndpointProto) -> Self { Self { - id: proto.take_id(), - p2p: proto.get_p2p().into(), - force_relay: proto.get_force_relay(), + id: proto.id, + p2p: P2pModeProto::from_i32(proto.p2p).unwrap_or_default().into(), + force_relay: proto.force_relay, } } } @@ -98,20 +102,22 @@ impl WebRtcPlayEndpoint { /// [`WebRtcPlayEndpointProto`]. #[must_use] pub fn into_proto(self, id: String) -> WebRtcPlayEndpointProto { - let mut proto = WebRtcPlayEndpointProto::new(); - proto.set_id(id); - proto.set_src(self.src); - proto.set_force_relay(self.force_relay); - proto + WebRtcPlayEndpointProto { + id, + src: self.src, + force_relay: self.force_relay, + on_start: String::new(), + on_stop: String::new(), + } } } impl From for WebRtcPlayEndpoint { fn from(mut proto: WebRtcPlayEndpointProto) -> Self { Self { - id: proto.take_id(), - src: proto.take_src(), - force_relay: proto.get_force_relay(), + id: proto.id, + src: proto.src, + force_relay: proto.force_relay, } } } @@ -128,26 +134,26 @@ impl Endpoint { /// Converts [`Endpoint`] into protobuf [`MemberElementProto`]. #[must_use] pub fn into_proto(self, id: String) -> MemberElementProto { - let mut proto = MemberElementProto::new(); - match self { + let oneof = match self { Self::WebRtcPlayEndpoint(spec) => { - proto.set_webrtc_play(spec.into_proto(id)) + MemberElementOneOfEl::WebrtcPlay(spec.into_proto(id)) } Self::WebRtcPublishEndpoint(spec) => { - proto.set_webrtc_pub(spec.into_proto(id)) + MemberElementOneOfEl::WebrtcPub(spec.into_proto(id)) } - } - proto + }; + + MemberElementProto { el: Some(oneof) } } } impl From for Endpoint { fn from(proto: MemberElementProto) -> Self { match proto.el.unwrap() { - MemberElementOneOfEl::webrtc_pub(webrtc_pub) => { + MemberElementOneOfEl::WebrtcPub(webrtc_pub) => { Self::WebRtcPublishEndpoint(webrtc_pub.into()) } - MemberElementOneOfEl::webrtc_play(webrtc_play) => { + MemberElementOneOfEl::WebrtcPlay(webrtc_play) => { Self::WebRtcPlayEndpoint(webrtc_play.into()) } } diff --git a/mock/control-api/src/api/member.rs b/mock/control-api/src/api/member.rs index affd87256..3ffdf44cd 100644 --- a/mock/control-api/src/api/member.rs +++ b/mock/control-api/src/api/member.rs @@ -2,8 +2,9 @@ use std::collections::HashMap; -use medea_control_api_proto::grpc::api::{ - Member as MemberProto, Room_Element as RoomElementProto, +use medea_control_api_proto::grpc::medea::{ + room::{element::El as RoomElementOneOfProto, Element as RoomElementProto}, + Member as MemberProto, }; use serde::{Deserialize, Serialize}; @@ -41,66 +42,44 @@ impl Member { /// Converts [`Member`] into protobuf [`MemberProto`]. #[must_use] pub fn into_proto(self, id: String) -> MemberProto { - let mut proto = MemberProto::new(); - let mut members_elements = HashMap::new(); - for (id, endpoint) in self.pipeline { - members_elements.insert(id.clone(), endpoint.into_proto(id)); - } - proto.set_id(id); - proto.set_pipeline(members_elements); - if let Some(on_leave) = self.on_leave { - proto.set_on_leave(on_leave); - } - if let Some(on_join) = self.on_join { - proto.set_on_join(on_join); - } + let member_elements = self + .pipeline + .into_iter() + .map(|(id, endpoint)| (id.clone(), endpoint.into_proto(id))) + .collect(); - if let Some(credentials) = self.credentials { - proto.set_credentials(credentials); + MemberProto { + pipeline: member_elements, + id, + credentials: self.credentials.unwrap_or_default(), + on_join: self.on_join.unwrap_or_default(), + on_leave: self.on_leave.unwrap_or_default(), } - - proto } /// Converts [`Member`] into protobuf [`RoomElementProto`]. #[must_use] pub fn into_room_el_proto(self, id: String) -> RoomElementProto { - let mut proto = RoomElementProto::new(); - proto.set_member(self.into_proto(id)); - proto + RoomElementProto { + el: Some(RoomElementOneOfProto::Member(self.into_proto(id))), + } } } impl From for Member { fn from(mut proto: MemberProto) -> Self { - let mut member_pipeline = HashMap::new(); - for (id, endpoint) in proto.take_pipeline() { - member_pipeline.insert(id, endpoint.into()); - } - - let on_leave = { - let on_leave = proto.take_on_leave(); - if on_leave.is_empty() { - None - } else { - Some(on_leave) - } - }; - let on_join = { - let on_join = proto.take_on_join(); - if on_join.is_empty() { - None - } else { - Some(on_join) - } - }; + let member_pipeline = proto + .pipeline + .into_iter() + .map(|(id, endpoint)| (id, endpoint.into())) + .collect(); Self { - id: proto.take_id(), + id: proto.id, pipeline: member_pipeline, - credentials: Some(proto.take_credentials()), - on_join, - on_leave, + credentials: Some(proto.credentials), + on_join: Some(proto.on_join).filter(|s| !s.is_empty()), + on_leave: Some(proto.on_leave).filter(|s| !s.is_empty()), } } } diff --git a/mock/control-api/src/api/mod.rs b/mock/control-api/src/api/mod.rs index 7e4dd4837..f82342776 100644 --- a/mock/control-api/src/api/mod.rs +++ b/mock/control-api/src/api/mod.rs @@ -17,12 +17,12 @@ use actix_web::{ }; use clap::ArgMatches; use futures::Future; -use medea_control_api_proto::grpc::api::{ +use medea_control_api_proto::grpc::medea::{ + element::El as ElementOneOf, + room::{element::El as RoomElementOneOf, Element as RoomElementProto}, CreateResponse as CreateResponseProto, Element as ElementProto, - Element_oneof_el as ElementOneOf, Error as ErrorProto, - GetResponse as GetResponseProto, Response as ResponseProto, - Room_Element as RoomElementProto, - Room_Element_oneof_el as RoomElementOneOf, + Error as ErrorProto, GetResponse as GetResponseProto, + Response as ResponseProto, }; use serde::{Deserialize, Serialize}; @@ -37,6 +37,7 @@ use self::{ member::Member, room::Room, }; +use actix::fut::err; /// Context of [`actix_web`] server. pub struct Context { @@ -227,9 +228,9 @@ pub struct ErrorResponse { impl Into for ErrorProto { fn into(mut self) -> ErrorResponse { ErrorResponse { - code: self.get_code(), - text: self.take_text(), - element: self.take_element(), + code: self.code, + text: self.text, + element: self.element, } } } @@ -290,26 +291,22 @@ impl_into_http_response!(SingleGetResponse); impl From for Response { fn from(mut resp: ResponseProto) -> Self { - if resp.has_error() { - Self { - error: Some(resp.take_error().into()), - } - } else { - Self { error: None } + Self { + error: resp.error.map(|e| e.into()), } } } impl From for CreateResponse { fn from(mut resp: CreateResponseProto) -> Self { - if resp.has_error() { + if let Some(error) = resp.error { Self { sids: None, - error: Some(resp.take_error().into()), + error: Some(error.into()), } } else { Self { - sids: Some(resp.take_sid()), + sids: Some(resp.sid), error: None, } } @@ -331,24 +328,23 @@ pub enum Element { impl Element { #[must_use] pub fn into_proto(self, id: String) -> RoomElementProto { - let mut proto = RoomElementProto::new(); - match self { - Self::Member(m) => proto.set_member(m.into_proto(id)), + let el = match self { + Self::Member(m) => RoomElementOneOf::Member(m.into_proto(id)), _ => unimplemented!(), - } - proto + }; + RoomElementProto { el: Some(el) } } } impl From for Element { fn from(proto: ElementProto) -> Self { match proto.el.unwrap() { - ElementOneOf::room(room) => Self::Room(room.into()), - ElementOneOf::member(member) => Self::Member(member.into()), - ElementOneOf::webrtc_pub(webrtc_pub) => { + ElementOneOf::Room(room) => Self::Room(room.into()), + ElementOneOf::Member(member) => Self::Member(member.into()), + ElementOneOf::WebrtcPub(webrtc_pub) => { Self::WebRtcPublishEndpoint(webrtc_pub.into()) } - ElementOneOf::webrtc_play(webrtc_play) => { + ElementOneOf::WebrtcPlay(webrtc_play) => { Self::WebRtcPlayEndpoint(webrtc_play.into()) } } @@ -358,7 +354,7 @@ impl From for Element { impl From for Element { fn from(proto: RoomElementProto) -> Self { match proto.el.unwrap() { - RoomElementOneOf::member(member) => Self::Member(member.into()), + RoomElementOneOf::Member(member) => Self::Member(member.into()), _ => unimplemented!( "Currently Control API mock server supports only Member \ element in Room pipeline." @@ -384,16 +380,16 @@ pub struct SingleGetResponse { impl From for SingleGetResponse { fn from(mut proto: GetResponseProto) -> Self { - if proto.has_error() { + if let Some(error) = proto.error { Self { element: None, - error: Some(proto.take_error().into()), + error: error.into(), } } else { Self { error: None, element: proto - .take_elements() + .elements .into_iter() .map(|(_, e)| e.into()) .next(), diff --git a/mock/control-api/src/api/room.rs b/mock/control-api/src/api/room.rs index a719d7ce5..fbc223b46 100644 --- a/mock/control-api/src/api/room.rs +++ b/mock/control-api/src/api/room.rs @@ -2,9 +2,9 @@ use std::collections::HashMap; -use medea_control_api_proto::grpc::api::{ - Room as RoomProto, Room_Element as RoomElementProto, - Room_Element_oneof_el as RoomElementOneOfEl, +use medea_control_api_proto::grpc::medea::{ + room::{element::El as RoomElementOneOfEl, Element as RoomElementProto}, + Room as RoomProto, }; use serde::{Deserialize, Serialize}; @@ -27,15 +27,16 @@ impl Room { /// Converts [`Room`] into protobuf [`RoomProto`]. #[must_use] pub fn into_proto(self, id: String) -> RoomProto { - let mut proto = RoomProto::new(); - let mut room_elements = HashMap::new(); - for (id, member) in self.pipeline { - room_elements.insert(id.clone(), member.into_proto(id)); - } - proto.set_id(id); - proto.set_pipeline(room_elements); + let room_elements = self + .pipeline + .into_iter() + .map(|(id, member)| (id.clone(), member.into_proto(id))) + .collect(); - proto + RoomProto { + id, + pipeline: room_elements, + } } } @@ -49,19 +50,18 @@ pub enum RoomElement { impl RoomElement { #[must_use] pub fn into_proto(self, id: String) -> RoomElementProto { - let mut proto = RoomElementProto::new(); - match self { - Self::Member(m) => proto.set_member(m.into_proto(id)), - } + let el = match self { + Self::Member(m) => RoomElementOneOfEl::Member(m.into_proto(id)), + }; - proto + RoomElementProto { el: Some(el) } } } impl From for RoomElement { fn from(proto: RoomElementProto) -> Self { match proto.el.unwrap() { - RoomElementOneOfEl::member(member) => Self::Member(member.into()), + RoomElementOneOfEl::Member(member) => Self::Member(member.into()), _ => unimplemented!(), } } @@ -69,11 +69,15 @@ impl From for RoomElement { impl From for Room { fn from(mut proto: RoomProto) -> Self { - let mut pipeline = HashMap::new(); - for (id, member) in proto.take_pipeline() { - pipeline.insert(id, member.into()); + let pipeline = proto + .pipeline + .into_iter() + .map(|(id, member)| (id, member.into())) + .collect(); + + Self { + id: proto.id, + pipeline, } - let id = proto.take_id(); - Self { id, pipeline } } } diff --git a/mock/control-api/src/callback/mod.rs b/mock/control-api/src/callback/mod.rs index 0361e93fe..f97f88302 100644 --- a/mock/control-api/src/callback/mod.rs +++ b/mock/control-api/src/callback/mod.rs @@ -2,8 +2,8 @@ pub mod server; -use medea_control_api_proto::grpc::callback::{ - Request as CallbackProto, Request_oneof_event as CallbackEventProto, +use medea_control_api_proto::grpc::medea_callback::{ + request::Event as CallbackEventProto, Request as CallbackProto, }; use serde::Serialize; @@ -18,12 +18,10 @@ pub enum CallbackEvent { impl From for CallbackEvent { fn from(proto: CallbackEventProto) -> Self { match proto { - CallbackEventProto::on_leave(on_leave) => { + CallbackEventProto::OnLeave(on_leave) => { Self::OnLeave(on_leave.into()) } - CallbackEventProto::on_join(on_join) => { - Self::OnJoin(on_join.into()) - } + CallbackEventProto::OnJoin(on_join) => Self::OnJoin(on_join.into()), } } } @@ -44,8 +42,8 @@ pub struct CallbackItem { impl From for CallbackItem { fn from(mut proto: CallbackProto) -> Self { Self { - fid: proto.take_fid(), - at: proto.take_at(), + fid: proto.fid, + at: proto.at, event: proto.event.unwrap().into(), } } @@ -53,7 +51,7 @@ impl From for CallbackItem { /// `on_join` callback's related entities and implementations. mod join { - use medea_control_api_proto::grpc::callback::OnJoin as OnJoinProto; + use medea_control_api_proto::grpc::medea_callback::OnJoin as OnJoinProto; use serde::Serialize; /// `OnJoin` callback for Control API. @@ -69,8 +67,8 @@ mod join { /// `on_leave` callback's related entities and implementations. mod leave { - use medea_control_api_proto::grpc::callback::{ - OnLeave as OnLeaveProto, OnLeave_Reason as OnLeaveReasonProto, + use medea_control_api_proto::grpc::medea_callback::{ + on_leave::Reason as OnLeaveReasonProto, OnLeave as OnLeaveProto, }; use serde::Serialize; @@ -84,7 +82,7 @@ mod leave { impl From for OnLeave { fn from(proto: OnLeaveProto) -> Self { Self { - reason: proto.get_reason().into(), + reason: proto.reason.into(), } } } @@ -105,9 +103,9 @@ mod leave { impl From for OnLeaveReason { fn from(proto: OnLeaveReasonProto) -> Self { match proto { - OnLeaveReasonProto::SERVER_SHUTDOWN => Self::ServerShutdown, - OnLeaveReasonProto::LOST_CONNECTION => Self::LostConnection, - OnLeaveReasonProto::DISCONNECTED => Self::Disconnected, + OnLeaveReasonProto::ServerShutdown => Self::ServerShutdown, + OnLeaveReasonProto::LostConnection => Self::LostConnection, + OnLeaveReasonProto::Disconnected => Self::Disconnected, } } } diff --git a/mock/control-api/src/callback/server.rs b/mock/control-api/src/callback/server.rs index ea6b85979..6ad9fc2d7 100644 --- a/mock/control-api/src/callback/server.rs +++ b/mock/control-api/src/callback/server.rs @@ -8,9 +8,8 @@ use actix::{Actor, Addr, Arbiter, Context, Handler, Message}; use clap::ArgMatches; use futures::future::Future as _; use grpcio::{Environment, RpcContext, Server, ServerBuilder, UnarySink}; -use medea_control_api_proto::grpc::{ - callback::{Request, Response}, - callback_grpc::{create_callback, Callback as CallbackService}, +use medea_control_api_proto::grpc::medea_callback::{ + callback_server::Callback as CallbackService, Request, Response, }; use crate::{callback::CallbackItem, prelude::*}; diff --git a/mock/control-api/src/client.rs b/mock/control-api/src/client.rs index eebec412b..2c8760c7f 100644 --- a/mock/control-api/src/client.rs +++ b/mock/control-api/src/client.rs @@ -8,8 +8,8 @@ use std::sync::Arc; use futures::{Future, IntoFuture}; use grpcio::{ChannelBuilder, EnvBuilder, Error}; use medea_control_api_proto::grpc::{ - api::{CreateRequest, CreateResponse, GetResponse, IdRequest, Response}, api_grpc::ControlApiClient, + medea::{CreateRequest, CreateResponse, GetResponse, IdRequest, Response}, }; use protobuf::RepeatedField; From 26f15be7aa2a8a3d3b3df1abcec7f97f6f334952 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 27 Jan 2020 14:37:13 +0300 Subject: [PATCH 005/224] Migrate client of medea-control-api-mock to Tonic --- mock/control-api/src/api/mod.rs | 2 +- mock/control-api/src/callback/mod.rs | 3 +- mock/control-api/src/callback/server.rs | 51 ++++++++++--------------- mock/control-api/src/client.rs | 39 +++++++++---------- 4 files changed, 42 insertions(+), 53 deletions(-) diff --git a/mock/control-api/src/api/mod.rs b/mock/control-api/src/api/mod.rs index f82342776..101114caf 100644 --- a/mock/control-api/src/api/mod.rs +++ b/mock/control-api/src/api/mod.rs @@ -383,7 +383,7 @@ impl From for SingleGetResponse { if let Some(error) = proto.error { Self { element: None, - error: error.into(), + error: Some(error.into()), } } else { Self { diff --git a/mock/control-api/src/callback/mod.rs b/mock/control-api/src/callback/mod.rs index f97f88302..9efff285e 100644 --- a/mock/control-api/src/callback/mod.rs +++ b/mock/control-api/src/callback/mod.rs @@ -4,6 +4,7 @@ pub mod server; use medea_control_api_proto::grpc::medea_callback::{ request::Event as CallbackEventProto, Request as CallbackProto, + on_leave::Reason as OnLeaveReasonProto, }; use serde::Serialize; @@ -82,7 +83,7 @@ mod leave { impl From for OnLeave { fn from(proto: OnLeaveProto) -> Self { Self { - reason: proto.reason.into(), + reason: OnLeaveReasonProto::from_i32(proto.reason).unwrap_or_default().into(), } } } diff --git a/mock/control-api/src/callback/server.rs b/mock/control-api/src/callback/server.rs index 6ad9fc2d7..82474f284 100644 --- a/mock/control-api/src/callback/server.rs +++ b/mock/control-api/src/callback/server.rs @@ -7,12 +7,13 @@ use std::sync::{Arc, Mutex}; use actix::{Actor, Addr, Arbiter, Context, Handler, Message}; use clap::ArgMatches; use futures::future::Future as _; -use grpcio::{Environment, RpcContext, Server, ServerBuilder, UnarySink}; +use tonic::transport::Server; use medea_control_api_proto::grpc::medea_callback::{ - callback_server::Callback as CallbackService, Request, Response, + callback_server::{Callback as CallbackService, CallbackServer as TonicCallbackServer}, Request, Response, }; use crate::{callback::CallbackItem, prelude::*}; +use tonic::Status; /// Type which used in [`GrpcCallbackServer`] for [`CallbackItem`] storing. type CallbackItems = Arc>>; @@ -22,9 +23,6 @@ type CallbackItems = Arc>>; /// Also this [`Actor`] can return all received callbacks /// with [`GetCallbacks`] [`Message`]. pub struct GrpcCallbackServer { - /// [`grpcio`] gRPC server. - server: Server, - /// All [`Callback`]s which this server received. events: CallbackItems, } @@ -33,7 +31,6 @@ impl Actor for GrpcCallbackServer { type Context = Context; fn started(&mut self, _ctx: &mut Self::Context) { - self.server.start(); } } @@ -53,19 +50,13 @@ impl GrpcCallbackService { } } +#[tonic::async_trait] impl CallbackService for GrpcCallbackService { - fn on_event( - &mut self, - ctx: RpcContext, - req: Request, - sink: UnarySink, - ) { - info!("Callback request received: [{:?}]", req); - self.events.lock().unwrap().push(req.into()); - ctx.spawn( - sink.success(Response::new()) - .map_err(|e| error!("Err: {:?}", e)), - ) + async fn on_event(&self, request: tonic::Request) -> Result, tonic::Status> { + info!("Callback request received: [{:?}]", request); + self.events.lock().unwrap().push(request.into_inner().into()); + + Ok(tonic::Response::new(Response {})) } } @@ -89,24 +80,24 @@ impl Handler for GrpcCallbackServer { /// Run [`GrpcCallbackServer`]. #[must_use] -pub fn run(args: &ArgMatches) -> Addr { +pub async fn run(args: &ArgMatches<'static>) -> Addr { let host = args.value_of("callback_host").unwrap(); - let port = args.value_of("callback_port").unwrap().parse().unwrap(); - let cq_count = 2; + let port: u32 = args.value_of("callback_port").unwrap().parse().unwrap(); let events = Arc::new(Mutex::new(Vec::new())); - let service = - create_callback(GrpcCallbackService::new(Arc::clone(&events))); - let env = Arc::new(Environment::new(cq_count)); + let service = TonicCallbackServer::new( + GrpcCallbackService::new(Arc::clone(&events)) + ); - let server = ServerBuilder::new(env) - .register_service(service) - .bind(host, port) - .build() - .unwrap(); + let server = Server::builder() + .add_service(service) + .serve( + format!("{}:{}", host, port).parse().unwrap(), + ) + .await.unwrap(); GrpcCallbackServer::start_in_arbiter(&Arbiter::new(), move |_| { - GrpcCallbackServer { server, events } + GrpcCallbackServer { events } }) } diff --git a/mock/control-api/src/client.rs b/mock/control-api/src/client.rs index 2c8760c7f..a4a16ab2b 100644 --- a/mock/control-api/src/client.rs +++ b/mock/control-api/src/client.rs @@ -8,8 +8,7 @@ use std::sync::Arc; use futures::{Future, IntoFuture}; use grpcio::{ChannelBuilder, EnvBuilder, Error}; use medea_control_api_proto::grpc::{ - api_grpc::ControlApiClient, - medea::{CreateRequest, CreateResponse, GetResponse, IdRequest, Response}, + medea::{CreateRequest, CreateResponse, GetResponse, IdRequest, Response, create_request::El as CreateRequestElProto, control_api_client::ControlApiClient}, }; use protobuf::RepeatedField; @@ -51,10 +50,9 @@ impl Into for Fid { /// Returns new [`IdRequest`] with provided FIDs. fn id_request(ids: Vec) -> IdRequest { - let mut req = IdRequest::new(); - let ids = RepeatedField::from(ids); - req.set_fid(ids); - req + IdRequest { + fid: ids + } } /// Client for [Medea]'s [Control API]. @@ -80,33 +78,32 @@ impl ControlClient { } /// Creates provided element with gRPC Control API. - pub fn create( - &self, + pub async fn create( + &mut self, id: String, fid: Fid, element: Element, - ) -> impl Future { - let mut req = CreateRequest::new(); - req.set_parent_fid(fid.into()); - match element { + ) -> Result { + let el = match element { Element::Room(room) => { - req.set_room(room.into_proto(id)); + CreateRequestElProto::Room(room.into_proto(id)) } Element::Member(member) => { - req.set_member(member.into_proto(id)); + CreateRequestElProto::Member(member.into_proto(id)) } Element::WebRtcPlayEndpoint(webrtc_play) => { - req.set_webrtc_play(webrtc_play.into_proto(id)); + CreateRequestElProto::WebrtcPlay(webrtc_play.into_proto(id)) } Element::WebRtcPublishEndpoint(webrtc_pub) => { - req.set_webrtc_pub(webrtc_pub.into_proto(id)); + CreateRequestElProto::WebrtcPub(webrtc_pub.into_proto(id)) } - } + }; + let req = CreateRequest { + parent_fid: fid.into(), + el: Some(el), + }; - self.grpc_client - .create_async(&req) - .into_future() - .and_then(|r| r) + self.grpc_client.create(tonic::Request::new(req)) } /// Gets element from Control API by FID. From e10669c258032f8c65e59d618e744381b18ad13d Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 27 Jan 2020 17:19:55 +0300 Subject: [PATCH 006/224] Migrate medea-control-api-mock to tonic and actix-web 2.0 --- Cargo.lock | 820 +----------------------- mock/control-api/Cargo.toml | 9 +- mock/control-api/src/api/endpoint.rs | 2 + mock/control-api/src/api/mod.rs | 71 +- mock/control-api/src/callback/mod.rs | 6 +- mock/control-api/src/callback/server.rs | 41 +- mock/control-api/src/client.rs | 84 ++- mock/control-api/src/main.rs | 14 +- src/api/control/callback/url.rs | 4 +- src/api/control/grpc/server.rs | 21 +- 10 files changed, 172 insertions(+), 900 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee7c46b65..dc5fa51f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,32 +9,6 @@ dependencies = [ "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-http 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "actix_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix" version = "0.9.0" @@ -59,18 +33,6 @@ dependencies = [ "trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-codec" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-codec" version = "0.2.0" @@ -85,25 +47,6 @@ dependencies = [ "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-connect" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-utils 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-connect" version = "1.0.2" @@ -124,60 +67,13 @@ dependencies = [ [[package]] name = "actix-cors" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-service 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-http" -version = "0.2.11" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-connect 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-server-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-utils 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -235,19 +131,6 @@ dependencies = [ "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-router" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-router" version = "0.2.4" @@ -260,20 +143,6 @@ dependencies = [ "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-rt" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-rt" version = "1.0.0" @@ -286,27 +155,6 @@ dependencies = [ "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-server" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-rt 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-server-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-server" version = "1.0.1" @@ -325,24 +173,6 @@ dependencies = [ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-server-config" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-service" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-service" version = "1.0.5" @@ -352,22 +182,6 @@ dependencies = [ "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-testing" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-rt 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-server 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-server-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-testing" version = "1.0.0" @@ -382,20 +196,6 @@ dependencies = [ "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-threadpool" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-threadpool" version = "0.3.1" @@ -425,21 +225,6 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-utils" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-utils" version = "1.0.6" @@ -457,40 +242,6 @@ dependencies = [ "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-web" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-http 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-router 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-rt 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-server 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-server-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-testing 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-utils 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web-codegen 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "awc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-web" version = "2.0.0" @@ -540,16 +291,6 @@ dependencies = [ "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix-web-codegen" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix-web-codegen" version = "0.2.0" @@ -560,16 +301,6 @@ dependencies = [ "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "actix_derive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "actix_derive" version = "0.5.0" @@ -585,14 +316,6 @@ name = "adler32" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "ahash" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "aho-corasick" version = "0.7.6" @@ -691,28 +414,6 @@ name = "autocfg" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "awc" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-http 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-service 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "awc" version = "1.0.1" @@ -811,15 +512,6 @@ name = "byteorder" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "bytes" version = "0.5.4" @@ -927,24 +619,6 @@ dependencies = [ "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "const-random" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "const-random-macro" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "constant_time_eq" version = "0.1.5" @@ -981,14 +655,6 @@ dependencies = [ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-channel" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam-channel" version = "0.4.0" @@ -1028,15 +694,6 @@ dependencies = [ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-utils" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam-utils" version = "0.7.0" @@ -1129,17 +786,6 @@ dependencies = [ "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "derive_more" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "derive_more" version = "0.15.0" @@ -1226,16 +872,6 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "enum-as-inner" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "enum-as-inner" version = "0.3.0" @@ -1280,7 +916,6 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1455,23 +1090,6 @@ dependencies = [ "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "h2" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "h2" version = "0.2.1" @@ -1490,20 +1108,6 @@ dependencies = [ "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "hashbrown" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "hashbrown" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "heck" version = "0.3.1" @@ -1529,16 +1133,6 @@ dependencies = [ "winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "http" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "http" version = "0.2.0" @@ -1599,25 +1193,15 @@ dependencies = [ "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "idna" version = "0.2.0" @@ -1726,14 +1310,6 @@ name = "linked-hash-map" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "lock_api" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "lock_api" version = "0.3.3" @@ -1841,13 +1417,13 @@ dependencies = [ name = "medea-control-api-mock" version = "0.1.0-dev" dependencies = [ - "actix 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-cors 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "actix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-cors 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "medea-control-api-proto 0.1.0-dev", "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1857,6 +1433,7 @@ dependencies = [ "slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-stdlog 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "slog-term 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1927,15 +1504,6 @@ name = "mime" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "miniz-sys" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "miniz_oxide" version = "0.3.5" @@ -2111,16 +1679,6 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parking_lot" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot" version = "0.9.0" @@ -2140,21 +1698,6 @@ dependencies = [ "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "parking_lot_core" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "parking_lot_core" version = "0.6.2" @@ -2390,24 +1933,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand" version = "0.7.3" @@ -2421,15 +1946,6 @@ dependencies = [ "rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand_chacha" version = "0.2.1" @@ -2460,14 +1976,6 @@ dependencies = [ "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand_hc" version = "0.2.0" @@ -2476,46 +1984,6 @@ dependencies = [ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rand_pcg" version = "0.2.1" @@ -2524,14 +1992,6 @@ dependencies = [ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rdrand" version = "0.4.0" @@ -2781,15 +2241,6 @@ name = "sha1" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "signal-hook" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "signal-hook-registry" version = "1.2.0" @@ -2932,14 +2383,6 @@ name = "static_assertions" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "string" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "strsim" version = "0.8.0" @@ -3070,125 +2513,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-codec" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-executor" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-io" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-signal" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-sync" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-timer" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-udp" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-util" version = "0.2.0" @@ -3463,30 +2787,6 @@ name = "treeline" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "trust-dns-proto" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "enum-as-inner 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "trust-dns-proto" version = "0.18.0-alpha.2" @@ -3506,24 +2806,6 @@ dependencies = [ "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "trust-dns-resolver" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-proto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "trust-dns-resolver" version = "0.18.0-alpha.2" @@ -3591,16 +2873,6 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "url" version = "2.1.1" @@ -3847,41 +3119,25 @@ dependencies = [ [metadata] "checksum Inflector 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -"checksum actix 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "671ce3d27313f236827a5dd153a1073ad03ef31fc77f562020263e7830cf1ef7" "checksum actix 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4af87564ff659dee8f9981540cac9418c45e910c8072fdedd643a262a38fcaf" -"checksum actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2c11af4b06dc935d8e1b1491dad56bfb32febc49096a91e773f8535c176453" "checksum actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09e55f0a5c2ca15795035d90c46bd0e73a5123b72f68f12596d6ba5282051380" -"checksum actix-connect 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9fade9bd4bb46bacde89f1e726c7a3dd230536092712f5d94d77ca57c087fca0" "checksum actix-connect 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c95cc9569221e9802bf4c377f6c18b90ef10227d787611decf79fd47d2a8e76c" -"checksum actix-cors 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "66e5b071c68ac8ab182e7b7717167ef29ea93e166bc26391f678f19ac08ed129" -"checksum actix-http 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fcb50f77cd28240d344fd54afd205bae8760a3b0ad448b1716a2aa31e24db139" +"checksum actix-cors 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6206917d5c0fdd79d81cec9ef02d3e802df4abf276d96241e1f595d971e002" "checksum actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c16664cc4fdea8030837ad5a845eb231fb93fc3c5c171edfefb52fad92ce9019" "checksum actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "21705adc76bbe4bc98434890e73a89cd00c6015e5704a60bb6eea6c3b72316b6" -"checksum actix-router 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "23224bb527e204261d0291102cb9b52713084def67d94f7874923baefe04ccf7" "checksum actix-router 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d7a10ca4d94e8c8e7a87c5173aba1b97ba9a6563ca02b0e1cd23531093d3ec8" -"checksum actix-rt 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "88c9da1d06603d82ec2b6690fc5b80eb626cd2d6b573f3d9a71d5252e06d098e" "checksum actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6a0a55507046441a496b2f0d26a84a65e67c8cafffe279072412f624b5fb6d" -"checksum actix-server 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd626534af8d0a738e5f74901fe603af0445708f91b86a7d763d80df10d562a5" "checksum actix-server 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "51d3455eaac03ca3e49d7b822eb35c884b861f715627254ccbe4309d08f1841a" -"checksum actix-server-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "483a34989c682d93142bacad6300375bb6ad8002d2e0bb249dbad86128b9ff30" -"checksum actix-service 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bca5b48e928841ff7e7dce1fdb5b0d4582f6b1b976e08f4bac3f640643e0773f" "checksum actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3e4fc95dfa7e24171b2d0bb46b85f8ab0e8499e4e3caec691fc4ea65c287564" -"checksum actix-testing 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "af001e97ac6750994824d400a1b7087055aab14317aa012f528d0b2b363f37f1" "checksum actix-testing 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48494745b72d0ea8ff0cf874aaf9b622a3ee03d7081ee0c04edea4f26d32c911" -"checksum actix-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b5ae85d13da7e6fb86b1b7bc83185e0e3bd4cc5f421c887e1803796c034d35d" "checksum actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4082192601de5f303013709ff84d81ca6a1bc4af7fb24f367a500a23c6e84e" "checksum actix-tls 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4e5b4faaf105e9a6d389c606c298dcdb033061b00d532af9df56ff3a54995a8" -"checksum actix-utils 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "908c3109948f5c37a8b57fd343a37dcad5bb1d90bfd06300ac96b17bbe017b95" "checksum actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fcf8f5631bf01adec2267808f00e228b761c60c0584cc9fa0b5364f41d147f4e" -"checksum actix-web 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "af3a1b967cdbacb903c4b9ae71257a7f098d881b25eb483d0c468b7dac579b03" "checksum actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3158e822461040822f0dbf1735b9c2ce1f95f93b651d7a7aded00b1efbb1f635" "checksum actix-web-actors 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1bd41bd66c4e9b5274cec87aac30168e63d64e96fd19db38edef6b46ba2982" -"checksum actix-web-codegen 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "068a33520e21c1eea89726be4d6b3ce2e6b81046904367e1677287695a043abb" "checksum actix-web-codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de0878b30e62623770a4713a6338329fd0119703bafc211d3e4144f4d4a7bdd5" -"checksum actix_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bf5f6d7bf2d220ae8b4a7ae02a572bb35b7c4806b24049af905ab8110de156c" "checksum actix_derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c" "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" -"checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" @@ -3896,7 +3152,6 @@ dependencies = [ "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" -"checksum awc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5e995283278dd3bf0449e7534e77184adb1570c0de8b6a50bf7c9d01ad8db8c4" "checksum awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7601d4d1d7ef2335d6597a41b5fe069f6ab799b85f53565ab390e7b7065aac5" "checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" @@ -3908,7 +3163,6 @@ dependencies = [ "checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" "checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" -"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" "checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" "checksum bytestring 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fc267467f58ef6cc8874064c62a0423eb0d099362c8a23edd1c6d044f46eead4" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" @@ -3921,19 +3175,15 @@ dependencies = [ "checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" "checksum config 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" "checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" -"checksum const-random 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a" -"checksum const-random-macro 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a" "checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" "checksum copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ff9c56c9fb2a49c05ef0e431485a22400af20d33226dc0764d891d09e724127" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" "checksum crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" -"checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" "checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" "checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" "checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" "checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" -"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" "checksum darling 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" "checksum darling_core 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" @@ -3942,7 +3192,6 @@ dependencies = [ "checksum deadpool-redis 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "061442c74bf11e8a19ddca0ea9bf46a2590f854df98e9830447601be097b8fe4" "checksum derive_builder 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" "checksum derive_builder_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" -"checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839" "checksum derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" "checksum derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" @@ -3954,7 +3203,6 @@ dependencies = [ "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28" -"checksum enum-as-inner 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d58266c97445680766be408285e798d3401c6d4c378ec5552e78737e681e37d" "checksum enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "900a6c7fbe523f4c2884eaf26b57b81bb69b6810a01a236390a7ac021d09492e" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" @@ -3981,14 +3229,10 @@ dependencies = [ "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" "checksum grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9ac757a85603e4f8c40a9f94be06a5ad412acab80b39b4e8895ca931b6619910" "checksum grpcio-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "7b2f22fb0327f153acccedbe91894dd0fb15bb6f202d8195665cd206af0402b0" -"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" -"checksum hashbrown 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29fba9abe4742d586dfd0c06ae4f7e73a1c2d86b856933509b269d82cdf06e18" -"checksum hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" "checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" -"checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" "checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" "checksum http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" @@ -3996,7 +3240,6 @@ dependencies = [ "checksum humantime-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f59e8a805c18bc9ded3f4e596cb5f0157d88a235e875480a7593b5926f95065" "checksum hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf49cfb32edee45d890537d9057d1b02ed55f53b7b6a30bae83a38c9231749e" "checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" -"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" @@ -4011,7 +3254,6 @@ dependencies = [ "checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" "checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" -"checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" "checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" @@ -4022,7 +3264,6 @@ dependencies = [ "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" "checksum memory_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" "checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" -"checksum miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" "checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" @@ -4042,9 +3283,7 @@ dependencies = [ "checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" "checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" "checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" -"checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" "checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" @@ -4073,21 +3312,13 @@ dependencies = [ "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d69c054daeca01bc1bee4af75b04dffa3458d6702cb7a74c2f38518c130fb624" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" @@ -4118,7 +3349,6 @@ dependencies = [ "checksum serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f74862f16557830c73deefde614c906f8af0157e064b64f156e32a0b12d7114c" "checksum serial_test_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c188479c8b700998829c168d7a4c21032660b0dd2ed87a0b166c85811750740" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "7a9c17dd3ba2d36023a5c9472ecddeda07e27fd0b05436e8c1e0c8f178185652" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99" @@ -4135,7 +3365,6 @@ dependencies = [ "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" "checksum static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3" -"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum strsim 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" @@ -4150,16 +3379,6 @@ dependencies = [ "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c1fc73332507b971a5010664991a441b5ee0de92017f5a0e8b00fd684573045b" -"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" -"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" -"checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" -"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" -"checksum tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd6dc5276ea05ce379a16de90083ec80836440d5ef8a6a39545a3207373b8296" -"checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" -"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" -"checksum tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" "checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" "checksum tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08283643b1d483eb7f3fc77069e63b5cba3e4db93514b3d45470e67f123e4e48" @@ -4185,8 +3404,6 @@ dependencies = [ "checksum tracing-futures 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33848db47a7c848ab48b66aab3293cb9c61ea879a3586ecfcd17302fcea0baf1" "checksum treeline 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" "checksum trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2a7f3a2ab8a919f5eca52a468866a67ed7d3efa265d48a652a9a3452272b413f" -"checksum trust-dns-proto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5559ebdf6c2368ddd11e20b11d6bbaf9e46deb803acd7815e93f5a7b4a6d2901" -"checksum trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c9992e58dba365798803c0b91018ff6c8d3fc77e06977c4539af2a6bfe0a039" "checksum trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6f90b1502b226f8b2514c6d5b37bafa8c200d7ca4102d57dc36ee0f3b7a04a2f" "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" @@ -4196,7 +3413,6 @@ dependencies = [ "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" diff --git a/mock/control-api/Cargo.toml b/mock/control-api/Cargo.toml index fe2d846c9..1287fcb8e 100644 --- a/mock/control-api/Cargo.toml +++ b/mock/control-api/Cargo.toml @@ -10,13 +10,14 @@ repository = "https://github.com/instrumentisto/medea" publish = false [dependencies] -actix = "0.8" -actix-cors = "0.1" -actix-web = "1.0" +actix = "0.9" +actix-rt = "1.0" +actix-cors = "0.2" +actix-web = "2.0" clap = "2.33" dotenv = "0.13" futures = "0.1" -grpcio = "0.4" +tonic = "0.1" medea-control-api-proto = { path = "../../proto/control-api" } protobuf = "2.7" serde = { version = "1.0", features = ["derive"] } diff --git a/mock/control-api/src/api/endpoint.rs b/mock/control-api/src/api/endpoint.rs index 13842a38a..0e0d1d6ca 100644 --- a/mock/control-api/src/api/endpoint.rs +++ b/mock/control-api/src/api/endpoint.rs @@ -51,6 +51,7 @@ pub struct WebRtcPublishEndpoint { p2p: P2pMode, /// Option to relay all media through a TURN server forcibly. + #[serde(default)] force_relay: bool, } @@ -94,6 +95,7 @@ pub struct WebRtcPlayEndpoint { src: String, /// Option to relay all media through a TURN server forcibly. + #[serde(default)] force_relay: bool, } diff --git a/mock/control-api/src/api/mod.rs b/mock/control-api/src/api/mod.rs index 101114caf..ef602b06a 100644 --- a/mock/control-api/src/api/mod.rs +++ b/mock/control-api/src/api/mod.rs @@ -38,6 +38,7 @@ use self::{ room::Room, }; use actix::fut::err; +use std::{rc::Rc, sync::Mutex}; /// Context of [`actix_web`] server. pub struct Context { @@ -45,7 +46,7 @@ pub struct Context { /// /// [Control API]: https://tinyurl.com/yxsqplq7 /// [Medea]: https://github.com/instrumentisto/medea - client: ControlClient, + client: Mutex, /// gRPC server which receives Control API callbacks. callback_server: Addr, @@ -54,42 +55,47 @@ pub struct Context { /// Run REST [Control API] server mock. /// /// [Control API]: https://tinyurl.com/yxsqplq7 -pub fn run(args: &ArgMatches, callback_server_addr: Addr) { +pub async fn run( + args: &ArgMatches<'static>, + callback_server_addr: Addr, +) { let medea_addr: String = args.value_of("medea_addr").unwrap().to_string(); HttpServer::new(move || { + debug!("Running HTTP server..."); App::new() - .wrap(Cors::new()) + .wrap(Cors::new().finish()) .data(Context { - client: ControlClient::new(&medea_addr), + client: Mutex::new(ControlClient::new(medea_addr.clone())), callback_server: callback_server_addr.clone(), }) .wrap(middleware::Logger::default()) .service( web::resource("/control-api/{a}") - .route(web::post().to_async(create::create1)) - .route(web::get().to_async(get::get1)) - .route(web::delete().to_async(delete::delete1)), + .route(web::post().to(create::create1)) + .route(web::get().to(get::get1)) + .route(web::delete().to(delete::delete1)), ) .service( web::resource("/control-api/{a}/{b}") - .route(web::post().to_async(create::create2)) - .route(web::get().to_async(get::get2)) - .route(web::delete().to_async(delete::delete2)), + .route(web::post().to(create::create2)) + .route(web::get().to(get::get2)) + .route(web::delete().to(delete::delete2)), ) .service( web::resource("/control-api/{a}/{b}/{c}") - .route(web::post().to_async(create::create3)) - .route(web::get().to_async(get::get3)) - .route(web::delete().to_async(delete::delete3)), + .route(web::post().to(create::create3)) + .route(web::get().to(get::get3)) + .route(web::delete().to(delete::delete3)), ) .service( - web::resource("/callbacks") - .route(web::get().to_async(get_callbacks)), + web::resource("/callbacks").route(web::get().to(get_callbacks)), ) }) .bind(args.value_of("addr").unwrap()) .unwrap() - .start(); + .run() + .await + .unwrap(); } /// Generates `request` macro which will generate [`actix_web`] request handler @@ -108,13 +114,16 @@ macro_rules! gen_request_macro { /// `$uri_tuple` - type of path which will be provided by [`actix_web`]. macro_rules! request { ($name:tt, $uri_tuple:ty) => { - pub fn $name( + pub async fn $name( path: actix_web::web::Path<$uri_tuple>, state: Data, - ) -> impl Future { + ) -> Result { state .client + .lock() + .unwrap() .$call_fn(path.into_inner().into()) + .await .map_err(|e| error!("{:?}", e)) .map(|r| <$resp>::from(r).into()) } @@ -126,12 +135,11 @@ macro_rules! gen_request_macro { /// [`actix_web`] REST API endpoint which returns all /// [`Callback`]s received by this mock server. #[allow(clippy::needless_pass_by_value)] -pub fn get_callbacks( - state: Data, -) -> impl Future { +pub async fn get_callbacks(state: Data) -> Result { state .callback_server .send(GetCallbackItems) + .await .map_err(|e| warn!("GrpcCallbackServer mailbox error. {:?}", e)) .map(|callbacks| HttpResponse::Ok().json(&callbacks.unwrap())) } @@ -171,40 +179,49 @@ mod get { mod create { use super::*; - pub fn create1( + pub async fn create1( path: actix_web::web::Path, state: Data, data: Json, - ) -> impl Future { + ) -> Result { state .client + .lock() + .unwrap() .create(path.into_inner(), Fid::from(()), data.0) + .await .map_err(|e| error!("{:?}", e)) .map(|r| CreateResponse::from(r).into()) } - pub fn create2( + pub async fn create2( path: actix_web::web::Path<(String, String)>, state: Data, data: Json, - ) -> impl Future { + ) -> Result { let uri = path.into_inner(); state .client + .lock() + .unwrap() .create(uri.1, Fid::from(uri.0), data.0) + .await .map_err(|e| error!("{:?}", e)) .map(|r| CreateResponse::from(r).into()) } - pub fn create3( + pub async fn create3( path: actix_web::web::Path<(String, String, String)>, state: Data, data: Json, - ) -> impl Future { + ) -> Result { let uri = path.into_inner(); state .client + .lock() + .unwrap() .create(uri.2, Fid::from((uri.0, uri.1)), data.0) + .await .map_err(|e| error!("{:?}", e)) .map(|r| CreateResponse::from(r).into()) } diff --git a/mock/control-api/src/callback/mod.rs b/mock/control-api/src/callback/mod.rs index 9efff285e..a0c6c01ae 100644 --- a/mock/control-api/src/callback/mod.rs +++ b/mock/control-api/src/callback/mod.rs @@ -3,8 +3,8 @@ pub mod server; use medea_control_api_proto::grpc::medea_callback::{ - request::Event as CallbackEventProto, Request as CallbackProto, on_leave::Reason as OnLeaveReasonProto, + request::Event as CallbackEventProto, Request as CallbackProto, }; use serde::Serialize; @@ -83,7 +83,9 @@ mod leave { impl From for OnLeave { fn from(proto: OnLeaveProto) -> Self { Self { - reason: OnLeaveReasonProto::from_i32(proto.reason).unwrap_or_default().into(), + reason: OnLeaveReasonProto::from_i32(proto.reason) + .unwrap_or_default() + .into(), } } } diff --git a/mock/control-api/src/callback/server.rs b/mock/control-api/src/callback/server.rs index 82474f284..e219c16db 100644 --- a/mock/control-api/src/callback/server.rs +++ b/mock/control-api/src/callback/server.rs @@ -7,10 +7,13 @@ use std::sync::{Arc, Mutex}; use actix::{Actor, Addr, Arbiter, Context, Handler, Message}; use clap::ArgMatches; use futures::future::Future as _; -use tonic::transport::Server; use medea_control_api_proto::grpc::medea_callback::{ - callback_server::{Callback as CallbackService, CallbackServer as TonicCallbackServer}, Request, Response, + callback_server::{ + Callback as CallbackService, CallbackServer as TonicCallbackServer, + }, + Request, Response, }; +use tonic::transport::Server; use crate::{callback::CallbackItem, prelude::*}; use tonic::Status; @@ -30,8 +33,7 @@ pub struct GrpcCallbackServer { impl Actor for GrpcCallbackServer { type Context = Context; - fn started(&mut self, _ctx: &mut Self::Context) { - } + fn started(&mut self, _ctx: &mut Self::Context) {} } /// Implementation for [`CallbackService`] gRPC service. @@ -52,9 +54,15 @@ impl GrpcCallbackService { #[tonic::async_trait] impl CallbackService for GrpcCallbackService { - async fn on_event(&self, request: tonic::Request) -> Result, tonic::Status> { + async fn on_event( + &self, + request: tonic::Request, + ) -> Result, tonic::Status> { info!("Callback request received: [{:?}]", request); - self.events.lock().unwrap().push(request.into_inner().into()); + self.events + .lock() + .unwrap() + .push(request.into_inner().into()); Ok(tonic::Response::new(Response {})) } @@ -86,16 +94,19 @@ pub async fn run(args: &ArgMatches<'static>) -> Addr { let events = Arc::new(Mutex::new(Vec::new())); - let service = TonicCallbackServer::new( - GrpcCallbackService::new(Arc::clone(&events)) - ); + let service = + TonicCallbackServer::new(GrpcCallbackService::new(Arc::clone(&events))); + let addr = format!("{}:{}", host, port).parse().unwrap(); + + let server = Arbiter::spawn(async move { + Server::builder() + .add_service(service) + .serve(addr) + .await + .unwrap(); + }); - let server = Server::builder() - .add_service(service) - .serve( - format!("{}:{}", host, port).parse().unwrap(), - ) - .await.unwrap(); + debug!("gRPC callback server started."); GrpcCallbackServer::start_in_arbiter(&Arbiter::new(), move |_| { GrpcCallbackServer { events } diff --git a/mock/control-api/src/client.rs b/mock/control-api/src/client.rs index a4a16ab2b..6b89acf7f 100644 --- a/mock/control-api/src/client.rs +++ b/mock/control-api/src/client.rs @@ -6,11 +6,14 @@ use std::sync::Arc; use futures::{Future, IntoFuture}; -use grpcio::{ChannelBuilder, EnvBuilder, Error}; -use medea_control_api_proto::grpc::{ - medea::{CreateRequest, CreateResponse, GetResponse, IdRequest, Response, create_request::El as CreateRequestElProto, control_api_client::ControlApiClient}, +use medea_control_api_proto::grpc::medea::{ + control_api_client::ControlApiClient, + create_request::El as CreateRequestElProto, CreateRequest, CreateResponse, + GetResponse, IdRequest, Response, }; use protobuf::RepeatedField; +use slog_scope::debug; +use tonic::{transport::Channel, Status}; use crate::api::Element; @@ -50,9 +53,7 @@ impl Into for Fid { /// Returns new [`IdRequest`] with provided FIDs. fn id_request(ids: Vec) -> IdRequest { - IdRequest { - fid: ids - } + IdRequest { fid: ids } } /// Client for [Medea]'s [Control API]. @@ -60,8 +61,10 @@ fn id_request(ids: Vec) -> IdRequest { /// [Medea]: https://github.com/instrumentisto/medea /// [Control API]: https://tinyurl.com/yxsqplq7 pub struct ControlClient { + medea_addr: String, + /// [`grpcio`] gRPC client for Medea Control API. - grpc_client: ControlApiClient, + grpc_client: Option>, } impl ControlClient { @@ -71,9 +74,23 @@ impl ControlClient { /// API gRPC server. Availability will be checked only on sending request to /// gRPC server.__ #[must_use] - pub fn new(medea_addr: &str) -> Self { + pub fn new(medea_addr: String) -> Self { Self { - grpc_client: new_grpcio_control_api_client(medea_addr), + medea_addr, + grpc_client: None, + } + } + + async fn get_client(&mut self) -> &mut ControlApiClient { + let qq = &mut self.grpc_client; + if let Some(client) = qq { + client + } else { + let client = + new_grpcio_control_api_client(self.medea_addr.clone()).await; + *qq = Some(client); + + qq.as_mut().unwrap() } } @@ -83,7 +100,7 @@ impl ControlClient { id: String, fid: Fid, element: Element, - ) -> Result { + ) -> Result { let el = match element { Element::Room(room) => { CreateRequestElProto::Room(room.into_proto(id)) @@ -103,39 +120,44 @@ impl ControlClient { el: Some(el), }; - self.grpc_client.create(tonic::Request::new(req)) + println!("\n\n\n\n\n{:?}\n\n\n\n\n\n", req); + + self.get_client() + .await + .create(tonic::Request::new(req)) + .await + .map(|resp| resp.into_inner()) } /// Gets element from Control API by FID. - pub fn get( - &self, - fid: Fid, - ) -> impl Future { + pub async fn get(&mut self, fid: Fid) -> Result { let req = id_request(vec![fid.into()]); - self.grpc_client - .get_async(&req) - .into_future() - .and_then(|r| r) + let resp = self + .get_client() + .await + .get(tonic::Request::new(req)) + .await + .map(|resp| resp.into_inner()); + debug!("Get response {:?}", resp); + resp } /// Deletes element from Control API by FID. - pub fn delete( - &self, - fid: Fid, - ) -> impl Future { + pub async fn delete(&mut self, fid: Fid) -> Result { let req = id_request(vec![fid.into()]); - self.grpc_client - .delete_async(&req) - .into_future() - .and_then(|r| r) + self.get_client() + .await + .delete(tonic::Request::new(req)) + .await + .map(|resp| resp.into_inner()) } } /// Returns new [`grpcio`] gRPC client for Control API. -fn new_grpcio_control_api_client(addr: &str) -> ControlApiClient { - let env = Arc::new(EnvBuilder::new().build()); - let ch = ChannelBuilder::new(env).connect(addr); - ControlApiClient::new(ch) +async fn new_grpcio_control_api_client( + addr: String, +) -> ControlApiClient { + ControlApiClient::connect(addr).await.unwrap() } diff --git a/mock/control-api/src/main.rs b/mock/control-api/src/main.rs index 1e3edb88f..06c8b44ed 100644 --- a/mock/control-api/src/main.rs +++ b/mock/control-api/src/main.rs @@ -17,9 +17,10 @@ use clap::{ crate_version, Arg, }; use slog::{o, Drain}; -use slog_scope::GlobalLoggerGuard; +use slog_scope::{debug, GlobalLoggerGuard}; -fn main() { +#[actix_rt::main] +async fn main() { dotenv::dotenv().ok(); let opts = app_from_crate!() @@ -33,7 +34,7 @@ fn main() { .arg( Arg::with_name("medea_addr") .help("Address to Medea's gRPC control API.") - .default_value("0.0.0.0:6565") + .default_value("http://0.0.0.0:6565") .long("medea-addr") .short("m"), ) @@ -55,10 +56,9 @@ fn main() { let _log_guard = init_logger(); - let sys = actix::System::new("control-api-mock"); - let callback_server = callback::server::run(&opts); - api::run(&opts, callback_server); - sys.run().unwrap(); + let callback_server = callback::server::run(&opts).await; + println!("Starting medea-control-api-mock."); + api::run(&opts, callback_server).await; } /// Initializes [`slog`] logger which will output logs with [`slog_term`]'s diff --git a/src/api/control/callback/url.rs b/src/api/control/callback/url.rs index 8be316a96..2c1e3c9c7 100644 --- a/src/api/control/callback/url.rs +++ b/src/api/control/callback/url.rs @@ -22,8 +22,8 @@ impl GrpcCallbackUrl { /// If you wish to get address with protocol - just use [`Display`] /// implementation. #[inline] - pub fn addr(&self) -> &str { - &self.0 + pub fn addr(&self) -> String { + format!("http://{}", self.0) } } diff --git a/src/api/control/grpc/server.rs b/src/api/control/grpc/server.rs index a5e3e0c82..247bf659a 100644 --- a/src/api/control/grpc/server.rs +++ b/src/api/control/grpc/server.rs @@ -285,6 +285,7 @@ impl ControlApi for ControlApiService { &self, request: tonic::Request, ) -> Result, Status> { + debug!("Create Request: {:?}", request); let create_response = match self.create_element(request.into_inner()).await { Ok(sid) => CreateResponse { sid, error: None }, @@ -322,7 +323,7 @@ impl ControlApi for ControlApiService { }, Err(e) => GetResponse { elements: HashMap::new(), - error: None, + error: Some(e.into()), }, }; @@ -382,16 +383,16 @@ pub async fn run( let (grpc_shutdown_tx, grpc_shutdown_rx) = futures::channel::oneshot::channel(); - let server = Server::builder() - .add_service(service) - .serve_with_shutdown( - format!("{}:{}", bind_ip, bind_port).parse().unwrap(), - async move { + let addr = format!("{}:{}", bind_ip, bind_port).parse().unwrap(); + Arbiter::spawn(async move { + Server::builder() + .add_service(service) + .serve_with_shutdown(addr, async move { grpc_shutdown_rx.await; - }, - ) - .await - .unwrap(); + }) + .await + .unwrap(); + }); GrpcServer::start_in_arbiter(&Arbiter::new(), move |_| { GrpcServer(Some(grpc_shutdown_tx)) From 9140b33666979301490e2883d5e0840c2c46881b Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 27 Jan 2020 17:41:44 +0300 Subject: [PATCH 007/224] Fix warns, lints --- mock/control-api/src/api/endpoint.rs | 4 +-- mock/control-api/src/api/member.rs | 2 +- mock/control-api/src/api/mod.rs | 12 ++++---- mock/control-api/src/api/room.rs | 2 +- mock/control-api/src/callback/mod.rs | 3 +- mock/control-api/src/callback/server.rs | 5 +--- mock/control-api/src/client.rs | 16 +++------- mock/control-api/src/main.rs | 2 +- src/api/control/callback/clients/grpc.rs | 10 ++----- src/api/control/grpc/server.rs | 30 ++++++++----------- src/api/control/member.rs | 2 +- src/api/control/room.rs | 8 ++--- .../endpoints/webrtc/play_endpoint.rs | 1 - .../endpoints/webrtc/publish_endpoint.rs | 1 - src/signalling/elements/member.rs | 1 - 15 files changed, 36 insertions(+), 63 deletions(-) diff --git a/mock/control-api/src/api/endpoint.rs b/mock/control-api/src/api/endpoint.rs index 0e0d1d6ca..250bde52f 100644 --- a/mock/control-api/src/api/endpoint.rs +++ b/mock/control-api/src/api/endpoint.rs @@ -72,7 +72,7 @@ impl WebRtcPublishEndpoint { } impl From for WebRtcPublishEndpoint { - fn from(mut proto: WebRtcPublishEndpointProto) -> Self { + fn from(proto: WebRtcPublishEndpointProto) -> Self { Self { id: proto.id, p2p: P2pModeProto::from_i32(proto.p2p).unwrap_or_default().into(), @@ -115,7 +115,7 @@ impl WebRtcPlayEndpoint { } impl From for WebRtcPlayEndpoint { - fn from(mut proto: WebRtcPlayEndpointProto) -> Self { + fn from(proto: WebRtcPlayEndpointProto) -> Self { Self { id: proto.id, src: proto.src, diff --git a/mock/control-api/src/api/member.rs b/mock/control-api/src/api/member.rs index 3ffdf44cd..2cbd385b0 100644 --- a/mock/control-api/src/api/member.rs +++ b/mock/control-api/src/api/member.rs @@ -67,7 +67,7 @@ impl Member { } impl From for Member { - fn from(mut proto: MemberProto) -> Self { + fn from(proto: MemberProto) -> Self { let member_pipeline = proto .pipeline .into_iter() diff --git a/mock/control-api/src/api/mod.rs b/mock/control-api/src/api/mod.rs index ef602b06a..ad6d7b3c8 100644 --- a/mock/control-api/src/api/mod.rs +++ b/mock/control-api/src/api/mod.rs @@ -16,7 +16,6 @@ use actix_web::{ App, HttpResponse, HttpServer, }; use clap::ArgMatches; -use futures::Future; use medea_control_api_proto::grpc::medea::{ element::El as ElementOneOf, room::{element::El as RoomElementOneOf, Element as RoomElementProto}, @@ -37,8 +36,7 @@ use self::{ member::Member, room::Room, }; -use actix::fut::err; -use std::{rc::Rc, sync::Mutex}; +use std::sync::Mutex; /// Context of [`actix_web`] server. pub struct Context { @@ -243,7 +241,7 @@ pub struct ErrorResponse { } impl Into for ErrorProto { - fn into(mut self) -> ErrorResponse { + fn into(self) -> ErrorResponse { ErrorResponse { code: self.code, text: self.text, @@ -307,7 +305,7 @@ impl_into_http_response!(Response); impl_into_http_response!(SingleGetResponse); impl From for Response { - fn from(mut resp: ResponseProto) -> Self { + fn from(resp: ResponseProto) -> Self { Self { error: resp.error.map(|e| e.into()), } @@ -315,7 +313,7 @@ impl From for Response { } impl From for CreateResponse { - fn from(mut resp: CreateResponseProto) -> Self { + fn from(resp: CreateResponseProto) -> Self { if let Some(error) = resp.error { Self { sids: None, @@ -396,7 +394,7 @@ pub struct SingleGetResponse { } impl From for SingleGetResponse { - fn from(mut proto: GetResponseProto) -> Self { + fn from(proto: GetResponseProto) -> Self { if let Some(error) = proto.error { Self { element: None, diff --git a/mock/control-api/src/api/room.rs b/mock/control-api/src/api/room.rs index fbc223b46..871615d3c 100644 --- a/mock/control-api/src/api/room.rs +++ b/mock/control-api/src/api/room.rs @@ -68,7 +68,7 @@ impl From for RoomElement { } impl From for Room { - fn from(mut proto: RoomProto) -> Self { + fn from(proto: RoomProto) -> Self { let pipeline = proto .pipeline .into_iter() diff --git a/mock/control-api/src/callback/mod.rs b/mock/control-api/src/callback/mod.rs index a0c6c01ae..21cf63537 100644 --- a/mock/control-api/src/callback/mod.rs +++ b/mock/control-api/src/callback/mod.rs @@ -3,7 +3,6 @@ pub mod server; use medea_control_api_proto::grpc::medea_callback::{ - on_leave::Reason as OnLeaveReasonProto, request::Event as CallbackEventProto, Request as CallbackProto, }; use serde::Serialize; @@ -41,7 +40,7 @@ pub struct CallbackItem { } impl From for CallbackItem { - fn from(mut proto: CallbackProto) -> Self { + fn from(proto: CallbackProto) -> Self { Self { fid: proto.fid, at: proto.at, diff --git a/mock/control-api/src/callback/server.rs b/mock/control-api/src/callback/server.rs index e219c16db..4c3e1d581 100644 --- a/mock/control-api/src/callback/server.rs +++ b/mock/control-api/src/callback/server.rs @@ -6,7 +6,6 @@ use std::sync::{Arc, Mutex}; use actix::{Actor, Addr, Arbiter, Context, Handler, Message}; use clap::ArgMatches; -use futures::future::Future as _; use medea_control_api_proto::grpc::medea_callback::{ callback_server::{ Callback as CallbackService, CallbackServer as TonicCallbackServer, @@ -16,7 +15,6 @@ use medea_control_api_proto::grpc::medea_callback::{ use tonic::transport::Server; use crate::{callback::CallbackItem, prelude::*}; -use tonic::Status; /// Type which used in [`GrpcCallbackServer`] for [`CallbackItem`] storing. type CallbackItems = Arc>>; @@ -87,7 +85,6 @@ impl Handler for GrpcCallbackServer { } /// Run [`GrpcCallbackServer`]. -#[must_use] pub async fn run(args: &ArgMatches<'static>) -> Addr { let host = args.value_of("callback_host").unwrap(); let port: u32 = args.value_of("callback_port").unwrap().parse().unwrap(); @@ -98,7 +95,7 @@ pub async fn run(args: &ArgMatches<'static>) -> Addr { TonicCallbackServer::new(GrpcCallbackService::new(Arc::clone(&events))); let addr = format!("{}:{}", host, port).parse().unwrap(); - let server = Arbiter::spawn(async move { + Arbiter::spawn(async move { Server::builder() .add_service(service) .serve(addr) diff --git a/mock/control-api/src/client.rs b/mock/control-api/src/client.rs index 6b89acf7f..e1eed38dc 100644 --- a/mock/control-api/src/client.rs +++ b/mock/control-api/src/client.rs @@ -3,16 +3,11 @@ //! [Medea]: https://github.com/instrumentisto/medea //! [Control API]: https://tinyurl.com/yxsqplq7 -use std::sync::Arc; - -use futures::{Future, IntoFuture}; use medea_control_api_proto::grpc::medea::{ control_api_client::ControlApiClient, create_request::El as CreateRequestElProto, CreateRequest, CreateResponse, GetResponse, IdRequest, Response, }; -use protobuf::RepeatedField; -use slog_scope::debug; use tonic::{transport::Channel, Status}; use crate::api::Element; @@ -126,21 +121,18 @@ impl ControlClient { .await .create(tonic::Request::new(req)) .await - .map(|resp| resp.into_inner()) + .map(tonic::Response::into_inner) } /// Gets element from Control API by FID. pub async fn get(&mut self, fid: Fid) -> Result { let req = id_request(vec![fid.into()]); - let resp = self - .get_client() + self.get_client() .await .get(tonic::Request::new(req)) .await - .map(|resp| resp.into_inner()); - debug!("Get response {:?}", resp); - resp + .map(tonic::Response::into_inner) } /// Deletes element from Control API by FID. @@ -151,7 +143,7 @@ impl ControlClient { .await .delete(tonic::Request::new(req)) .await - .map(|resp| resp.into_inner()) + .map(tonic::Response::into_inner) } } diff --git a/mock/control-api/src/main.rs b/mock/control-api/src/main.rs index 06c8b44ed..2c7fc0aa9 100644 --- a/mock/control-api/src/main.rs +++ b/mock/control-api/src/main.rs @@ -17,7 +17,7 @@ use clap::{ crate_version, Arg, }; use slog::{o, Drain}; -use slog_scope::{debug, GlobalLoggerGuard}; +use slog_scope::GlobalLoggerGuard; #[actix_rt::main] async fn main() { diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index 8816d224b..370316ce2 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -2,11 +2,7 @@ use std::{fmt, sync::Arc}; -use futures::{ - compat::Future01CompatExt as _, - future::{FutureExt as _, LocalBoxFuture}, -}; -use grpcio::{ChannelBuilder, EnvBuilder}; +use futures::future::{FutureExt as _, LocalBoxFuture}; #[rustfmt::skip] use medea_control_api_proto::grpc::medea_callback::{ callback_client::CallbackClient as ProtoCallbackClient @@ -18,7 +14,7 @@ use crate::api::control::callback::{ CallbackRequest, }; use std::sync::Mutex; -use tonic::{transport::Channel, IntoRequest}; +use tonic::transport::Channel; /// gRPC client for sending [`CallbackRequest`]s. pub struct GrpcCallbackClient { @@ -40,7 +36,7 @@ impl GrpcCallbackClient { /// Note that this function doesn't check availability of gRPC server on /// provided [`GrpcCallbackUrl`]. pub async fn new(addr: &GrpcCallbackUrl) -> Self { - let addr = addr.addr().to_string(); + let addr = addr.addr(); let client = Arc::new(Mutex::new( ProtoCallbackClient::connect(addr).await.unwrap(), )); diff --git a/src/api/control/grpc/server.rs b/src/api/control/grpc/server.rs index 247bf659a..ccc3dc321 100644 --- a/src/api/control/grpc/server.rs +++ b/src/api/control/grpc/server.rs @@ -5,16 +5,12 @@ use std::{ collections::HashMap, convert::{From, TryFrom}, - sync::Arc, }; use actix::{Actor, Addr, Arbiter, Context, Handler, MailboxError}; use derive_more::{Display, From}; use failure::Fail; -use futures::{ - compat::Future01CompatExt as _, - future::{self, BoxFuture, FutureExt as _, TryFutureExt as _}, -}; +use futures::future::{self, BoxFuture, FutureExt as _, TryFutureExt as _}; use medea_control_api_proto::grpc::medea::{ control_api_server::{ ControlApi, ControlApiServer as TonicControlApiServer, @@ -36,17 +32,15 @@ use crate::{ EndpointId, EndpointSpec, MemberId, MemberSpec, RoomSpec, TryFromProtobufError, }, - conf::server::ControlApiServer, log::prelude::*, shutdown::ShutdownGracefully, signalling::room_service::{ CreateEndpointInRoom, CreateMemberInRoom, CreateRoom, DeleteElements, Get, RoomService, RoomServiceError, Sids, }, - utils::ResponseAnyFuture, AppContext, }; -use tonic::{Request, Status}; +use tonic::Status; /// Errors which can happen while processing requests to gRPC [Control API]. /// @@ -141,7 +135,7 @@ impl ControlApiService { /// Creates element based on provided [`CreateRequest`]. pub fn create_element( &self, - mut req: CreateRequest, + req: CreateRequest, ) -> BoxFuture<'static, Result> { let unparsed_parent_fid = req.parent_fid; let elem = if let Some(elem) = req.el { @@ -170,7 +164,7 @@ impl ControlApiService { match parent_fid { StatefulFid::Room(parent_fid) => match elem { - CreateRequestOneof::Member(mut member) => { + CreateRequestOneof::Member(member) => { let id: MemberId = member.id.clone().into(); match MemberSpec::try_from(member) .map_err(ErrorResponse::from) @@ -190,12 +184,12 @@ impl ControlApiService { }, StatefulFid::Member(parent_fid) => { let (endpoint, id) = match elem { - CreateRequestOneof::WebrtcPlay(mut play) => ( + CreateRequestOneof::WebrtcPlay(play) => ( WebRtcPlayEndpoint::try_from(&play) .map(EndpointSpec::from), play.id.into(), ), - CreateRequestOneof::WebrtcPub(mut publish) => ( + CreateRequestOneof::WebrtcPub(publish) => ( Ok(WebRtcPublishEndpoint::from(&publish)) .map(EndpointSpec::from), publish.id.into(), @@ -227,12 +221,12 @@ impl ControlApiService { /// Deletes element by [`IdRequest`]. pub fn delete_element( &self, - mut req: IdRequest, + req: IdRequest, ) -> BoxFuture<'static, Result<(), ErrorResponse>> { let room_service = self.room_service.clone(); async move { let mut delete_elements_msg = DeleteElements::new(); - for id in req.fid.into_iter() { + for id in req.fid { let fid = StatefulFid::try_from(id)?; delete_elements_msg.add_fid(fid); } @@ -252,13 +246,13 @@ impl ControlApiService { /// Returns requested by [`IdRequest`] [`Element`]s serialized to protobuf. pub fn get_element( &self, - mut req: IdRequest, + req: IdRequest, ) -> BoxFuture<'static, Result, ErrorResponse>> { let room_service = self.room_service.clone(); async move { let mut fids = Vec::new(); - for id in req.fid.into_iter() { + for id in req.fid { let fid = StatefulFid::try_from(id)?; fids.push(fid); } @@ -357,7 +351,7 @@ impl Handler for GrpcServer { "gRPC Control API server received ShutdownGracefully message so \ shutting down.", ); - if let Some(mut grpc_shutdown) = self.0.take() { + if let Some(grpc_shutdown) = self.0.take() { grpc_shutdown.send(()).unwrap(); } } @@ -388,7 +382,7 @@ pub async fn run( Server::builder() .add_service(service) .serve_with_shutdown(addr, async move { - grpc_shutdown_rx.await; + grpc_shutdown_rx.await.ok(); }) .await .unwrap(); diff --git a/src/api/control/member.rs b/src/api/control/member.rs index 70c0e49e9..06a3198d7 100644 --- a/src/api/control/member.rs +++ b/src/api/control/member.rs @@ -148,7 +148,7 @@ fn generate_member_credentials() -> String { impl TryFrom for MemberSpec { type Error = TryFromProtobufError; - fn try_from(mut member: MemberProto) -> Result { + fn try_from(member: MemberProto) -> Result { let mut pipeline = HashMap::new(); for (id, member_element) in member.pipeline { if let Some(elem) = member_element.el { diff --git a/src/api/control/room.rs b/src/api/control/room.rs index cdbff4780..9c93a0321 100644 --- a/src/api/control/room.rs +++ b/src/api/control/room.rs @@ -59,7 +59,7 @@ impl TryFrom for RoomSpec { fn try_from(proto: ElementProto) -> Result { let id = match proto { - ElementProto::Room(mut room) => { + ElementProto::Room(room) => { let mut pipeline = HashMap::new(); for (id, room_element) in room.pipeline { if let Some(elem) = room_element.el { @@ -77,9 +77,9 @@ impl TryFrom for RoomSpec { pipeline, }); } - ElementProto::Member(mut member) => member.id, - ElementProto::WebrtcPub(mut webrtc_pub) => webrtc_pub.id, - ElementProto::WebrtcPlay(mut webrtc_play) => webrtc_play.id, + ElementProto::Member(member) => member.id, + ElementProto::WebrtcPub(webrtc_pub) => webrtc_pub.id, + ElementProto::WebrtcPlay(webrtc_play) => webrtc_play.id, }; Err(TryFromProtobufError::ExpectedOtherElement( diff --git a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs index ffd60c8ee..9d5ebc0bd 100644 --- a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs @@ -23,7 +23,6 @@ use crate::{ }; use super::publish_endpoint::WebRtcPublishEndpoint; -use crate::api::control::RootElement; #[derive(Debug, Clone)] struct WebRtcPlayEndpointInner { diff --git a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs index 13d50d654..24c37f570 100644 --- a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs @@ -26,7 +26,6 @@ use crate::{ }; use super::play_endpoint::WebRtcPlayEndpoint; -use crate::api::control::error_codes::ErrorCode::ElementIdIsNotLocal; #[derive(Clone, Debug)] struct WebRtcPublishEndpointInner { diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index 70b0aa73e..107bdc6ae 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -34,7 +34,6 @@ use super::endpoints::{ webrtc::{WebRtcPlayEndpoint, WebRtcPublishEndpoint}, Endpoint, }; -use futures::AsyncReadExt; /// Errors which may occur while loading [`Member`]s from [`RoomSpec`]. #[derive(Debug, Display, Fail)] From 34c34cfb380c7f549c53a697a8a2f370a65a69a1 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 27 Jan 2020 19:56:17 +0300 Subject: [PATCH 008/224] Migrate medea E2E tests to tonic --- tests/e2e/callbacks/member.rs | 32 ++- tests/e2e/callbacks/mod.rs | 54 ++--- tests/e2e/grpc_control_api/create.rs | 186 +++++++++------- tests/e2e/grpc_control_api/delete.rs | 75 ++++--- tests/e2e/grpc_control_api/mod.rs | 284 +++++++++++++----------- tests/e2e/grpc_control_api/signaling.rs | 181 +++++++-------- 6 files changed, 428 insertions(+), 384 deletions(-) diff --git a/tests/e2e/callbacks/member.rs b/tests/e2e/callbacks/member.rs index 7ed5ac871..5fee35cb0 100644 --- a/tests/e2e/callbacks/member.rs +++ b/tests/e2e/callbacks/member.rs @@ -5,8 +5,8 @@ use std::time::Duration; use actix::{clock::delay_for, Addr, Context}; use actix_http::ws::CloseCode; use medea_client_api_proto::Event; -use medea_control_api_proto::grpc::callback::{ - OnLeave_Reason as OnLeaveReason, Request, +use medea_control_api_proto::grpc::medea_callback::{ + on_leave::Reason as OnLeaveReason, request::Event as EventProto, Request, }; use crate::{ @@ -36,7 +36,7 @@ type CallbackTestItem = (Addr, Addr); /// will receive all callbacks from Medea. async fn callback_test(name: &'static str, port: u16) -> CallbackTestItem { let callback_server = super::run(port); - let control_client = ControlClient::new(); + let mut control_client = ControlClient::new().await; let member = RoomBuilder::default() .id(name) .add_member( @@ -50,7 +50,7 @@ async fn callback_test(name: &'static str, port: u16) -> CallbackTestItem { .build() .unwrap() .build_request(String::new()); - let create_response = control_client.create(&member); + let create_response = control_client.create(member).await; let on_event = move |_: &Event, _: &mut Context, _: Vec<&Event>| {}; @@ -80,8 +80,16 @@ async fn on_join() { let (_, callback_server) = callback_test(TEST_NAME, 9096).await; delay_for(Duration::from_millis(300)).await; let callbacks = callback_server.send(GetCallbacks).await.unwrap().unwrap(); - let on_joins_count = - callbacks.into_iter().filter(Request::has_on_join).count(); + let on_joins_count = callbacks + .into_iter() + .filter(|r| { + if let EventProto::OnJoin(_) = r.event.as_ref().unwrap() { + true + } else { + false + } + }) + .count(); assert_eq!(on_joins_count, 1); } @@ -110,13 +118,13 @@ async fn on_leave_normally_disconnected() { let on_leaves_count = callbacks .into_iter() .filter_map(|mut req| { - if req.has_on_leave() { - Some(req.take_on_leave().reason) + if let Some(EventProto::OnLeave(on_leave)) = req.event { + Some(on_leave.reason) } else { None } }) - .filter(|reason| reason == &OnLeaveReason::DISCONNECTED) + .filter(|reason| reason == &(OnLeaveReason::Disconnected as i32)) .count(); assert_eq!(on_leaves_count, 1); } @@ -147,13 +155,13 @@ async fn on_leave_on_connection_loss() { let on_leaves_count = callbacks .into_iter() .filter_map(|mut req| { - if req.has_on_leave() { - Some(req.take_on_leave().reason) + if let Some(EventProto::OnLeave(on_leave)) = req.event { + Some(on_leave.reason) } else { None } }) - .filter(|reason| reason == &OnLeaveReason::LOST_CONNECTION) + .filter(|reason| reason == &(OnLeaveReason::LostConnection as i32)) .count(); assert_eq!(on_leaves_count, 1); } diff --git a/tests/e2e/callbacks/mod.rs b/tests/e2e/callbacks/mod.rs index a17213476..d921116d1 100644 --- a/tests/e2e/callbacks/mod.rs +++ b/tests/e2e/callbacks/mod.rs @@ -8,27 +8,22 @@ use actix::{Actor, Addr, Arbiter, Context, Handler, Message}; use futures::{ compat::Future01CompatExt as _, FutureExt as _, TryFutureExt as _, }; -use grpcio::{Environment, RpcContext, Server, ServerBuilder, UnarySink}; -use medea_control_api_proto::grpc::{ - callback::{Request, Response}, - callback_grpc::{create_callback, Callback}, +use medea_control_api_proto::grpc::medea_callback::{ + callback_server::{Callback, CallbackServer as TonicCallbackServer}, + Request, Response, }; +use tonic::{transport::Server, Status}; /// Requests which [`GrpcCallbackServer`] will receive. type CallbackItems = Arc>>; /// gRPC Control API callback server for tests. pub struct GrpcCallbackServer { - server: Server, callbacks: CallbackItems, } impl Actor for GrpcCallbackServer { type Context = Context; - - fn started(&mut self, _: &mut Self::Context) { - self.server.start(); - } } /// Returns all [`Request`]s which this [`GrpcCallbackServer`] received. @@ -60,40 +55,33 @@ impl CallbackServer { } } +#[tonic::async_trait] impl Callback for CallbackServer { - fn on_event( - &mut self, - ctx: RpcContext, - req: Request, - sink: UnarySink, - ) { - self.callbacks.lock().unwrap().push(req); - ctx.spawn( - async move { - sink.success(Response::new()).compat().await.unwrap(); - Ok(()) - } - .boxed() - .compat(), - ) + async fn on_event( + &self, + request: tonic::Request, + ) -> Result, Status> { + self.callbacks.lock().unwrap().push(request.into_inner()); + Ok(tonic::Response::new(Response {})) } } /// Runs [`GrpcCallbackServer`] on `localhost` and provided port. pub fn run(port: u16) -> Addr { - let cq_count = 2; let callbacks = Arc::new(Mutex::new(Vec::new())); - let service = create_callback(CallbackServer::new(Arc::clone(&callbacks))); - let env = Arc::new(Environment::new(cq_count)); + let service = + TonicCallbackServer::new(CallbackServer::new(Arc::clone(&callbacks))); - let server = ServerBuilder::new(env) - .register_service(service) - .bind("127.0.0.1", port) - .build() - .unwrap(); + Arbiter::spawn(async move { + Server::builder() + .add_service(service) + .serve(format!("127.0.0.1:{}", port).parse().unwrap()) + .await + .unwrap() + }); GrpcCallbackServer::start_in_arbiter(&Arbiter::new(), move |_| { - GrpcCallbackServer { server, callbacks } + GrpcCallbackServer { callbacks } }) } diff --git a/tests/e2e/grpc_control_api/create.rs b/tests/e2e/grpc_control_api/create.rs index af041e5fd..b628c080c 100644 --- a/tests/e2e/grpc_control_api/create.rs +++ b/tests/e2e/grpc_control_api/create.rs @@ -6,7 +6,11 @@ //! [Control API]: https://tinyurl.com/yxsqplq7 use medea::api::control::error_codes::ErrorCode; -use medea_control_api_proto::grpc::api::WebRtcPublishEndpoint_P2P; +use medea_control_api_proto::grpc::medea::{ + element::El as RootEl, member::element::El as MemberEl, + room::element::El as RoomEl, + web_rtc_publish_endpoint::P2p as WebRtcPublishEndpoint_P2P, +}; use super::{ create_room_req, ControlClient, MemberBuilder, RoomBuilder, @@ -15,13 +19,14 @@ use super::{ mod room { use super::*; + use crate::grpc_control_api::Elem; - #[test] - fn room() { + #[actix_rt::test] + async fn room() { const TEST_NAME: &str = "create-room"; - let client = ControlClient::new(); - let sids = client.create(&create_room_req(TEST_NAME)); + let mut client = ControlClient::new().await; + let sids = client.create(create_room_req(TEST_NAME)).await; assert_eq!(sids.len(), 2); sids.get(&"publisher".to_string()).unwrap(); let responder_sid = @@ -31,33 +36,42 @@ mod room { &format!("ws://127.0.0.1:8080/ws/{}/responder/test", TEST_NAME) ); - let mut get_resp = client.get(TEST_NAME); - let room = get_resp.take_room(); + let mut get_resp = client.get(TEST_NAME).await; + let mut room = get_resp.take_room(); - let responder = - room.get_pipeline().get("responder").unwrap().get_member(); - assert_eq!(responder.get_credentials(), "test"); - let responder_pipeline = responder.get_pipeline(); + let responder = room.pipeline.remove("responder").unwrap(); + let responder = match responder.el.unwrap() { + RoomEl::Member(member) => member, + _ => panic!(), + }; + assert_eq!(responder.credentials.as_str(), "test"); + let mut responder_pipeline = responder.pipeline; assert_eq!(responder_pipeline.len(), 1); - let responder_play = - responder_pipeline.get("play").unwrap().get_webrtc_play(); + let responder_play = responder_pipeline.remove("play").unwrap(); + let responder_play = match responder_play.el.unwrap() { + MemberEl::WebrtcPlay(play) => play, + _ => panic!(), + }; assert_eq!( - responder_play.get_src(), + responder_play.src, format!("local://{}/publisher/publish", TEST_NAME) ); - let publisher = - room.get_pipeline().get("publisher").unwrap().get_member(); - assert_ne!(publisher.get_credentials(), "test"); - assert_ne!(publisher.get_credentials(), ""); - let publisher_pipeline = responder.get_pipeline(); + let publisher = room.pipeline.remove("publisher").unwrap(); + let publisher = match publisher.el.unwrap() { + RoomEl::Member(member) => member, + _ => panic!(), + }; + assert_ne!(publisher.credentials.as_str(), "test"); + assert_ne!(publisher.credentials.as_str(), ""); + let publisher_pipeline = publisher.pipeline; assert_eq!(publisher_pipeline.len(), 1); } - #[test] - fn cant_create_rooms_with_duplicate_ids() { + #[actix_rt::test] + async fn cant_create_rooms_with_duplicate_ids() { const TEST_NAME: &str = "cant_create_rooms_with_duplicate_ids"; - let client = ControlClient::new(); + let mut client = ControlClient::new().await; let create_room = RoomBuilder::default() .id(TEST_NAME) @@ -65,19 +79,19 @@ mod room { .unwrap() .build_request(""); - client.create(&create_room); + client.create(create_room.clone()); - if let Err(err) = client.try_create(&create_room) { + if let Err(err) = client.try_create(create_room).await { assert_eq!(err.code, ErrorCode::RoomAlreadyExists as u32) } else { panic!("should err") } } - #[test] - fn element_id_mismatch() { + #[actix_rt::test] + async fn element_id_mismatch() { const TEST_NAME: &str = "element_id_mismatch"; - let client = ControlClient::new(); + let mut client = ControlClient::new().await; let create_room = RoomBuilder::default() .id(TEST_NAME) @@ -85,7 +99,7 @@ mod room { .unwrap() .build_request(TEST_NAME); - if let Err(err) = client.try_create(&create_room) { + if let Err(err) = client.try_create(create_room).await { assert_eq!(err.code, ErrorCode::ElementIdMismatch as u32) } else { panic!("should err") @@ -97,12 +111,12 @@ mod member { use super::*; - #[test] - fn member() { + #[actix_rt::test] + async fn member() { const TEST_NAME: &str = "create-member"; - let client = ControlClient::new(); - client.create(&create_room_req(TEST_NAME)); + let mut client = ControlClient::new().await; + client.create(create_room_req(TEST_NAME)); let add_member = MemberBuilder::default() .id("test-member") @@ -118,7 +132,7 @@ mod member { .unwrap() .build_request(TEST_NAME); - let sids = client.create(&add_member); + let sids = client.create(add_member).await; let e2e_test_member_sid = sids.get(&"test-member".to_string()).unwrap().as_str(); assert_eq!( @@ -128,15 +142,16 @@ mod member { let member = client .get(&format!("{}/test-member", TEST_NAME)) + .await .take_member(); - assert_eq!(member.get_pipeline().len(), 1); - assert_eq!(member.get_credentials(), "qwerty"); + assert_eq!(member.pipeline.len(), 1); + assert_eq!(member.credentials.as_str(), "qwerty"); } - #[test] - fn cant_create_member_in_non_existent_room() { + #[actix_rt::test] + async fn cant_create_member_in_non_existent_room() { const TEST_NAME: &str = "cant_create_member_in_non_existent_room"; - let client = ControlClient::new(); + let mut client = ControlClient::new().await; let create_member = MemberBuilder::default() .id("caller") @@ -144,18 +159,18 @@ mod member { .unwrap() .build_request(TEST_NAME); - if let Err(err) = client.try_create(&create_member) { + if let Err(err) = client.try_create(create_member).await { assert_eq!(err.code, ErrorCode::RoomNotFound as u32) } else { panic!("should err") } } - #[test] - fn cant_create_members_with_duplicate_ids() { + #[actix_rt::test] + async fn cant_create_members_with_duplicate_ids() { const TEST_NAME: &str = "cant_create_members_with_duplicate_ids"; - let client = ControlClient::new(); + let mut client = ControlClient::new().await; let create_room = RoomBuilder::default() .id(TEST_NAME) @@ -163,7 +178,7 @@ mod member { .unwrap() .build_request(""); - client.create(&create_room); + client.create(create_room).await; let create_member = MemberBuilder::default() .id("caller") @@ -171,26 +186,26 @@ mod member { .unwrap() .build_request(TEST_NAME); - client.create(&create_member); + client.create(create_member.clone()).await; - if let Err(err) = client.try_create(&create_member) { + if let Err(err) = client.try_create(create_member).await { assert_eq!(err.code, ErrorCode::MemberAlreadyExists as u32) } else { panic!("should err") } } - #[test] - fn element_id_mismatch() { - let client = ControlClient::new(); + #[actix_rt::test] + async fn element_id_mismatch() { + let mut client = ControlClient::new().await; - let create_member = MemberBuilder::default() + let mut create_member = MemberBuilder::default() .id("asd") .build() .unwrap() .build_request("qwe/qwe"); - if let Err(err) = client.try_create(&create_member) { + if let Err(err) = client.try_create(create_member).await { assert_eq!(err.code, ErrorCode::ElementIdMismatch as u32) } else { panic!("should err") @@ -202,34 +217,35 @@ mod endpoint { use super::*; - #[test] - fn endpoint() { + #[actix_rt::test] + async fn endpoint() { const TEST_NAME: &str = "create-endpoint"; - let client = ControlClient::new(); - client.create(&create_room_req(TEST_NAME)); + let mut client = ControlClient::new().await; + client.create(create_room_req(TEST_NAME)).await; let create_req = WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::NEVER) + .p2p_mode(WebRtcPublishEndpoint_P2P::Never) .build() .unwrap() .build_request(format!("{}/responder", TEST_NAME)); - let sids = client.create(&create_req); + let sids = client.create(create_req).await; assert_eq!(sids.len(), 0); let endpoint = client .get(&format!("{}/responder/publish", TEST_NAME)) + .await .take_webrtc_pub(); - assert_eq!(endpoint.get_p2p(), WebRtcPublishEndpoint_P2P::NEVER); + assert_eq!(endpoint.p2p, WebRtcPublishEndpoint_P2P::Never as i32); } - #[test] - fn cant_create_endpoint_in_non_existent_member() { + #[actix_rt::test] + async fn cant_create_endpoint_in_non_existent_member() { const TEST_NAME: &str = "cant_create_endpoint_in_non_existent_member"; - let client = ControlClient::new(); + let mut client = ControlClient::new().await; let create_room = RoomBuilder::default() .id(TEST_NAME) @@ -237,47 +253,47 @@ mod endpoint { .unwrap() .build_request(""); - client.create(&create_room); + client.create(create_room).await; let create_play = WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::ALWAYS) + .p2p_mode(WebRtcPublishEndpoint_P2P::Always) .build() .unwrap() .build_request(format!("{}/member", TEST_NAME)); - if let Err(err) = client.try_create(&create_play) { + if let Err(err) = client.try_create(create_play).await { assert_eq!(err.code, ErrorCode::MemberNotFound as u32) } else { panic!("should err") } } - #[test] - fn cant_create_endpoint_in_non_existent_room() { + #[actix_rt::test] + async fn cant_create_endpoint_in_non_existent_room() { const TEST_NAME: &str = "cant_create_endpoint_in_non_existent_room"; - let client = ControlClient::new(); + let mut client = ControlClient::new().await; let create_publish = WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::ALWAYS) + .p2p_mode(WebRtcPublishEndpoint_P2P::Always) .build() .unwrap() .build_request(format!("{}/member", TEST_NAME)); - if let Err(err) = client.try_create(&create_publish) { + if let Err(err) = client.try_create(create_publish).await { assert_eq!(err.code, ErrorCode::RoomNotFound as u32) } else { panic!("should err") } } - #[test] - fn cant_create_endpoints_with_duplicate_ids() { + #[actix_rt::test] + async fn cant_create_endpoints_with_duplicate_ids() { const TEST_NAME: &str = "cant_create_endpoints_with_duplicate_ids"; - let client = ControlClient::new(); + let mut client = ControlClient::new().await; let create_room = RoomBuilder::default() .id(TEST_NAME) @@ -286,30 +302,30 @@ mod endpoint { .unwrap() .build_request(""); - client.create(&create_room); + client.create(create_room).await; let create_endpoint = WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::ALWAYS) + .p2p_mode(WebRtcPublishEndpoint_P2P::Always) .build() .unwrap() .build_request(format!("{}/member", TEST_NAME)); - client.create(&create_endpoint); + client.create(create_endpoint.clone()).await; - if let Err(err) = client.try_create(&create_endpoint) { + if let Err(err) = client.try_create(create_endpoint).await { assert_eq!(err.code, ErrorCode::EndpointAlreadyExists as u32) } else { panic!("should err") } } - #[test] - fn cant_create_play_endpoint_when_no_pusblish_endpoints() { + #[actix_rt::test] + async fn cant_create_play_endpoint_when_no_pusblish_endpoints() { const TEST_NAME: &str = "cant_create_play_endpoint_when_no_pusblish_endpoints"; - let client = ControlClient::new(); + let mut client = ControlClient::new().await; let create_room = RoomBuilder::default() .id(TEST_NAME) @@ -318,7 +334,7 @@ mod endpoint { .unwrap() .build_request(""); - client.create(&create_room); + client.create(create_room).await; let create_endpoint = WebRtcPlayEndpointBuilder::default() .id("play") @@ -327,25 +343,25 @@ mod endpoint { .unwrap() .build_request(format!("{}/member", TEST_NAME)); - if let Err(err) = client.try_create(&create_endpoint) { + if let Err(err) = client.try_create(create_endpoint).await { assert_eq!(err.code, ErrorCode::EndpointNotFound as u32) } else { panic!("should err") } } - #[test] - fn element_id_mismatch() { - let client = ControlClient::new(); + #[actix_rt::test] + async fn element_id_mismatch() { + let mut client = ControlClient::new().await; let create_endpoint = WebRtcPublishEndpointBuilder::default() .id("asd") - .p2p_mode(WebRtcPublishEndpoint_P2P::ALWAYS) + .p2p_mode(WebRtcPublishEndpoint_P2P::Always) .build() .unwrap() .build_request("qwe"); - if let Err(err) = client.try_create(&create_endpoint) { + if let Err(err) = client.try_create(create_endpoint).await { assert_eq!(err.code, ErrorCode::ElementIdMismatch as u32) } else { panic!("should err") diff --git a/tests/e2e/grpc_control_api/delete.rs b/tests/e2e/grpc_control_api/delete.rs index d8df5b7b6..38893ce35 100644 --- a/tests/e2e/grpc_control_api/delete.rs +++ b/tests/e2e/grpc_control_api/delete.rs @@ -26,49 +26,51 @@ use super::{create_room_req, ControlClient}; /// [Medea]: https://github.com/instrumentisto/medea /// [Control API]: https://tinyurl.com/yxsqplq7 /// [`ErrorCode`]: medea::api::control::error_codes::ErrorCode -fn test_for_delete( +async fn test_for_delete( room_id: &str, element_id: &str, error_code: MedeaErrorCode, ) { - let client = ControlClient::new(); - client.create(&create_room_req(room_id)); + let mut client = ControlClient::new().await; + client.create(create_room_req(room_id)).await; - client.try_get(element_id).unwrap(); + client.try_get(element_id).await.unwrap(); - client.delete(&[element_id]).unwrap(); + client.delete(&[element_id]).await.unwrap(); - let get_room_err = match client.try_get(element_id) { + let get_room_err = match client.try_get(element_id).await { Ok(_) => panic!("{} not deleted!", element_id), Err(e) => e, }; assert_eq!(get_room_err.code, error_code as u32); } -#[test] -fn room() { +#[actix_rt::test] +async fn room() { const TEST_NAME: &str = "delete-room"; - test_for_delete(TEST_NAME, TEST_NAME, ErrorCode::RoomNotFound); + test_for_delete(TEST_NAME, TEST_NAME, ErrorCode::RoomNotFound).await; } -#[test] -fn member() { +#[actix_rt::test] +async fn member() { const TEST_NAME: &str = "delete-member"; test_for_delete( TEST_NAME, &format!("{}/publisher", TEST_NAME), ErrorCode::MemberNotFound, - ); + ) + .await; } -#[test] -fn endpoint() { +#[actix_rt::test] +async fn endpoint() { const TEST_NAME: &str = "delete-endpoint"; test_for_delete( &TEST_NAME, &format!("{}/publisher/publish", TEST_NAME), ErrorCode::EndpointNotFound, - ); + ) + .await; } /// Tests that `Delete` method on parent element also deletes all nested @@ -89,17 +91,17 @@ fn endpoint() { /// [Medea]: https://github.com/instrumentisto/medea /// [Control API]: https://tinyurl.com/yxsqplq7 /// [`ErrorCode`]: medea::api::control::error_codes::ErrorCode -fn test_cascade_delete( +async fn test_cascade_delete( room_id: &str, elements_uris: &[&str], code: MedeaErrorCode, root_elem_uri: &str, ) { - let client = ControlClient::new(); - client.create(&create_room_req(room_id)); - client.delete(elements_uris).unwrap(); + let mut client = ControlClient::new().await; + client.create(create_room_req(room_id)).await; + client.delete(elements_uris).await.unwrap(); - match client.try_get(root_elem_uri) { + match client.try_get(root_elem_uri).await { Ok(_) => panic!("Member not deleted!"), Err(e) => { assert_eq!(e.code, code as u32); @@ -107,8 +109,8 @@ fn test_cascade_delete( } } -#[test] -fn cascade_delete_endpoints_when_deleting_member() { +#[actix_rt::test] +async fn cascade_delete_endpoints_when_deleting_member() { const TEST_NAME: &str = "member-and-endpoint-same-time"; test_cascade_delete( @@ -119,11 +121,12 @@ fn cascade_delete_endpoints_when_deleting_member() { ], MedeaErrorCode::MemberNotFound, &format!("{}/publisher", TEST_NAME), - ); + ) + .await; } -#[test] -fn cascade_delete_everything_when_deleting_room() { +#[actix_rt::test] +async fn cascade_delete_everything_when_deleting_room() { const TEST_NAME: &str = "room-and-inner-elements-same-time"; test_cascade_delete( @@ -135,26 +138,28 @@ fn cascade_delete_everything_when_deleting_room() { ], MedeaErrorCode::RoomNotFound, TEST_NAME, - ); + ) + .await; } -#[test] -fn cant_delete_members_from_different_rooms_in_single_request() { - let client = ControlClient::new(); +#[actix_rt::test] +async fn cant_delete_members_from_different_rooms_in_single_request() { + let mut client = ControlClient::new().await; - if let Err(err) = client.delete(&["room1/member1", "room2/member1"]) { + if let Err(err) = client.delete(&["room1/member1", "room2/member1"]).await { assert_eq!(err.code, MedeaErrorCode::ProvidedNotSameRoomIds as u32); } else { panic!("should err") } } -#[test] -fn cant_delete_endpoints_from_different_rooms_in_single_request() { - let client = ControlClient::new(); +#[actix_rt::test] +async fn cant_delete_endpoints_from_different_rooms_in_single_request() { + let mut client = ControlClient::new().await; - if let Err(err) = - client.delete(&["room1/member1/endpoint1", "room2/member1/endpoint1"]) + if let Err(err) = client + .delete(&["room1/member1/endpoint1", "room2/member1/endpoint1"]) + .await { assert_eq!(err.code, MedeaErrorCode::ProvidedNotSameRoomIds as u32); } else { diff --git a/tests/e2e/grpc_control_api/mod.rs b/tests/e2e/grpc_control_api/mod.rs index ee0231378..e877e735e 100644 --- a/tests/e2e/grpc_control_api/mod.rs +++ b/tests/e2e/grpc_control_api/mod.rs @@ -10,24 +10,57 @@ mod signaling; use std::{collections::HashMap, sync::Arc}; use derive_builder::*; -use grpcio::{ChannelBuilder, EnvBuilder}; -use medea_control_api_proto::grpc::{ - api::{ - CreateRequest, Element, Error, IdRequest, Member as GrpcMember, - Member_Element, Room as GrpcRoom, Room_Element, - WebRtcPlayEndpoint as GrpcWebRtcPlayEndpoint, - WebRtcPublishEndpoint as GrpcWebRtcPublishEndpoint, - WebRtcPublishEndpoint_P2P, - }, - api_grpc::ControlApiClient, +use medea::conf::ControlApi; +use medea_control_api_proto::grpc::medea::{ + control_api_client::ControlApiClient, + create_request::El as CreateRequestEl, + element::El as RootEl, + member::{element::El as MemberEl, Element as Member_Element}, + room::{element::El as RoomEl, Element as Room_Element}, + web_rtc_publish_endpoint::P2p as WebRtcPublishEndpoint_P2P, + CreateRequest, Element, Error, IdRequest, Member as GrpcMember, + Room as GrpcRoom, WebRtcPlayEndpoint as GrpcWebRtcPlayEndpoint, + WebRtcPublishEndpoint as GrpcWebRtcPublishEndpoint, }; -use protobuf::RepeatedField; +use tonic::transport::Channel; + +pub struct Elem(pub Element); + +impl Elem { + pub fn take_room(self) -> GrpcRoom { + match self.0.el.unwrap() { + RootEl::Room(room) => room, + _ => panic!("Not Room element!"), + } + } + + pub fn take_member(self) -> GrpcMember { + match self.0.el.unwrap() { + RootEl::Member(member) => member, + _ => panic!("Not Room element!"), + } + } + + pub fn take_webrtc_pub(self) -> GrpcWebRtcPublishEndpoint { + match self.0.el.unwrap() { + RootEl::WebrtcPub(webrtc_pub) => webrtc_pub, + _ => panic!("Not Room element!"), + } + } + + pub fn take_webrtc_play(self) -> GrpcWebRtcPlayEndpoint { + match self.0.el.unwrap() { + RootEl::WebrtcPlay(webrtc_play) => webrtc_play, + _ => panic!("Not Room element!"), + } + } +} /// Client for [Medea]'s gRPC [Control API]. /// /// [Medea]: https://github.com/instrumentisto/medea #[derive(Clone)] -pub struct ControlClient(ControlApiClient); +pub struct ControlClient(ControlApiClient); impl ControlClient { /// Create new [`ControlClient`]. @@ -37,10 +70,12 @@ impl ControlClient { /// Note that this function don't connects to the server. This mean that /// when you call [`ControlClient::new`] and server not working you will /// don't know it until try to send something with this client. - pub fn new() -> Self { - let env = Arc::new(EnvBuilder::new().build()); - let ch = ChannelBuilder::new(env).connect("127.0.0.1:6565"); - Self(ControlApiClient::new(ch)) + pub async fn new() -> Self { + Self( + ControlApiClient::connect("http://127.0.0.1:6565") + .await + .unwrap(), + ) } /// Gets some [`Element`] by local URI. @@ -49,17 +84,16 @@ impl ControlClient { /// /// - if [`GetResponse`] has error /// - if connection with server failed - pub fn get(&self, uri: &str) -> Element { - let mut get_room_request = IdRequest::new(); - let mut room = RepeatedField::new(); - room.push(uri.to_string()); - get_room_request.set_fid(room); - - let mut resp = self.0.get(&get_room_request).unwrap(); - if resp.has_error() { - panic!("{:?}", resp.get_error()); + pub async fn get(&mut self, uri: &str) -> Elem { + let room = vec![uri.to_string()]; + let get_room_request = IdRequest { fid: room }; + + let mut resp = self.0.get(get_room_request).await.unwrap().into_inner(); + if let Some(err) = resp.error { + panic!("{:?}", err); } - resp.take_elements().remove(&uri.to_string()).unwrap() + + Elem(resp.elements.remove(&uri.to_string()).unwrap()) } /// Tries to get some [`Element`] by local URI. @@ -67,17 +101,16 @@ impl ControlClient { /// # Panics /// /// - if connection with server failed. - pub fn try_get(&self, uri: &str) -> Result { - let mut get_room_request = IdRequest::new(); - let mut room = RepeatedField::new(); - room.push(uri.to_string()); - get_room_request.set_fid(room); - - let mut resp = self.0.get(&get_room_request).unwrap(); - if resp.has_error() { - return Err(resp.take_error()); + pub async fn try_get(&mut self, uri: &str) -> Result { + let room = vec![uri.to_string()]; + let get_room_request = IdRequest { fid: room }; + + let mut resp = self.0.get(get_room_request).await.unwrap().into_inner(); + if let Some(e) = resp.error { + return Err(e); } - Ok(resp.take_elements().remove(&uri.to_string()).unwrap()) + + Ok(resp.elements.remove(&uri.to_string()).unwrap()) } /// Creates `Element` and returns it sids. @@ -86,10 +119,13 @@ impl ControlClient { /// /// - if [`CreateResponse`] has error. /// - if connection with server failed. - pub fn create(&self, req: &CreateRequest) -> HashMap { - let resp = self.0.create(&req).unwrap(); - if resp.has_error() { - panic!("{:?}", resp.get_error()); + pub async fn create( + &mut self, + req: CreateRequest, + ) -> HashMap { + let resp = self.0.create(req).await.unwrap().into_inner(); + if let Some(e) = resp.error { + panic!("{:?}", e); } resp.sid @@ -100,14 +136,14 @@ impl ControlClient { /// # Panics /// /// - if connection with server failed. - pub fn try_create( - &self, - req: &CreateRequest, + pub async fn try_create( + &mut self, + req: CreateRequest, ) -> Result, Error> { - let mut resp = self.0.create(&req).unwrap(); + let mut resp = self.0.create(req).await.unwrap().into_inner(); - if resp.has_error() { - Err(resp.take_error()) + if let Some(e) = resp.error { + Err(e) } else { Ok(resp.sid) } @@ -119,15 +155,13 @@ impl ControlClient { /// /// - if [`Response`] has error /// - if connection with server failed. - pub fn delete(&self, ids: &[&str]) -> Result<(), Error> { - let mut delete_req = IdRequest::new(); - let mut delete_ids = RepeatedField::new(); - ids.iter().for_each(|id| delete_ids.push((*id).to_string())); - delete_req.set_fid(delete_ids); - - let mut resp = self.0.delete(&delete_req).unwrap(); - if resp.has_error() { - Err(resp.take_error()) + pub async fn delete(&mut self, ids: &[&str]) -> Result<(), Error> { + let delete_ids = ids.iter().map(|id| id.to_string()).collect(); + let delete_req = IdRequest { fid: delete_ids }; + + let mut resp = self.0.delete(delete_req).await.unwrap().into_inner(); + if let Some(e) = resp.error { + Err(e) } else { Ok(()) } @@ -145,25 +179,26 @@ pub struct Room { impl Room { pub fn build_request>(self, uri: T) -> CreateRequest { - let mut request = CreateRequest::default(); - - let mut grpc_room = GrpcRoom::new(); - let mut members = HashMap::new(); - - for (id, member) in self.members { - let mut room_element = Room_Element::new(); - room_element.set_member(member.into()); - - members.insert(id, room_element); + let members = self + .members + .into_iter() + .map(|(id, member)| { + let room_element = Room_Element { + el: Some(RoomEl::Member(member.into())), + }; + + (id, room_element) + }) + .collect(); + let grpc_room = GrpcRoom { + id: self.id, + pipeline: members, + }; + + CreateRequest { + parent_fid: uri.into(), + el: Some(CreateRequestEl::Room(grpc_room)), } - - grpc_room.set_id(self.id); - grpc_room.set_pipeline(members); - - request.set_parent_fid(uri.into()); - request.set_room(grpc_room); - - request } } @@ -198,39 +233,28 @@ pub struct Member { impl Into for Member { fn into(self) -> GrpcMember { - let mut grpc_member = GrpcMember::new(); - - let mut pipeline = HashMap::new(); - - for (id, element) in self.endpoints { - pipeline.insert(id, element.into()); - } - - if let Some(credentials) = self.credentials { - grpc_member.set_credentials(credentials) - } - - grpc_member.set_pipeline(pipeline); - grpc_member.set_id(self.id); - if let Some(on_join) = self.on_join { - grpc_member.set_on_join(on_join) + let pipeline = self + .endpoints + .into_iter() + .map(|(id, element)| (id, element.into())) + .collect(); + + GrpcMember { + id: self.id, + pipeline, + on_leave: self.on_leave.unwrap_or_default(), + on_join: self.on_join.unwrap_or_default(), + credentials: self.credentials.unwrap_or_default(), } - if let Some(on_leave) = self.on_leave { - grpc_member.set_on_leave(on_leave) - } - - grpc_member } } impl Member { fn build_request>(self, url: T) -> CreateRequest { - let mut request = CreateRequest::default(); - - request.set_parent_fid(url.into()); - request.set_member(self.into()); - - request + CreateRequest { + parent_fid: url.into(), + el: Some(CreateRequestEl::Member(self.into())), + } } } @@ -262,18 +286,18 @@ impl Endpoint { impl Into for Endpoint { fn into(self) -> Member_Element { - let mut member_elem = Member_Element::new(); - - match self { + let member_el = match self { Self::WebRtcPlayElement(element) => { - member_elem.set_webrtc_play(element.into()); + MemberEl::WebrtcPlay(element.into()) } Self::WebRtcPublishElement(element) => { - member_elem.set_webrtc_pub(element.into()) + MemberEl::WebrtcPub(element.into()) } - } + }; - member_elem + Member_Element { + el: Some(member_el), + } } } @@ -286,22 +310,22 @@ pub struct WebRtcPlayEndpoint { impl WebRtcPlayEndpoint { pub fn build_request>(self, url: T) -> CreateRequest { - let mut request = CreateRequest::default(); - - request.set_parent_fid(url.into()); - request.set_webrtc_play(self.into()); - - request + CreateRequest { + el: Some(CreateRequestEl::WebrtcPlay(self.into())), + parent_fid: url.into(), + } } } impl Into for WebRtcPlayEndpoint { fn into(self) -> GrpcWebRtcPlayEndpoint { - let mut endpoint = GrpcWebRtcPlayEndpoint::new(); - endpoint.set_src(self.src); - endpoint.set_id(self.id); - - endpoint + GrpcWebRtcPlayEndpoint { + src: self.src, + on_start: String::new(), + on_stop: String::new(), + id: self.id, + force_relay: false, + } } } @@ -320,22 +344,22 @@ pub struct WebRtcPublishEndpoint { impl WebRtcPublishEndpoint { pub fn build_request>(self, url: T) -> CreateRequest { - let mut request = CreateRequest::default(); - - request.set_parent_fid(url.into()); - request.set_webrtc_pub(self.into()); - - request + CreateRequest { + el: Some(CreateRequestEl::WebrtcPub(self.into())), + parent_fid: url.into(), + } } } impl Into for WebRtcPublishEndpoint { fn into(self) -> GrpcWebRtcPublishEndpoint { - let mut endpoint = GrpcWebRtcPublishEndpoint::new(); - endpoint.set_p2p(self.p2p_mode); - endpoint.set_id(self.id); - - endpoint + GrpcWebRtcPublishEndpoint { + p2p: self.p2p_mode as i32, + on_start: String::default(), + on_stop: String::default(), + id: self.id, + force_relay: bool::default(), + } } } @@ -382,7 +406,7 @@ fn create_room_req(room_id: &str) -> CreateRequest { .add_endpoint( WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::ALWAYS) + .p2p_mode(WebRtcPublishEndpoint_P2P::Always) .build() .unwrap(), ) diff --git a/tests/e2e/grpc_control_api/signaling.rs b/tests/e2e/grpc_control_api/signaling.rs index 74f88bb6f..e9480c83a 100644 --- a/tests/e2e/grpc_control_api/signaling.rs +++ b/tests/e2e/grpc_control_api/signaling.rs @@ -9,10 +9,10 @@ use std::{ time::Duration, }; -use actix::Context; +use actix::{Arbiter, Context}; use futures::{channel::mpsc, StreamExt as _}; use medea_client_api_proto::Event; -use medea_control_api_proto::grpc::api::WebRtcPublishEndpoint_P2P; +use medea_control_api_proto::grpc::medea::web_rtc_publish_endpoint::P2p; use tokio::time::timeout; use crate::{grpc_control_api::ControlClient, signalling::TestMember}; @@ -54,9 +54,9 @@ fn done_on_both_peers_created() -> ( async fn signalling_starts_when_create_play_member_after_pub_member() { const TEST_NAME: &str = "create-play-member-after-pub-member"; - let control_client = ControlClient::new(); + let mut control_client = ControlClient::new().await; - let create_room = RoomBuilder::default() + let mut create_room = RoomBuilder::default() .id(TEST_NAME) .add_member( MemberBuilder::default() @@ -65,7 +65,7 @@ async fn signalling_starts_when_create_play_member_after_pub_member() { .add_endpoint( WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::ALWAYS) + .p2p_mode(P2p::Always) .build() .unwrap(), ) @@ -76,7 +76,7 @@ async fn signalling_starts_when_create_play_member_after_pub_member() { .unwrap() .build_request(""); - control_client.create(&create_room); + control_client.create(create_room); let (on_event, done) = done_on_both_peers_created(); let deadline = Some(Duration::from_secs(5)); @@ -102,7 +102,7 @@ async fn signalling_starts_when_create_play_member_after_pub_member() { .unwrap() .build_request(TEST_NAME); - control_client.create(&create_play_member); + control_client.create(create_play_member); TestMember::connect( &format!("ws://127.0.0.1:8080/ws/{}/responder/qwerty", TEST_NAME), Box::new(on_event), @@ -118,7 +118,7 @@ async fn signalling_starts_when_create_play_endpoint_after_pub_member() { const TEST_NAME: &str = "signalling_starts_when_create_play_endpoint_after_pub_member"; - let control_client = ControlClient::new(); + let mut control_client = ControlClient::new().await; let create_room = RoomBuilder::default() .id(TEST_NAME) @@ -129,7 +129,7 @@ async fn signalling_starts_when_create_play_endpoint_after_pub_member() { .add_endpoint( WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::ALWAYS) + .p2p_mode(P2p::Always) .build() .unwrap(), ) @@ -140,7 +140,7 @@ async fn signalling_starts_when_create_play_endpoint_after_pub_member() { .unwrap() .build_request(""); - control_client.create(&create_room); + control_client.create(create_room); let (on_event, done) = done_on_both_peers_created(); let deadline = Some(Duration::from_secs(5)); @@ -158,7 +158,7 @@ async fn signalling_starts_when_create_play_endpoint_after_pub_member() { .build() .unwrap() .build_request(TEST_NAME); - control_client.create(&create_second_member); + control_client.create(create_second_member); let create_play = WebRtcPlayEndpointBuilder::default() .id("play") @@ -167,7 +167,7 @@ async fn signalling_starts_when_create_play_endpoint_after_pub_member() { .unwrap() .build_request(format!("{}/responder", TEST_NAME)); - control_client.create(&create_play); + control_client.create(create_play); TestMember::connect( &format!("ws://127.0.0.1:8080/ws/{}/responder/qwerty", TEST_NAME), @@ -183,7 +183,7 @@ async fn signalling_starts_when_create_play_endpoint_after_pub_member() { async fn signalling_starts_in_loopback_scenario() { const TEST_NAME: &str = "signalling_starts_in_loopback_scenario"; - let control_client = ControlClient::new(); + let mut control_client = ControlClient::new().await; let create_room = RoomBuilder::default() .id(TEST_NAME) @@ -194,7 +194,7 @@ async fn signalling_starts_in_loopback_scenario() { .add_endpoint( WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::ALWAYS) + .p2p_mode(P2p::Always) .build() .unwrap(), ) @@ -205,7 +205,7 @@ async fn signalling_starts_in_loopback_scenario() { .unwrap() .build_request(""); - control_client.create(&create_room); + control_client.create(create_room); let (on_event, done) = done_on_both_peers_created(); @@ -225,81 +225,84 @@ async fn signalling_starts_in_loopback_scenario() { .unwrap() .build_request(format!("{}/publisher", TEST_NAME)); - control_client.create(&create_play); + control_client.create(create_play); done.await; } -#[actix_rt::test] -async fn peers_removed_on_delete_member() { - const TEST_NAME: &str = "delete-member-check-peers-removed"; - - let control_client = ControlClient::new(); - - let create_room = RoomBuilder::default() - .id(TEST_NAME) - .add_member( - MemberBuilder::default() - .id("publisher") - .credentials("test") - .add_endpoint( - WebRtcPublishEndpointBuilder::default() - .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::ALWAYS) - .build() - .unwrap(), - ) - .build() - .unwrap(), - ) - .add_member( - MemberBuilder::default() - .id("responder") - .credentials("test") - .add_endpoint( - WebRtcPlayEndpointBuilder::default() - .id("play") - .src(format!("local://{}/publisher/publish", TEST_NAME)) - .build() - .unwrap(), - ) - .build() - .unwrap(), - ) - .build() - .unwrap() - .build_request(""); - - control_client.create(&create_room); - - let peers_created = Rc::new(Cell::new(0)); - let on_event = - move |event: &Event, _: &mut Context, _: Vec<&Event>| { - match event { - Event::PeerCreated { .. } => { - peers_created.set(peers_created.get() + 1); - if peers_created.get() == 2 { - control_client - .delete(&[&format!("{}/responder", TEST_NAME)]) - .unwrap(); - } - } - Event::PeersRemoved { .. } => { - actix::System::current().stop(); - } - _ => {} - } - }; - - let deadline = Some(Duration::from_secs(5)); - TestMember::start( - format!("ws://127.0.0.1:8080/ws/{}/publisher/test", TEST_NAME), - Box::new(on_event.clone()), - deadline, - ); - TestMember::start( - format!("ws://127.0.0.1:8080/ws/{}/responder/test", TEST_NAME), - Box::new(on_event), - deadline, - ); -} +//#[actix_rt::test] +// async fn peers_removed_on_delete_member() { +// const TEST_NAME: &str = "delete-member-check-peers-removed"; +// +// let mut control_client = ControlClient::new().await; +// +// let create_room = RoomBuilder::default() +// .id(TEST_NAME) +// .add_member( +// MemberBuilder::default() +// .id("publisher") +// .credentials("test") +// .add_endpoint( +// WebRtcPublishEndpointBuilder::default() +// .id("publish") +// .p2p_mode(P2p::Always) +// .build() +// .unwrap(), +// ) +// .build() +// .unwrap(), +// ) +// .add_member( +// MemberBuilder::default() +// .id("responder") +// .credentials("test") +// .add_endpoint( +// WebRtcPlayEndpointBuilder::default() +// .id("play") +// .src(format!("local://{}/publisher/publish", +// TEST_NAME)) .build() +// .unwrap(), +// ) +// .build() +// .unwrap(), +// ) +// .build() +// .unwrap() +// .build_request(""); +// +// control_client.create(create_room); +// +// let peers_created = Rc::new(Cell::new(0)); +// let on_event = +// move |event: &Event, _: &mut Context, _: Vec<&Event>| { +// match event { +// Event::PeerCreated { .. } => { +// peers_created.set(peers_created.get() + 1); +// if peers_created.get() == 2 { +// Arbiter::spawn(async move { +// control_client +// .delete(&[&format!("{}/responder", +// TEST_NAME)]) .await +// .unwrap(); +// }) +// } +// } +// Event::PeersRemoved { .. } => { +// actix::System::current().stop(); +// } +// _ => {} +// } +// }; +// +// let deadline = Some(Duration::from_secs(5)); +// TestMember::start( +// format!("ws://127.0.0.1:8080/ws/{}/publisher/test", TEST_NAME), +// Box::new(on_event.clone()), +// deadline, +// ); +// TestMember::start( +// format!("ws://127.0.0.1:8080/ws/{}/responder/test", TEST_NAME), +// Box::new(on_event), +// deadline, +// ); +//} From 848307fe83ffc40df1397a2b08e062b7024ff5b4 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 28 Jan 2020 13:02:03 +0300 Subject: [PATCH 009/224] Fix all E2E tests --- tests/e2e/grpc_control_api/create.rs | 4 +- tests/e2e/grpc_control_api/signaling.rs | 168 ++++++++++++------------ 2 files changed, 87 insertions(+), 85 deletions(-) diff --git a/tests/e2e/grpc_control_api/create.rs b/tests/e2e/grpc_control_api/create.rs index b628c080c..15933dd37 100644 --- a/tests/e2e/grpc_control_api/create.rs +++ b/tests/e2e/grpc_control_api/create.rs @@ -79,7 +79,7 @@ mod room { .unwrap() .build_request(""); - client.create(create_room.clone()); + client.create(create_room.clone()).await; if let Err(err) = client.try_create(create_room).await { assert_eq!(err.code, ErrorCode::RoomAlreadyExists as u32) @@ -116,7 +116,7 @@ mod member { const TEST_NAME: &str = "create-member"; let mut client = ControlClient::new().await; - client.create(create_room_req(TEST_NAME)); + client.create(create_room_req(TEST_NAME)).await; let add_member = MemberBuilder::default() .id("test-member") diff --git a/tests/e2e/grpc_control_api/signaling.rs b/tests/e2e/grpc_control_api/signaling.rs index e9480c83a..95a6f0adc 100644 --- a/tests/e2e/grpc_control_api/signaling.rs +++ b/tests/e2e/grpc_control_api/signaling.rs @@ -76,7 +76,7 @@ async fn signalling_starts_when_create_play_member_after_pub_member() { .unwrap() .build_request(""); - control_client.create(create_room); + control_client.create(create_room).await; let (on_event, done) = done_on_both_peers_created(); let deadline = Some(Duration::from_secs(5)); @@ -102,7 +102,7 @@ async fn signalling_starts_when_create_play_member_after_pub_member() { .unwrap() .build_request(TEST_NAME); - control_client.create(create_play_member); + control_client.create(create_play_member).await; TestMember::connect( &format!("ws://127.0.0.1:8080/ws/{}/responder/qwerty", TEST_NAME), Box::new(on_event), @@ -140,7 +140,7 @@ async fn signalling_starts_when_create_play_endpoint_after_pub_member() { .unwrap() .build_request(""); - control_client.create(create_room); + control_client.create(create_room).await; let (on_event, done) = done_on_both_peers_created(); let deadline = Some(Duration::from_secs(5)); @@ -158,7 +158,7 @@ async fn signalling_starts_when_create_play_endpoint_after_pub_member() { .build() .unwrap() .build_request(TEST_NAME); - control_client.create(create_second_member); + control_client.create(create_second_member).await; let create_play = WebRtcPlayEndpointBuilder::default() .id("play") @@ -167,7 +167,7 @@ async fn signalling_starts_when_create_play_endpoint_after_pub_member() { .unwrap() .build_request(format!("{}/responder", TEST_NAME)); - control_client.create(create_play); + control_client.create(create_play).await; TestMember::connect( &format!("ws://127.0.0.1:8080/ws/{}/responder/qwerty", TEST_NAME), @@ -205,7 +205,7 @@ async fn signalling_starts_in_loopback_scenario() { .unwrap() .build_request(""); - control_client.create(create_room); + control_client.create(create_room).await; let (on_event, done) = done_on_both_peers_created(); @@ -225,84 +225,86 @@ async fn signalling_starts_in_loopback_scenario() { .unwrap() .build_request(format!("{}/publisher", TEST_NAME)); - control_client.create(create_play); + control_client.create(create_play).await; done.await; } -//#[actix_rt::test] -// async fn peers_removed_on_delete_member() { -// const TEST_NAME: &str = "delete-member-check-peers-removed"; -// -// let mut control_client = ControlClient::new().await; -// -// let create_room = RoomBuilder::default() -// .id(TEST_NAME) -// .add_member( -// MemberBuilder::default() -// .id("publisher") -// .credentials("test") -// .add_endpoint( -// WebRtcPublishEndpointBuilder::default() -// .id("publish") -// .p2p_mode(P2p::Always) -// .build() -// .unwrap(), -// ) -// .build() -// .unwrap(), -// ) -// .add_member( -// MemberBuilder::default() -// .id("responder") -// .credentials("test") -// .add_endpoint( -// WebRtcPlayEndpointBuilder::default() -// .id("play") -// .src(format!("local://{}/publisher/publish", -// TEST_NAME)) .build() -// .unwrap(), -// ) -// .build() -// .unwrap(), -// ) -// .build() -// .unwrap() -// .build_request(""); -// -// control_client.create(create_room); -// -// let peers_created = Rc::new(Cell::new(0)); -// let on_event = -// move |event: &Event, _: &mut Context, _: Vec<&Event>| { -// match event { -// Event::PeerCreated { .. } => { -// peers_created.set(peers_created.get() + 1); -// if peers_created.get() == 2 { -// Arbiter::spawn(async move { -// control_client -// .delete(&[&format!("{}/responder", -// TEST_NAME)]) .await -// .unwrap(); -// }) -// } -// } -// Event::PeersRemoved { .. } => { -// actix::System::current().stop(); -// } -// _ => {} -// } -// }; -// -// let deadline = Some(Duration::from_secs(5)); -// TestMember::start( -// format!("ws://127.0.0.1:8080/ws/{}/publisher/test", TEST_NAME), -// Box::new(on_event.clone()), -// deadline, -// ); -// TestMember::start( -// format!("ws://127.0.0.1:8080/ws/{}/responder/test", TEST_NAME), -// Box::new(on_event), -// deadline, -// ); -//} +#[actix_rt::test] +async fn peers_removed_on_delete_member() { + const TEST_NAME: &str = "delete-member-check-peers-removed"; + + let mut control_client = Rc::new(RefCell::new(ControlClient::new().await)); + + let create_room = RoomBuilder::default() + .id(TEST_NAME) + .add_member( + MemberBuilder::default() + .id("publisher") + .credentials("test") + .add_endpoint( + WebRtcPublishEndpointBuilder::default() + .id("publish") + .p2p_mode(P2p::Always) + .build() + .unwrap(), + ) + .build() + .unwrap(), + ) + .add_member( + MemberBuilder::default() + .id("responder") + .credentials("test") + .add_endpoint( + WebRtcPlayEndpointBuilder::default() + .id("play") + .src(format!("local://{}/publisher/publish", TEST_NAME)) + .build() + .unwrap(), + ) + .build() + .unwrap(), + ) + .build() + .unwrap() + .build_request(""); + + control_client.borrow_mut().create(create_room).await; + + let peers_created = Rc::new(Cell::new(0)); + let on_event = + move |event: &Event, _: &mut Context, _: Vec<&Event>| { + match event { + Event::PeerCreated { .. } => { + peers_created.set(peers_created.get() + 1); + if peers_created.get() == 2 { + let client = control_client.clone(); + Arbiter::spawn(async move { + client + .borrow_mut() + .delete(&[&format!("{}/responder", TEST_NAME)]) + .await + .unwrap(); + }) + } + } + Event::PeersRemoved { .. } => { + actix::System::current().stop(); + } + _ => {} + } + }; + + let deadline = Some(Duration::from_secs(5)); + TestMember::start( + format!("ws://127.0.0.1:8080/ws/{}/publisher/test", TEST_NAME), + Box::new(on_event.clone()), + deadline, + ); + TestMember::start( + format!("ws://127.0.0.1:8080/ws/{}/responder/test", TEST_NAME), + Box::new(on_event), + deadline, + ); +} From b1b8f2ee95b72f200c5d5a67b55c8bf12731ce17 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 28 Jan 2020 13:30:16 +0300 Subject: [PATCH 010/224] Fix deadlock --- Cargo.lock | 37 ++++++++++++++++++++++++ Cargo.toml | 5 ++++ src/api/control/callback/clients/grpc.rs | 29 +++++++------------ src/api/control/callback/clients/mod.rs | 7 +++-- src/api/control/callback/service.rs | 24 ++++++--------- src/main.rs | 25 ++++++++++++++++ src/signalling/room_repo.rs | 14 ++++----- tests/e2e/grpc_control_api/signaling.rs | 4 +-- 8 files changed, 99 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc5fa51f6..b2ce8df4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -903,6 +903,11 @@ dependencies = [ "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fixedbitset" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "fixedbitset" version = "0.2.0" @@ -1380,6 +1385,7 @@ dependencies = [ "medea-control-api-proto 0.1.0-dev", "medea-macro 0.2.0-dev", "mockall 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1679,6 +1685,11 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ordermap" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "parking_lot" version = "0.9.0" @@ -1717,11 +1728,14 @@ name = "parking_lot_core" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1735,6 +1749,15 @@ name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "petgraph" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "petgraph" version = "0.5.0" @@ -2459,6 +2482,16 @@ dependencies = [ "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.6" @@ -3206,6 +3239,7 @@ dependencies = [ "checksum enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "900a6c7fbe523f4c2884eaf26b57b81bb69b6810a01a236390a7ac021d09492e" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" +"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" "checksum float-cmp 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75224bec9bfe1a65e2d34132933f2de7fe79900c96a0174307554244ece8150e" @@ -3282,12 +3316,14 @@ dependencies = [ "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" "checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" +"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" "checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" "checksum pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "75fca1c4ff21f60ca2d37b80d72b63dab823a9d19d3cda3a81d18bc03f0ba8c5" "checksum pin-project-internal 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6544cd4e4ecace61075a6ec78074beeef98d58aa9a3d07d053d993b2946a90d6" @@ -3374,6 +3410,7 @@ dependencies = [ "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" diff --git a/Cargo.toml b/Cargo.toml index c75584d66..f1895a6f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,10 @@ members = [ [profile.release] lto = "thin" +[features] +deadlock_detection = [] +default = ["deadlock_detection"] + [dependencies] actix = "0.9" actix-web = "2.0" @@ -60,6 +64,7 @@ tokio = { version = "0.2", features = ["signal", "time"] } tonic = "0.1" toml = "0.5" url = "2.1" +parking_lot = { version = "0.10", features = ["deadlock_detection"] } [dependencies.slog] version = "2.5" features = ["release_max_level_trace", "max_level_trace"] diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index 370316ce2..0c1f56bd2 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -13,13 +13,13 @@ use crate::api::control::callback::{ url::GrpcCallbackUrl, CallbackRequest, }; -use std::sync::Mutex; +use parking_lot::Mutex; use tonic::transport::Channel; /// gRPC client for sending [`CallbackRequest`]s. pub struct GrpcCallbackClient { /// [`grpcio`] gRPC client of Control API Callback service. - client: Arc>>, + client: ProtoCallbackClient, } impl fmt::Debug for GrpcCallbackClient { @@ -37,28 +37,21 @@ impl GrpcCallbackClient { /// provided [`GrpcCallbackUrl`]. pub async fn new(addr: &GrpcCallbackUrl) -> Self { let addr = addr.addr(); - let client = Arc::new(Mutex::new( - ProtoCallbackClient::connect(addr).await.unwrap(), - )); + let client = ProtoCallbackClient::connect(addr).await.unwrap(); Self { client } } } +#[async_trait::async_trait] impl CallbackClient for GrpcCallbackClient { - fn send( - &self, + async fn send( + &mut self, request: CallbackRequest, - ) -> LocalBoxFuture<'static, Result<(), CallbackClientError>> { - let client = Arc::clone(&self.client); - async move { - client - .lock() - .unwrap() - .on_event(tonic::Request::new(request.into())) - .await?; - Ok(()) - } - .boxed_local() + ) -> Result<(), CallbackClientError> { + self.client + .on_event(tonic::Request::new(request.into())) + .await?; + Ok(()) } } diff --git a/src/api/control/callback/clients/mod.rs b/src/api/control/callback/clients/mod.rs index 8f916dc6a..5c8cc2226 100644 --- a/src/api/control/callback/clients/mod.rs +++ b/src/api/control/callback/clients/mod.rs @@ -13,12 +13,13 @@ use crate::{ }; /// Client that sends [`CallbackRequest`]'s to [`Callback`] server. +#[async_trait::async_trait] pub trait CallbackClient: Debug + Send + Sync { /// Sends [`CallbackRequest`] to [`Callback`] server. - fn send( - &self, + async fn send( + &mut self, request: CallbackRequest, - ) -> LocalBoxFuture<'static, Result<(), CallbackClientError>>; + ) -> Result<(), CallbackClientError>; } /// Error of sending [`CallbackRequest`] by [`CallbackClient`]. diff --git a/src/api/control/callback/service.rs b/src/api/control/callback/service.rs index 45a33e737..ce61d4554 100644 --- a/src/api/control/callback/service.rs +++ b/src/api/control/callback/service.rs @@ -1,12 +1,9 @@ //! Service which stores and lazily creates [`CallbackRequest`] clients. -use std::{ - collections::hash_map::HashMap, - fmt::Debug, - sync::{Arc, RwLock}, -}; +use std::{collections::hash_map::HashMap, fmt::Debug, sync::Arc}; use actix::Arbiter; +use parking_lot::RwLock; use crate::{ api::control::{ @@ -48,22 +45,19 @@ impl CallbackService { let req = CallbackRequest::new(fid, event.into()); info!("Sending CallbackRequest [{:?}] to [{}]", req, callback_url); - let read_lock = inner.read().unwrap(); + let mut read_lock = inner.write(); let send_request = - if let Some(client) = read_lock.get(&callback_url) { - client.send(req) + if let Some(client) = read_lock.get_mut(&callback_url) { + client.send(req).await } else { drop(read_lock); - let new_client = build_client(&callback_url).await; - let send = new_client.send(req); - inner - .write() - .unwrap() - .insert(callback_url, Box::new(new_client)); + let mut new_client = build_client(&callback_url).await; + let send = new_client.send(req).await; + inner.write().insert(callback_url, Box::new(new_client)); send }; - if let Err(e) = send_request.await { + if let Err(e) = send_request { error!("Failed to send callback because {:?}.", e); } }) diff --git a/src/main.rs b/src/main.rs index 007e366b4..2b6df9974 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,6 +29,31 @@ fn main() -> Result<(), Error> { info!("{:?}", config); + #[cfg(feature = "deadlock_detection")] + { + // only for #[cfg] + use parking_lot::deadlock; + use std::{thread, time::Duration}; + + // Create a background thread which checks for deadlocks every 10s + thread::spawn(move || loop { + thread::sleep(Duration::from_secs(10)); + let deadlocks = deadlock::check_deadlock(); + if deadlocks.is_empty() { + continue; + } + + println!("{} deadlocks detected", deadlocks.len()); + for (i, threads) in deadlocks.iter().enumerate() { + println!("Deadlock #{}", i); + for t in threads { + println!("Thread Id {:#?}", t.thread_id()); + println!("{:#?}", t.backtrace()); + } + } + }); + } // only for #[cfg] + let sys = System::new("medea"); Arbiter::spawn( async move { diff --git a/src/signalling/room_repo.rs b/src/signalling/room_repo.rs index 01989094f..a623ddfdd 100644 --- a/src/signalling/room_repo.rs +++ b/src/signalling/room_repo.rs @@ -1,11 +1,9 @@ //! Repository that stores [`Room`]s addresses. -use std::{ - collections::HashMap, - sync::{Arc, Mutex}, -}; +use std::{collections::HashMap, sync::Arc}; use actix::Addr; +use parking_lot::Mutex; use crate::{api::control::RoomId, signalling::Room}; @@ -29,23 +27,23 @@ impl RoomRepository { /// Returns [`Room`] by its ID. pub fn get(&self, id: &RoomId) -> Option> { - let rooms = self.rooms.lock().unwrap(); + let rooms = self.rooms.lock(); rooms.get(id).cloned() } /// Removes [`Room`] from [`RoomRepository`] by [`RoomId`]. pub fn remove(&self, id: &RoomId) { - self.rooms.lock().unwrap().remove(id); + self.rooms.lock().remove(id); } /// Adds new [`Room`] into [`RoomRepository`]. pub fn add(&self, id: RoomId, room: Addr) { - self.rooms.lock().unwrap().insert(id, room); + self.rooms.lock().insert(id, room); } /// Checks existence of [`Room`] in [`RoomRepository`] by provided /// [`RoomId`]. pub fn contains_room_with_id(&self, id: &RoomId) -> bool { - self.rooms.lock().unwrap().contains_key(id) + self.rooms.lock().contains_key(id) } } diff --git a/tests/e2e/grpc_control_api/signaling.rs b/tests/e2e/grpc_control_api/signaling.rs index 95a6f0adc..5ad2d1d7a 100644 --- a/tests/e2e/grpc_control_api/signaling.rs +++ b/tests/e2e/grpc_control_api/signaling.rs @@ -281,8 +281,8 @@ async fn peers_removed_on_delete_member() { if peers_created.get() == 2 { let client = control_client.clone(); Arbiter::spawn(async move { - client - .borrow_mut() + client + .borrow_mut() .delete(&[&format!("{}/responder", TEST_NAME)]) .await .unwrap(); From c4031e9e9c032f78039ae1373c411fe1ccb7a287 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Wed, 29 Jan 2020 17:39:00 +0300 Subject: [PATCH 011/224] Wrap GrpcCallbackClient into Actor --- src/api/control/callback/clients/grpc.rs | 71 ++++++++++++++++++------ src/api/control/callback/clients/mod.rs | 31 ++++++----- src/api/control/callback/mod.rs | 5 +- src/api/control/callback/service.rs | 50 ++++++++++------- src/api/control/callback/url.rs | 8 +-- 5 files changed, 110 insertions(+), 55 deletions(-) diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index 0c1f56bd2..99458dca5 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -2,24 +2,69 @@ use std::{fmt, sync::Arc}; -use futures::future::{FutureExt as _, LocalBoxFuture}; +use futures::future::{BoxFuture, FutureExt as _, LocalBoxFuture}; #[rustfmt::skip] use medea_control_api_proto::grpc::medea_callback::{ callback_client::CallbackClient as ProtoCallbackClient }; +use futures::{Future, TryFutureExt}; use crate::api::control::callback::{ clients::{CallbackClient, CallbackClientError}, url::GrpcCallbackUrl, CallbackRequest, }; +use actix::{Actor, ActorFuture, Addr, Context, Handler, WrapFuture}; +use actix_web::dev::Service; +use failure::_core::pin::Pin; use parking_lot::Mutex; +use std::{cell::RefCell, rc::Rc}; use tonic::transport::Channel; /// gRPC client for sending [`CallbackRequest`]s. pub struct GrpcCallbackClient { /// [`grpcio`] gRPC client of Control API Callback service. - client: ProtoCallbackClient, + client: Rc>>, +} + +pub type ActFuture = + Box>; + +impl Actor for GrpcCallbackClient { + type Context = Context; +} + +impl CallbackClient for Addr { + fn send( + &self, + request: CallbackRequest, + ) -> LocalBoxFuture<'static, Result<(), CallbackClientError>> { + let this = self.clone(); + Box::pin(async move { Ok(this.send(request).await??) }) + } +} + +impl Handler for GrpcCallbackClient { + type Result = ActFuture>; + + fn handle( + &mut self, + msg: CallbackRequest, + ctx: &mut Self::Context, + ) -> Self::Result { + let client = Rc::clone(&self.client); + Box::new( + async move { + client + .borrow_mut() + .on_event(tonic::Request::new(msg.into())) + .await?; + + Ok(()) + } + .into_actor(self), + ) + } } impl fmt::Debug for GrpcCallbackClient { @@ -35,23 +80,13 @@ impl GrpcCallbackClient { /// /// Note that this function doesn't check availability of gRPC server on /// provided [`GrpcCallbackUrl`]. - pub async fn new(addr: &GrpcCallbackUrl) -> Self { + pub async fn new( + addr: &GrpcCallbackUrl, + ) -> Result { let addr = addr.addr(); - let client = ProtoCallbackClient::connect(addr).await.unwrap(); + let client = + Rc::new(RefCell::new(ProtoCallbackClient::connect(addr).await?)); - Self { client } - } -} - -#[async_trait::async_trait] -impl CallbackClient for GrpcCallbackClient { - async fn send( - &mut self, - request: CallbackRequest, - ) -> Result<(), CallbackClientError> { - self.client - .on_event(tonic::Request::new(request.into())) - .await?; - Ok(()) + Ok(Self { client }) } } diff --git a/src/api/control/callback/clients/mod.rs b/src/api/control/callback/clients/mod.rs index 5c8cc2226..7c4db4d7f 100644 --- a/src/api/control/callback/clients/mod.rs +++ b/src/api/control/callback/clients/mod.rs @@ -5,37 +5,42 @@ pub mod grpc; use std::fmt::Debug; use derive_more::From; -use futures::future::LocalBoxFuture; +use futures::future::{BoxFuture, LocalBoxFuture}; use crate::{ api::control::callback::{url::CallbackUrl, CallbackRequest}, log::prelude::*, }; - -/// Client that sends [`CallbackRequest`]'s to [`Callback`] server. -#[async_trait::async_trait] -pub trait CallbackClient: Debug + Send + Sync { - /// Sends [`CallbackRequest`] to [`Callback`] server. - async fn send( - &mut self, - request: CallbackRequest, - ) -> Result<(), CallbackClientError>; -} +use actix::{Actor, Addr, Recipient}; +use std::sync::Arc; /// Error of sending [`CallbackRequest`] by [`CallbackClient`]. #[derive(Debug, From)] pub enum CallbackClientError { /// [`grpcio`] failed to send [`CallbackRequest`]. Tonic(tonic::Status), + + Mailbox(actix::MailboxError), + + TonicTransport(tonic::transport::Error), +} + +pub trait CallbackClient: Debug + Send + Sync { + fn send( + &self, + request: CallbackRequest, + ) -> LocalBoxFuture<'static, Result<(), CallbackClientError>>; } /// Creates [`CallbackClient`] basing on provided [`CallbackUrl`]. #[inline] -pub async fn build_client(url: &CallbackUrl) -> impl CallbackClient { +pub async fn build_client( + url: &CallbackUrl, +) -> Result { info!("Creating CallbackClient for url: {}", url); match &url { CallbackUrl::Grpc(grpc_url) => { - grpc::GrpcCallbackClient::new(grpc_url).await + Ok(grpc::GrpcCallbackClient::new(grpc_url).await?.start()) } } } diff --git a/src/api/control/callback/mod.rs b/src/api/control/callback/mod.rs index 9c7a25a70..48254e4de 100644 --- a/src/api/control/callback/mod.rs +++ b/src/api/control/callback/mod.rs @@ -4,7 +4,9 @@ pub mod clients; pub mod service; pub mod url; +use actix::Message; use chrono::{DateTime, Utc}; +use clients::CallbackClientError; use derive_more::From; use medea_control_api_proto::grpc::medea_callback::{ on_leave::Reason as OnLeaveReasonProto, @@ -96,7 +98,8 @@ impl Into for CallbackEvent { /// /// [`CallbackClient::send`]: /// crate::api::control::callback::clients::CallbackClient::send -#[derive(Debug)] +#[derive(Debug, Message)] +#[rtype(result = "Result<(), CallbackClientError>")] pub struct CallbackRequest { /// FID (Full ID) of element with which event was occurred. fid: StatefulFid, diff --git a/src/api/control/callback/service.rs b/src/api/control/callback/service.rs index ce61d4554..274cf086b 100644 --- a/src/api/control/callback/service.rs +++ b/src/api/control/callback/service.rs @@ -2,7 +2,7 @@ use std::{collections::hash_map::HashMap, fmt::Debug, sync::Arc}; -use actix::Arbiter; +use actix::{Arbiter, Recipient}; use parking_lot::RwLock; use crate::{ @@ -13,10 +13,11 @@ use crate::{ log::prelude::*, }; -use super::{ - clients::{build_client, CallbackClient}, - CallbackRequest, +use super::{clients::build_client, CallbackRequest}; +use crate::api::control::callback::clients::{ + CallbackClient, CallbackClientError, }; +use futures::{future::BoxFuture, Future}; /// Service which stores and lazily creates [`CallbackRequest`] clients. #[derive(Clone, Debug, Default)] @@ -28,6 +29,30 @@ pub struct CallbackService( ); impl CallbackService { + async fn send_request( + &self, + request: CallbackRequest, + callback_url: CallbackUrl, + ) -> Result<(), CallbackClientError> { + info!( + "Sending CallbackRequest [{:?}] to [{}]", + request, callback_url + ); + + let read_lock = self.0.read(); + if let Some(client) = read_lock.get(&callback_url) { + client.send(request).await?; + } else { + drop(read_lock); + + let mut new_client = build_client(&callback_url).await?; + let send = new_client.send(request).await?; + self.0.write().insert(callback_url, Box::new(new_client)); + }; + + Ok(()) + } + /// Asynchronously sends [`CallbackEvent`] for provided [`StatefulFid`] to /// [`CallbackClient`]. /// @@ -40,24 +65,11 @@ impl CallbackService { fid: StatefulFid, event: T, ) { - let inner = self.0.clone(); + let this = self.clone(); Arbiter::spawn(async move { let req = CallbackRequest::new(fid, event.into()); - info!("Sending CallbackRequest [{:?}] to [{}]", req, callback_url); - - let mut read_lock = inner.write(); - let send_request = - if let Some(client) = read_lock.get_mut(&callback_url) { - client.send(req).await - } else { - drop(read_lock); - let mut new_client = build_client(&callback_url).await; - let send = new_client.send(req).await; - inner.write().insert(callback_url, Box::new(new_client)); - send - }; - if let Err(e) = send_request { + if let Err(e) = this.send_request(req, callback_url).await { error!("Failed to send callback because {:?}.", e); } }) diff --git a/src/api/control/callback/url.rs b/src/api/control/callback/url.rs index 2c1e3c9c7..e187b085e 100644 --- a/src/api/control/callback/url.rs +++ b/src/api/control/callback/url.rs @@ -108,10 +108,10 @@ mod tests { #[test] fn successful_parse_grpc_url() { for (url, expected_callback_url) in &[ - ("grpc://127.0.0.1:9090", "127.0.0.1:9090"), - ("grpc://example.com:9090", "example.com:9090"), - ("grpc://example.com", "example.com"), - ("grpc://127.0.0.1", "127.0.0.1"), + ("grpc://127.0.0.1:9090", "http://127.0.0.1:9090"), + ("grpc://example.com:9090", "http://example.com:9090"), + ("grpc://example.com", "http://example.com"), + ("grpc://127.0.0.1", "http://127.0.0.1"), ] { let callback_url = CallbackUrl::try_from((*url).to_string()).unwrap(); From da79adf13bf9843b79099ae12d08023ff881a76a Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Wed, 29 Jan 2020 17:42:45 +0300 Subject: [PATCH 012/224] Fix warns --- src/api/control/callback/clients/grpc.rs | 15 +++++---------- src/api/control/callback/clients/mod.rs | 5 ++--- src/api/control/callback/service.rs | 16 ++++++++-------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index 99458dca5..d154659bb 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -1,25 +1,20 @@ //! Implementation of gRPC client for sending [`CallbackRequest`]s. -use std::{fmt, sync::Arc}; +use std::{cell::RefCell, fmt, rc::Rc}; -use futures::future::{BoxFuture, FutureExt as _, LocalBoxFuture}; +use futures::future::LocalBoxFuture; #[rustfmt::skip] use medea_control_api_proto::grpc::medea_callback::{ callback_client::CallbackClient as ProtoCallbackClient }; -use futures::{Future, TryFutureExt}; +use actix::{Actor, ActorFuture, Addr, Context, Handler, WrapFuture}; +use tonic::transport::Channel; use crate::api::control::callback::{ clients::{CallbackClient, CallbackClientError}, url::GrpcCallbackUrl, CallbackRequest, }; -use actix::{Actor, ActorFuture, Addr, Context, Handler, WrapFuture}; -use actix_web::dev::Service; -use failure::_core::pin::Pin; -use parking_lot::Mutex; -use std::{cell::RefCell, rc::Rc}; -use tonic::transport::Channel; /// gRPC client for sending [`CallbackRequest`]s. pub struct GrpcCallbackClient { @@ -50,7 +45,7 @@ impl Handler for GrpcCallbackClient { fn handle( &mut self, msg: CallbackRequest, - ctx: &mut Self::Context, + _: &mut Self::Context, ) -> Self::Result { let client = Rc::clone(&self.client); Box::new( diff --git a/src/api/control/callback/clients/mod.rs b/src/api/control/callback/clients/mod.rs index 7c4db4d7f..db7eba1e1 100644 --- a/src/api/control/callback/clients/mod.rs +++ b/src/api/control/callback/clients/mod.rs @@ -4,15 +4,14 @@ pub mod grpc; use std::fmt::Debug; +use actix::Actor; use derive_more::From; -use futures::future::{BoxFuture, LocalBoxFuture}; +use futures::future::LocalBoxFuture; use crate::{ api::control::callback::{url::CallbackUrl, CallbackRequest}, log::prelude::*, }; -use actix::{Actor, Addr, Recipient}; -use std::sync::Arc; /// Error of sending [`CallbackRequest`] by [`CallbackClient`]. #[derive(Debug, From)] diff --git a/src/api/control/callback/service.rs b/src/api/control/callback/service.rs index 274cf086b..ab3739b01 100644 --- a/src/api/control/callback/service.rs +++ b/src/api/control/callback/service.rs @@ -2,22 +2,22 @@ use std::{collections::hash_map::HashMap, fmt::Debug, sync::Arc}; -use actix::{Arbiter, Recipient}; +use actix::Arbiter; use parking_lot::RwLock; use crate::{ api::control::{ - callback::{url::CallbackUrl, CallbackEvent}, + callback::{ + clients::{CallbackClient, CallbackClientError}, + url::CallbackUrl, + CallbackEvent, + }, refs::StatefulFid, }, log::prelude::*, }; use super::{clients::build_client, CallbackRequest}; -use crate::api::control::callback::clients::{ - CallbackClient, CallbackClientError, -}; -use futures::{future::BoxFuture, Future}; /// Service which stores and lazily creates [`CallbackRequest`] clients. #[derive(Clone, Debug, Default)] @@ -45,8 +45,8 @@ impl CallbackService { } else { drop(read_lock); - let mut new_client = build_client(&callback_url).await?; - let send = new_client.send(request).await?; + let new_client = build_client(&callback_url).await?; + new_client.send(request).await?; self.0.write().insert(callback_url, Box::new(new_client)); }; From cb043618378823e650ea1872b4910cdf5e2978dd Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Wed, 29 Jan 2020 19:28:01 +0300 Subject: [PATCH 013/224] Refactor Protobuf imports --- mock/control-api/src/api/endpoint.rs | 76 ++++---- mock/control-api/src/api/member.rs | 23 +-- mock/control-api/src/api/mod.rs | 52 +++--- mock/control-api/src/api/room.rs | 31 ++-- mock/control-api/src/callback/mod.rs | 46 ++--- mock/control-api/src/callback/server.rs | 8 +- mock/control-api/src/client.rs | 40 ++-- src/api/control/callback/mod.rs | 44 ++--- src/api/control/endpoints/mod.rs | 21 +-- .../control/endpoints/webrtc_play_endpoint.rs | 9 +- .../endpoints/webrtc_publish_endpoint.rs | 35 ++-- src/api/control/error_codes.rs | 8 +- src/api/control/grpc/server.rs | 59 +++--- src/api/control/member.rs | 19 +- src/api/control/room.rs | 19 +- src/signalling/elements/endpoints/mod.rs | 6 +- .../endpoints/webrtc/play_endpoint.rs | 28 ++- .../endpoints/webrtc/publish_endpoint.rs | 32 ++-- src/signalling/elements/member.rs | 29 ++- src/signalling/room.rs | 27 ++- src/signalling/room_service.rs | 4 +- tests/e2e/callbacks/member.rs | 27 +-- tests/e2e/callbacks/mod.rs | 19 +- tests/e2e/grpc_control_api/create.rs | 32 ++-- tests/e2e/grpc_control_api/mod.rs | 172 +++++++++--------- tests/e2e/grpc_control_api/signaling.rs | 4 +- 26 files changed, 420 insertions(+), 450 deletions(-) diff --git a/mock/control-api/src/api/endpoint.rs b/mock/control-api/src/api/endpoint.rs index 250bde52f..260658958 100644 --- a/mock/control-api/src/api/endpoint.rs +++ b/mock/control-api/src/api/endpoint.rs @@ -1,13 +1,6 @@ //! `Endpoint` related methods and entities. -use medea_control_api_proto::grpc::medea::{ - member::{ - element::El as MemberElementOneOfEl, Element as MemberElementProto, - }, - web_rtc_publish_endpoint::P2p as P2pModeProto, - WebRtcPlayEndpoint as WebRtcPlayEndpointProto, - WebRtcPublishEndpoint as WebRtcPublishEndpointProto, -}; +use medea_control_api_proto::grpc::medea as proto; use serde::{Deserialize, Serialize}; /// P2P mode of [`WebRtcPublishEndpoint`]. @@ -18,22 +11,25 @@ pub enum P2pMode { IfPossible, } -impl Into for P2pMode { - fn into(self) -> P2pModeProto { +impl Into for P2pMode { + fn into(self) -> proto::web_rtc_publish_endpoint::P2p { + use proto::web_rtc_publish_endpoint::P2p::*; + match self { - Self::Always => P2pModeProto::Always, - Self::IfPossible => P2pModeProto::IfPossible, - Self::Never => P2pModeProto::Never, + Self::Always => Always, + Self::IfPossible => IfPossible, + Self::Never => Never, } } } -impl From for P2pMode { - fn from(proto: P2pModeProto) -> Self { +impl From for P2pMode { + fn from(proto: proto::web_rtc_publish_endpoint::P2p) -> Self { + use proto::web_rtc_publish_endpoint::P2p::*; match proto { - P2pModeProto::Always => Self::Always, - P2pModeProto::IfPossible => Self::IfPossible, - P2pModeProto::Never => Self::Never, + Always => Self::Always, + IfPossible => Self::IfPossible, + Never => Self::Never, } } } @@ -57,11 +53,11 @@ pub struct WebRtcPublishEndpoint { impl WebRtcPublishEndpoint { /// Converts [`WebRtcPublishEndpoint`] into protobuf - /// [`WebRtcPublishEndpointProto`]. + /// [`proto::WebRtcPublishEndpoint`]. #[must_use] - pub fn into_proto(self, id: String) -> WebRtcPublishEndpointProto { - let p2p: P2pModeProto = self.p2p.into(); - WebRtcPublishEndpointProto { + pub fn into_proto(self, id: String) -> proto::WebRtcPublishEndpoint { + let p2p: proto::web_rtc_publish_endpoint::P2p = self.p2p.into(); + proto::WebRtcPublishEndpoint { id, p2p: p2p as i32, force_relay: self.force_relay, @@ -71,11 +67,13 @@ impl WebRtcPublishEndpoint { } } -impl From for WebRtcPublishEndpoint { - fn from(proto: WebRtcPublishEndpointProto) -> Self { +impl From for WebRtcPublishEndpoint { + fn from(proto: proto::WebRtcPublishEndpoint) -> Self { Self { id: proto.id, - p2p: P2pModeProto::from_i32(proto.p2p).unwrap_or_default().into(), + p2p: proto::web_rtc_publish_endpoint::P2p::from_i32(proto.p2p) + .unwrap_or_default() + .into(), force_relay: proto.force_relay, } } @@ -101,10 +99,10 @@ pub struct WebRtcPlayEndpoint { impl WebRtcPlayEndpoint { /// Converts [`WebRtcPlayEndpoint`] into protobuf - /// [`WebRtcPlayEndpointProto`]. + /// [`proto::WebRtcPlayEndpoint`]. #[must_use] - pub fn into_proto(self, id: String) -> WebRtcPlayEndpointProto { - WebRtcPlayEndpointProto { + pub fn into_proto(self, id: String) -> proto::WebRtcPlayEndpoint { + proto::WebRtcPlayEndpoint { id, src: self.src, force_relay: self.force_relay, @@ -114,8 +112,8 @@ impl WebRtcPlayEndpoint { } } -impl From for WebRtcPlayEndpoint { - fn from(proto: WebRtcPlayEndpointProto) -> Self { +impl From for WebRtcPlayEndpoint { + fn from(proto: proto::WebRtcPlayEndpoint) -> Self { Self { id: proto.id, src: proto.src, @@ -133,29 +131,29 @@ pub enum Endpoint { } impl Endpoint { - /// Converts [`Endpoint`] into protobuf [`MemberElementProto`]. + /// Converts [`Endpoint`] into protobuf [`proto::member::Element`]. #[must_use] - pub fn into_proto(self, id: String) -> MemberElementProto { + pub fn into_proto(self, id: String) -> proto::member::Element { let oneof = match self { Self::WebRtcPlayEndpoint(spec) => { - MemberElementOneOfEl::WebrtcPlay(spec.into_proto(id)) + proto::member::element::El::WebrtcPlay(spec.into_proto(id)) } Self::WebRtcPublishEndpoint(spec) => { - MemberElementOneOfEl::WebrtcPub(spec.into_proto(id)) + proto::member::element::El::WebrtcPub(spec.into_proto(id)) } }; - MemberElementProto { el: Some(oneof) } + proto::member::Element { el: Some(oneof) } } } -impl From for Endpoint { - fn from(proto: MemberElementProto) -> Self { +impl From for Endpoint { + fn from(proto: proto::member::Element) -> Self { match proto.el.unwrap() { - MemberElementOneOfEl::WebrtcPub(webrtc_pub) => { + proto::member::element::El::WebrtcPub(webrtc_pub) => { Self::WebRtcPublishEndpoint(webrtc_pub.into()) } - MemberElementOneOfEl::WebrtcPlay(webrtc_play) => { + proto::member::element::El::WebrtcPlay(webrtc_play) => { Self::WebRtcPlayEndpoint(webrtc_play.into()) } } diff --git a/mock/control-api/src/api/member.rs b/mock/control-api/src/api/member.rs index 2cbd385b0..b0ef2ff62 100644 --- a/mock/control-api/src/api/member.rs +++ b/mock/control-api/src/api/member.rs @@ -2,10 +2,7 @@ use std::collections::HashMap; -use medea_control_api_proto::grpc::medea::{ - room::{element::El as RoomElementOneOfProto, Element as RoomElementProto}, - Member as MemberProto, -}; +use medea_control_api_proto::grpc::medea as proto; use serde::{Deserialize, Serialize}; use super::endpoint::Endpoint; @@ -39,16 +36,16 @@ pub struct Member { } impl Member { - /// Converts [`Member`] into protobuf [`MemberProto`]. + /// Converts [`Member`] into protobuf [`proto::Member`]. #[must_use] - pub fn into_proto(self, id: String) -> MemberProto { + pub fn into_proto(self, id: String) -> proto::Member { let member_elements = self .pipeline .into_iter() .map(|(id, endpoint)| (id.clone(), endpoint.into_proto(id))) .collect(); - MemberProto { + proto::Member { pipeline: member_elements, id, credentials: self.credentials.unwrap_or_default(), @@ -57,17 +54,17 @@ impl Member { } } - /// Converts [`Member`] into protobuf [`RoomElementProto`]. + /// Converts [`Member`] into protobuf [`proto::room::Element`]. #[must_use] - pub fn into_room_el_proto(self, id: String) -> RoomElementProto { - RoomElementProto { - el: Some(RoomElementOneOfProto::Member(self.into_proto(id))), + pub fn into_room_el_proto(self, id: String) -> proto::room::Element { + proto::room::Element { + el: Some(proto::room::element::El::Member(self.into_proto(id))), } } } -impl From for Member { - fn from(proto: MemberProto) -> Self { +impl From for Member { + fn from(proto: proto::Member) -> Self { let member_pipeline = proto .pipeline .into_iter() diff --git a/mock/control-api/src/api/mod.rs b/mock/control-api/src/api/mod.rs index ad6d7b3c8..990302919 100644 --- a/mock/control-api/src/api/mod.rs +++ b/mock/control-api/src/api/mod.rs @@ -16,13 +16,7 @@ use actix_web::{ App, HttpResponse, HttpServer, }; use clap::ArgMatches; -use medea_control_api_proto::grpc::medea::{ - element::El as ElementOneOf, - room::{element::El as RoomElementOneOf, Element as RoomElementProto}, - CreateResponse as CreateResponseProto, Element as ElementProto, - Error as ErrorProto, GetResponse as GetResponseProto, - Response as ResponseProto, -}; +use medea_control_api_proto::grpc::medea as proto; use serde::{Deserialize, Serialize}; use crate::{ @@ -240,7 +234,7 @@ pub struct ErrorResponse { pub element: String, } -impl Into for ErrorProto { +impl Into for proto::Error { fn into(self) -> ErrorResponse { ErrorResponse { code: self.code, @@ -304,16 +298,16 @@ impl_into_http_response!(CreateResponse); impl_into_http_response!(Response); impl_into_http_response!(SingleGetResponse); -impl From for Response { - fn from(resp: ResponseProto) -> Self { +impl From for Response { + fn from(resp: proto::Response) -> Self { Self { error: resp.error.map(|e| e.into()), } } } -impl From for CreateResponse { - fn from(resp: CreateResponseProto) -> Self { +impl From for CreateResponse { + fn from(resp: proto::CreateResponse) -> Self { if let Some(error) = resp.error { Self { sids: None, @@ -342,34 +336,40 @@ pub enum Element { impl Element { #[must_use] - pub fn into_proto(self, id: String) -> RoomElementProto { + pub fn into_proto(self, id: String) -> proto::room::Element { let el = match self { - Self::Member(m) => RoomElementOneOf::Member(m.into_proto(id)), + Self::Member(m) => { + proto::room::element::El::Member(m.into_proto(id)) + } _ => unimplemented!(), }; - RoomElementProto { el: Some(el) } + proto::room::Element { el: Some(el) } } } -impl From for Element { - fn from(proto: ElementProto) -> Self { +impl From for Element { + fn from(proto: proto::Element) -> Self { + use proto::element::El::*; + match proto.el.unwrap() { - ElementOneOf::Room(room) => Self::Room(room.into()), - ElementOneOf::Member(member) => Self::Member(member.into()), - ElementOneOf::WebrtcPub(webrtc_pub) => { + Room(room) => Self::Room(room.into()), + Member(member) => Self::Member(member.into()), + WebrtcPub(webrtc_pub) => { Self::WebRtcPublishEndpoint(webrtc_pub.into()) } - ElementOneOf::WebrtcPlay(webrtc_play) => { + WebrtcPlay(webrtc_play) => { Self::WebRtcPlayEndpoint(webrtc_play.into()) } } } } -impl From for Element { - fn from(proto: RoomElementProto) -> Self { +impl From for Element { + fn from(proto: proto::room::Element) -> Self { match proto.el.unwrap() { - RoomElementOneOf::Member(member) => Self::Member(member.into()), + proto::room::element::El::Member(member) => { + Self::Member(member.into()) + } _ => unimplemented!( "Currently Control API mock server supports only Member \ element in Room pipeline." @@ -393,8 +393,8 @@ pub struct SingleGetResponse { pub error: Option, } -impl From for SingleGetResponse { - fn from(proto: GetResponseProto) -> Self { +impl From for SingleGetResponse { + fn from(proto: proto::GetResponse) -> Self { if let Some(error) = proto.error { Self { element: None, diff --git a/mock/control-api/src/api/room.rs b/mock/control-api/src/api/room.rs index 871615d3c..55bd3368c 100644 --- a/mock/control-api/src/api/room.rs +++ b/mock/control-api/src/api/room.rs @@ -2,10 +2,7 @@ use std::collections::HashMap; -use medea_control_api_proto::grpc::medea::{ - room::{element::El as RoomElementOneOfEl, Element as RoomElementProto}, - Room as RoomProto, -}; +use medea_control_api_proto::grpc::medea as proto; use serde::{Deserialize, Serialize}; use super::member::Member; @@ -24,16 +21,16 @@ pub struct Room { } impl Room { - /// Converts [`Room`] into protobuf [`RoomProto`]. + /// Converts [`Room`] into protobuf [`proto::Room`]. #[must_use] - pub fn into_proto(self, id: String) -> RoomProto { + pub fn into_proto(self, id: String) -> proto::Room { let room_elements = self .pipeline .into_iter() .map(|(id, member)| (id.clone(), member.into_proto(id))) .collect(); - RoomProto { + proto::Room { id, pipeline: room_elements, } @@ -49,26 +46,30 @@ pub enum RoomElement { impl RoomElement { #[must_use] - pub fn into_proto(self, id: String) -> RoomElementProto { + pub fn into_proto(self, id: String) -> proto::room::Element { let el = match self { - Self::Member(m) => RoomElementOneOfEl::Member(m.into_proto(id)), + Self::Member(m) => { + proto::room::element::El::Member(m.into_proto(id)) + } }; - RoomElementProto { el: Some(el) } + proto::room::Element { el: Some(el) } } } -impl From for RoomElement { - fn from(proto: RoomElementProto) -> Self { +impl From for RoomElement { + fn from(proto: proto::room::Element) -> Self { match proto.el.unwrap() { - RoomElementOneOfEl::Member(member) => Self::Member(member.into()), + proto::room::element::El::Member(member) => { + Self::Member(member.into()) + } _ => unimplemented!(), } } } -impl From for Room { - fn from(proto: RoomProto) -> Self { +impl From for Room { + fn from(proto: proto::Room) -> Self { let pipeline = proto .pipeline .into_iter() diff --git a/mock/control-api/src/callback/mod.rs b/mock/control-api/src/callback/mod.rs index 21cf63537..2522d5028 100644 --- a/mock/control-api/src/callback/mod.rs +++ b/mock/control-api/src/callback/mod.rs @@ -2,9 +2,7 @@ pub mod server; -use medea_control_api_proto::grpc::medea_callback::{ - request::Event as CallbackEventProto, Request as CallbackProto, -}; +use medea_control_api_proto::grpc::medea_callback as proto; use serde::Serialize; /// All callbacks which can happen. @@ -15,13 +13,15 @@ pub enum CallbackEvent { OnLeave(leave::OnLeave), } -impl From for CallbackEvent { - fn from(proto: CallbackEventProto) -> Self { +impl From for CallbackEvent { + fn from(proto: proto::request::Event) -> Self { match proto { - CallbackEventProto::OnLeave(on_leave) => { + proto::request::Event::OnLeave(on_leave) => { Self::OnLeave(on_leave.into()) } - CallbackEventProto::OnJoin(on_join) => Self::OnJoin(on_join.into()), + proto::request::Event::OnJoin(on_join) => { + Self::OnJoin(on_join.into()) + } } } } @@ -39,8 +39,8 @@ pub struct CallbackItem { at: String, } -impl From for CallbackItem { - fn from(proto: CallbackProto) -> Self { +impl From for CallbackItem { + fn from(proto: proto::Request) -> Self { Self { fid: proto.fid, at: proto.at, @@ -51,15 +51,15 @@ impl From for CallbackItem { /// `on_join` callback's related entities and implementations. mod join { - use medea_control_api_proto::grpc::medea_callback::OnJoin as OnJoinProto; + use medea_control_api_proto::grpc::medea_callback as proto; use serde::Serialize; /// `OnJoin` callback for Control API. #[derive(Clone, Serialize)] pub struct OnJoin; - impl From for OnJoin { - fn from(_: OnJoinProto) -> Self { + impl From for OnJoin { + fn from(_: proto::OnJoin) -> Self { Self } } @@ -67,9 +67,7 @@ mod join { /// `on_leave` callback's related entities and implementations. mod leave { - use medea_control_api_proto::grpc::medea_callback::{ - on_leave::Reason as OnLeaveReasonProto, OnLeave as OnLeaveProto, - }; + use medea_control_api_proto::grpc::medea_callback as proto; use serde::Serialize; /// `OnLeave` callback of Control API. @@ -79,10 +77,10 @@ mod leave { reason: OnLeaveReason, } - impl From for OnLeave { - fn from(proto: OnLeaveProto) -> Self { + impl From for OnLeave { + fn from(proto: proto::OnLeave) -> Self { Self { - reason: OnLeaveReasonProto::from_i32(proto.reason) + reason: proto::on_leave::Reason::from_i32(proto.reason) .unwrap_or_default() .into(), } @@ -102,12 +100,14 @@ mod leave { ServerShutdown, } - impl From for OnLeaveReason { - fn from(proto: OnLeaveReasonProto) -> Self { + impl From for OnLeaveReason { + fn from(proto: proto::on_leave::Reason) -> Self { + use proto::on_leave::Reason::*; + match proto { - OnLeaveReasonProto::ServerShutdown => Self::ServerShutdown, - OnLeaveReasonProto::LostConnection => Self::LostConnection, - OnLeaveReasonProto::Disconnected => Self::Disconnected, + ServerShutdown => Self::ServerShutdown, + LostConnection => Self::LostConnection, + Disconnected => Self::Disconnected, } } } diff --git a/mock/control-api/src/callback/server.rs b/mock/control-api/src/callback/server.rs index 4c3e1d581..5eb70441d 100644 --- a/mock/control-api/src/callback/server.rs +++ b/mock/control-api/src/callback/server.rs @@ -7,10 +7,10 @@ use std::sync::{Arc, Mutex}; use actix::{Actor, Addr, Arbiter, Context, Handler, Message}; use clap::ArgMatches; use medea_control_api_proto::grpc::medea_callback::{ + self as proto, callback_server::{ Callback as CallbackService, CallbackServer as TonicCallbackServer, }, - Request, Response, }; use tonic::transport::Server; @@ -54,15 +54,15 @@ impl GrpcCallbackService { impl CallbackService for GrpcCallbackService { async fn on_event( &self, - request: tonic::Request, - ) -> Result, tonic::Status> { + request: tonic::Request, + ) -> Result, tonic::Status> { info!("Callback request received: [{:?}]", request); self.events .lock() .unwrap() .push(request.into_inner().into()); - Ok(tonic::Response::new(Response {})) + Ok(tonic::Response::new(proto::Response {})) } } diff --git a/mock/control-api/src/client.rs b/mock/control-api/src/client.rs index e1eed38dc..95e0757e5 100644 --- a/mock/control-api/src/client.rs +++ b/mock/control-api/src/client.rs @@ -3,11 +3,8 @@ //! [Medea]: https://github.com/instrumentisto/medea //! [Control API]: https://tinyurl.com/yxsqplq7 -use medea_control_api_proto::grpc::medea::{ - control_api_client::ControlApiClient, - create_request::El as CreateRequestElProto, CreateRequest, CreateResponse, - GetResponse, IdRequest, Response, -}; +use medea_control_api_proto::grpc::medea as proto; +use proto::control_api_client::ControlApiClient; use tonic::{transport::Channel, Status}; use crate::api::Element; @@ -46,9 +43,9 @@ impl Into for Fid { } } -/// Returns new [`IdRequest`] with provided FIDs. -fn id_request(ids: Vec) -> IdRequest { - IdRequest { fid: ids } +/// Returns new [`proto::IdRequest`] with provided FIDs. +fn id_request(ids: Vec) -> proto::IdRequest { + proto::IdRequest { fid: ids } } /// Client for [Medea]'s [Control API]. @@ -95,22 +92,19 @@ impl ControlClient { id: String, fid: Fid, element: Element, - ) -> Result { + ) -> Result { + use proto::create_request::El::*; let el = match element { - Element::Room(room) => { - CreateRequestElProto::Room(room.into_proto(id)) - } - Element::Member(member) => { - CreateRequestElProto::Member(member.into_proto(id)) - } + Element::Room(room) => Room(room.into_proto(id)), + Element::Member(member) => Member(member.into_proto(id)), Element::WebRtcPlayEndpoint(webrtc_play) => { - CreateRequestElProto::WebrtcPlay(webrtc_play.into_proto(id)) + WebrtcPlay(webrtc_play.into_proto(id)) } Element::WebRtcPublishEndpoint(webrtc_pub) => { - CreateRequestElProto::WebrtcPub(webrtc_pub.into_proto(id)) + WebrtcPub(webrtc_pub.into_proto(id)) } }; - let req = CreateRequest { + let req = proto::CreateRequest { parent_fid: fid.into(), el: Some(el), }; @@ -125,7 +119,10 @@ impl ControlClient { } /// Gets element from Control API by FID. - pub async fn get(&mut self, fid: Fid) -> Result { + pub async fn get( + &mut self, + fid: Fid, + ) -> Result { let req = id_request(vec![fid.into()]); self.get_client() @@ -136,7 +133,10 @@ impl ControlClient { } /// Deletes element from Control API by FID. - pub async fn delete(&mut self, fid: Fid) -> Result { + pub async fn delete( + &mut self, + fid: Fid, + ) -> Result { let req = id_request(vec![fid.into()]); self.get_client() diff --git a/src/api/control/callback/mod.rs b/src/api/control/callback/mod.rs index 48254e4de..9e7665d0d 100644 --- a/src/api/control/callback/mod.rs +++ b/src/api/control/callback/mod.rs @@ -8,11 +8,7 @@ use actix::Message; use chrono::{DateTime, Utc}; use clients::CallbackClientError; use derive_more::From; -use medea_control_api_proto::grpc::medea_callback::{ - on_leave::Reason as OnLeaveReasonProto, - request::Event as RequestOneofEventProto, OnJoin as OnJoinProto, OnJoin, - OnLeave as OnLeaveProto, Request as CallbackRequestProto, -}; +use medea_control_api_proto::grpc::medea_callback as proto; use crate::api::control::refs::StatefulFid; @@ -30,10 +26,10 @@ impl OnLeaveEvent { } } -impl Into for OnLeaveEvent { - fn into(self) -> OnLeaveProto { - let on_leave: OnLeaveReasonProto = self.reason.into(); - OnLeaveProto { +impl Into for OnLeaveEvent { + fn into(self) -> proto::OnLeave { + let on_leave: proto::on_leave::Reason = self.reason.into(); + proto::OnLeave { reason: on_leave as i32, } } @@ -52,12 +48,12 @@ pub enum OnLeaveReason { ServerShutdown, } -impl Into for OnLeaveReason { - fn into(self) -> OnLeaveReasonProto { +impl Into for OnLeaveReason { + fn into(self) -> proto::on_leave::Reason { match self { - Self::LostConnection => OnLeaveReasonProto::LostConnection, - Self::ServerShutdown => OnLeaveReasonProto::ServerShutdown, - Self::Disconnected => OnLeaveReasonProto::Disconnected, + Self::LostConnection => proto::on_leave::Reason::LostConnection, + Self::ServerShutdown => proto::on_leave::Reason::ServerShutdown, + Self::Disconnected => proto::on_leave::Reason::Disconnected, } } } @@ -66,9 +62,9 @@ impl Into for OnLeaveReason { #[derive(Debug)] pub struct OnJoinEvent; -impl Into for OnJoinEvent { - fn into(self) -> OnJoin { - OnJoinProto {} +impl Into for OnJoinEvent { + fn into(self) -> proto::OnJoin { + proto::OnJoin {} } } @@ -79,14 +75,14 @@ pub enum CallbackEvent { OnLeave(OnLeaveEvent), } -impl Into for CallbackEvent { - fn into(self) -> RequestOneofEventProto { +impl Into for CallbackEvent { + fn into(self) -> proto::request::Event { match self { Self::OnJoin(on_join) => { - RequestOneofEventProto::OnJoin(on_join.into()) + proto::request::Event::OnJoin(on_join.into()) } Self::OnLeave(on_leave) => { - RequestOneofEventProto::OnLeave(on_leave.into()) + proto::request::Event::OnLeave(on_leave.into()) } } } @@ -123,9 +119,9 @@ impl CallbackRequest { } } -impl Into for CallbackRequest { - fn into(self) -> CallbackRequestProto { - CallbackRequestProto { +impl Into for CallbackRequest { + fn into(self) -> proto::Request { + proto::Request { event: Some(self.event.into()), fid: self.fid.to_string(), at: self.at.to_rfc3339(), diff --git a/src/api/control/endpoints/mod.rs b/src/api/control/endpoints/mod.rs index 37fdbf411..53017449c 100644 --- a/src/api/control/endpoints/mod.rs +++ b/src/api/control/endpoints/mod.rs @@ -8,13 +8,9 @@ pub mod webrtc_publish_endpoint; use std::convert::TryFrom; use derive_more::{Display, From, Into}; +use medea_control_api_proto::grpc::medea as proto; use serde::Deserialize; -use medea_control_api_proto::grpc::medea::{ - create_request::El as ElementProto, - member::element::El as MemberElementProto, -}; - use super::{member::MemberElement, TryFromProtobufError}; #[doc(inline)] @@ -70,13 +66,14 @@ impl Into for EndpointSpec { } } -impl TryFrom<(Id, MemberElementProto)> for EndpointSpec { +impl TryFrom<(Id, proto::member::element::El)> for EndpointSpec { type Error = TryFromProtobufError; fn try_from( - (_, proto): (Id, MemberElementProto), + (_, proto): (Id, proto::member::element::El), ) -> Result { - use MemberElementProto::*; + use proto::member::element::El::*; + match proto { WebrtcPlay(elem) => { let play = WebRtcPlayEndpoint::try_from(&elem)?; @@ -90,11 +87,13 @@ impl TryFrom<(Id, MemberElementProto)> for EndpointSpec { } } -impl TryFrom<(Id, ElementProto)> for EndpointSpec { +impl TryFrom<(Id, proto::create_request::El)> for EndpointSpec { type Error = TryFromProtobufError; - fn try_from((id, proto): (Id, ElementProto)) -> Result { - use ElementProto::*; + fn try_from( + (id, proto): (Id, proto::create_request::El), + ) -> Result { + use proto::create_request::El::*; match proto { WebrtcPlay(elem) => { let play = WebRtcPlayEndpoint::try_from(&elem)?; diff --git a/src/api/control/endpoints/webrtc_play_endpoint.rs b/src/api/control/endpoints/webrtc_play_endpoint.rs index 5d7d140df..a8035a789 100644 --- a/src/api/control/endpoints/webrtc_play_endpoint.rs +++ b/src/api/control/endpoints/webrtc_play_endpoint.rs @@ -5,8 +5,7 @@ use std::convert::TryFrom; use derive_more::{Display, From, Into}; -use medea_control_api_proto::grpc::medea as medea_grpc_control_api; -use medea_grpc_control_api::WebRtcPlayEndpoint as WebRtcPlayEndpointProto; +use medea_control_api_proto::grpc::medea as proto; use serde::Deserialize; use crate::api::control::{refs::SrcUri, TryFromProtobufError}; @@ -28,10 +27,12 @@ pub struct WebRtcPlayEndpoint { pub force_relay: bool, } -impl TryFrom<&WebRtcPlayEndpointProto> for WebRtcPlayEndpoint { +impl TryFrom<&proto::WebRtcPlayEndpoint> for WebRtcPlayEndpoint { type Error = TryFromProtobufError; - fn try_from(value: &WebRtcPlayEndpointProto) -> Result { + fn try_from( + value: &proto::WebRtcPlayEndpoint, + ) -> Result { Ok(Self { src: SrcUri::try_from(value.src.clone())?, force_relay: value.force_relay, diff --git a/src/api/control/endpoints/webrtc_publish_endpoint.rs b/src/api/control/endpoints/webrtc_publish_endpoint.rs index 9622c2c2a..1c0619805 100644 --- a/src/api/control/endpoints/webrtc_publish_endpoint.rs +++ b/src/api/control/endpoints/webrtc_publish_endpoint.rs @@ -5,10 +5,7 @@ use derive_more::{Display, From, Into}; use serde::Deserialize; -use medea_control_api_proto::grpc::medea::{ - web_rtc_publish_endpoint::P2p as WebRtcPublishEndpointP2pProto, - WebRtcPublishEndpoint as WebRtcPublishEndpointProto, -}; +use medea_control_api_proto::grpc::medea as proto; /// ID of [`WebRtcPublishEndpoint`]. #[derive( @@ -29,22 +26,26 @@ pub enum P2pMode { IfPossible, } -impl From for P2pMode { - fn from(value: WebRtcPublishEndpointP2pProto) -> Self { +impl From for P2pMode { + fn from(value: proto::web_rtc_publish_endpoint::P2p) -> Self { + use proto::web_rtc_publish_endpoint::P2p::*; + match value { - WebRtcPublishEndpointP2pProto::Always => Self::Always, - WebRtcPublishEndpointP2pProto::IfPossible => Self::IfPossible, - WebRtcPublishEndpointP2pProto::Never => Self::Never, + Always => Self::Always, + IfPossible => Self::IfPossible, + Never => Self::Never, } } } -impl Into for P2pMode { - fn into(self) -> WebRtcPublishEndpointP2pProto { +impl Into for P2pMode { + fn into(self) -> proto::web_rtc_publish_endpoint::P2p { + use proto::web_rtc_publish_endpoint::P2p::*; + match self { - Self::Always => WebRtcPublishEndpointP2pProto::Always, - Self::IfPossible => WebRtcPublishEndpointP2pProto::IfPossible, - Self::Never => WebRtcPublishEndpointP2pProto::Never, + Self::Always => Always, + Self::IfPossible => IfPossible, + Self::Never => Never, } } } @@ -61,11 +62,11 @@ pub struct WebRtcPublishEndpoint { pub force_relay: bool, } -impl From<&WebRtcPublishEndpointProto> for WebRtcPublishEndpoint { - fn from(value: &WebRtcPublishEndpointProto) -> Self { +impl From<&proto::WebRtcPublishEndpoint> for WebRtcPublishEndpoint { + fn from(value: &proto::WebRtcPublishEndpoint) -> Self { Self { p2p: P2pMode::from( - WebRtcPublishEndpointP2pProto::from_i32(value.p2p) + proto::web_rtc_publish_endpoint::P2p::from_i32(value.p2p) .unwrap_or_default(), ), force_relay: value.force_relay, diff --git a/src/api/control/error_codes.rs b/src/api/control/error_codes.rs index 9c9a9f52d..e7ee7e841 100644 --- a/src/api/control/error_codes.rs +++ b/src/api/control/error_codes.rs @@ -7,7 +7,7 @@ use std::string::ToString; use derive_more::Display; -use medea_control_api_proto::grpc::medea::Error as ErrorProto; +use medea_control_api_proto::grpc::medea as proto; use crate::{ api::control::{ @@ -101,15 +101,15 @@ impl ErrorResponse { } } -impl Into for ErrorResponse { - fn into(self) -> ErrorProto { +impl Into for ErrorResponse { + fn into(self) -> proto::Error { let text = if let Some(additional_text) = &self.explanation { format!("{} {}", self.error_code.to_string(), additional_text) } else { self.error_code.to_string() }; - ErrorProto { + proto::Error { doc: String::new(), text, element: self.element_id.unwrap_or_default(), diff --git a/src/api/control/grpc/server.rs b/src/api/control/grpc/server.rs index ccc3dc321..3d0437fb2 100644 --- a/src/api/control/grpc/server.rs +++ b/src/api/control/grpc/server.rs @@ -11,14 +11,13 @@ use actix::{Actor, Addr, Arbiter, Context, Handler, MailboxError}; use derive_more::{Display, From}; use failure::Fail; use futures::future::{self, BoxFuture, FutureExt as _, TryFutureExt as _}; -use medea_control_api_proto::grpc::medea::{ - control_api_server::{ +use medea_control_api_proto::grpc::{ + medea as proto, + medea::control_api_server::{ ControlApi, ControlApiServer as TonicControlApiServer, }, - create_request::El as CreateRequestOneof, - CreateRequest, CreateResponse, Element, GetResponse, IdRequest, Response, }; -use tonic::transport::Server; +use tonic::{transport::Server, Status}; use crate::{ api::control::{ @@ -40,7 +39,6 @@ use crate::{ }, AppContext, }; -use tonic::Status; /// Errors which can happen while processing requests to gRPC [Control API]. /// @@ -132,10 +130,10 @@ impl ControlApiService { .boxed() } - /// Creates element based on provided [`CreateRequest`]. + /// Creates element based on provided [`proto::CreateRequest`]. pub fn create_element( &self, - req: CreateRequest, + req: proto::CreateRequest, ) -> BoxFuture<'static, Result> { let unparsed_parent_fid = req.parent_fid; let elem = if let Some(elem) = req.el { @@ -164,7 +162,7 @@ impl ControlApiService { match parent_fid { StatefulFid::Room(parent_fid) => match elem { - CreateRequestOneof::Member(member) => { + proto::create_request::El::Member(member) => { let id: MemberId = member.id.clone().into(); match MemberSpec::try_from(member) .map_err(ErrorResponse::from) @@ -184,12 +182,12 @@ impl ControlApiService { }, StatefulFid::Member(parent_fid) => { let (endpoint, id) = match elem { - CreateRequestOneof::WebrtcPlay(play) => ( + proto::create_request::El::WebrtcPlay(play) => ( WebRtcPlayEndpoint::try_from(&play) .map(EndpointSpec::from), play.id.into(), ), - CreateRequestOneof::WebrtcPub(publish) => ( + proto::create_request::El::WebrtcPub(publish) => ( Ok(WebRtcPublishEndpoint::from(&publish)) .map(EndpointSpec::from), publish.id.into(), @@ -218,10 +216,10 @@ impl ControlApiService { } } - /// Deletes element by [`IdRequest`]. + /// Deletes element by [`proto::IdRequest`]. pub fn delete_element( &self, - req: IdRequest, + req: proto::IdRequest, ) -> BoxFuture<'static, Result<(), ErrorResponse>> { let room_service = self.room_service.clone(); async move { @@ -243,12 +241,15 @@ impl ControlApiService { .boxed() } - /// Returns requested by [`IdRequest`] [`Element`]s serialized to protobuf. + /// Returns requested by [`proto::IdRequest`] [`proto::Element`]s serialized + /// to protobuf. pub fn get_element( &self, - req: IdRequest, - ) -> BoxFuture<'static, Result, ErrorResponse>> - { + req: proto::IdRequest, + ) -> BoxFuture< + 'static, + Result, ErrorResponse>, + > { let room_service = self.room_service.clone(); async move { let mut fids = Vec::new(); @@ -277,13 +278,13 @@ impl ControlApiService { impl ControlApi for ControlApiService { async fn create( &self, - request: tonic::Request, - ) -> Result, Status> { + request: tonic::Request, + ) -> Result, Status> { debug!("Create Request: {:?}", request); let create_response = match self.create_element(request.into_inner()).await { - Ok(sid) => CreateResponse { sid, error: None }, - Err(err) => CreateResponse { + Ok(sid) => proto::CreateResponse { sid, error: None }, + Err(err) => proto::CreateResponse { sid: HashMap::new(), error: Some(err.into()), }, @@ -294,11 +295,11 @@ impl ControlApi for ControlApiService { async fn delete( &self, - request: tonic::Request, - ) -> Result, Status> { + request: tonic::Request, + ) -> Result, Status> { let response = match self.delete_element(request.into_inner()).await { - Ok(_) => Response { error: None }, - Err(e) => Response { + Ok(_) => proto::Response { error: None }, + Err(e) => proto::Response { error: Some(e.into()), }, }; @@ -308,14 +309,14 @@ impl ControlApi for ControlApiService { async fn get( &self, - request: tonic::Request, - ) -> Result, Status> { + request: tonic::Request, + ) -> Result, Status> { let response = match self.get_element(request.into_inner()).await { - Ok(elements) => GetResponse { + Ok(elements) => proto::GetResponse { elements, error: None, }, - Err(e) => GetResponse { + Err(e) => proto::GetResponse { elements: HashMap::new(), error: Some(e.into()), }, diff --git a/src/api/control/member.rs b/src/api/control/member.rs index 06a3198d7..ab57f70b7 100644 --- a/src/api/control/member.rs +++ b/src/api/control/member.rs @@ -5,10 +5,7 @@ use std::{collections::HashMap, convert::TryFrom}; use derive_more::{Display, From}; -use medea_control_api_proto::grpc::medea::{ - create_request::El as ElementProto, room::element::El as RoomElementProto, - Member as MemberProto, -}; +use medea_control_api_proto::grpc::medea as proto; use rand::{distributions::Alphanumeric, Rng}; use serde::Deserialize; @@ -145,10 +142,10 @@ fn generate_member_credentials() -> String { .collect() } -impl TryFrom for MemberSpec { +impl TryFrom for MemberSpec { type Error = TryFromProtobufError; - fn try_from(member: MemberProto) -> Result { + fn try_from(member: proto::Member) -> Result { let mut pipeline = HashMap::new(); for (id, member_element) in member.pipeline { if let Some(elem) = member_element.el { @@ -192,15 +189,17 @@ impl TryFrom for MemberSpec { } macro_rules! impl_try_from_proto_for_member { - ($proto:tt) => { + ($proto:path) => { impl TryFrom<(Id, $proto)> for MemberSpec { type Error = TryFromProtobufError; fn try_from( (id, proto): (Id, $proto), ) -> Result { + use $proto as proto_el; + match proto { - $proto::Member(member) => Self::try_from(member), + proto_el::Member(member) => Self::try_from(member), _ => Err(TryFromProtobufError::ExpectedOtherElement( String::from("Member"), id.to_string(), @@ -211,8 +210,8 @@ macro_rules! impl_try_from_proto_for_member { }; } -impl_try_from_proto_for_member!(RoomElementProto); -impl_try_from_proto_for_member!(ElementProto); +impl_try_from_proto_for_member!(proto::room::element::El); +impl_try_from_proto_for_member!(proto::create_request::El); impl TryFrom<&RoomElement> for MemberSpec { type Error = TryFromElementError; diff --git a/src/api/control/room.rs b/src/api/control/room.rs index 9c93a0321..1762b9fb2 100644 --- a/src/api/control/room.rs +++ b/src/api/control/room.rs @@ -5,10 +5,7 @@ use std::{collections::HashMap, convert::TryFrom}; use derive_more::{Display, From}; -#[rustfmt::skip] -use medea_control_api_proto::grpc::medea::{ - create_request::El as ElementProto, -}; +use medea_control_api_proto::grpc::medea as proto; use serde::Deserialize; use crate::api::control::{ @@ -54,12 +51,14 @@ pub struct RoomSpec { pub pipeline: Pipeline, } -impl TryFrom for RoomSpec { +impl TryFrom for RoomSpec { type Error = TryFromProtobufError; - fn try_from(proto: ElementProto) -> Result { + fn try_from(proto: proto::create_request::El) -> Result { + use proto::create_request::El; + let id = match proto { - ElementProto::Room(room) => { + El::Room(room) => { let mut pipeline = HashMap::new(); for (id, room_element) in room.pipeline { if let Some(elem) = room_element.el { @@ -77,9 +76,9 @@ impl TryFrom for RoomSpec { pipeline, }); } - ElementProto::Member(member) => member.id, - ElementProto::WebrtcPub(webrtc_pub) => webrtc_pub.id, - ElementProto::WebrtcPlay(webrtc_play) => webrtc_play.id, + El::Member(member) => member.id, + El::WebrtcPub(webrtc_pub) => webrtc_pub.id, + El::WebrtcPlay(webrtc_play) => webrtc_play.id, }; Err(TryFromProtobufError::ExpectedOtherElement( diff --git a/src/signalling/elements/endpoints/mod.rs b/src/signalling/elements/endpoints/mod.rs index 832828b00..2cc21d1a7 100644 --- a/src/signalling/elements/endpoints/mod.rs +++ b/src/signalling/elements/endpoints/mod.rs @@ -5,7 +5,7 @@ pub mod webrtc; use derive_more::From; -use medea_control_api_proto::grpc::medea::Element as RootElementProto; +use medea_control_api_proto::grpc::medea as proto; /// Enum which can store all kinds of [Medea] endpoints. /// @@ -16,8 +16,8 @@ pub enum Endpoint { WebRtcPlayEndpoint(webrtc::WebRtcPlayEndpoint), } -impl Into for Endpoint { - fn into(self) -> RootElementProto { +impl Into for Endpoint { + fn into(self) -> proto::Element { match self { Self::WebRtcPublishEndpoint(play) => play.into(), Self::WebRtcPlayEndpoint(publish) => publish.into(), diff --git a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs index 9d5ebc0bd..e80253108 100644 --- a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs @@ -6,11 +6,7 @@ use std::{ }; use medea_client_api_proto::PeerId; -use medea_control_api_proto::grpc::medea::{ - element::El as RootElProto, - member::{element::El as MemberElProto, Element as ElementProto}, - Element as RootElementProto, WebRtcPlayEndpoint as WebRtcPlayEndpointProto, -}; +use medea_control_api_proto::grpc::medea as proto; use crate::{ api::control::{ @@ -208,17 +204,17 @@ impl WeakWebRtcPlayEndpoint { } } -impl Into for WebRtcPlayEndpoint { - fn into(self) -> ElementProto { - ElementProto { - el: Some(MemberElProto::WebrtcPlay(self.into())), +impl Into for WebRtcPlayEndpoint { + fn into(self) -> proto::member::Element { + proto::member::Element { + el: Some(proto::member::element::El::WebrtcPlay(self.into())), } } } -impl Into for WebRtcPlayEndpoint { - fn into(self) -> WebRtcPlayEndpointProto { - WebRtcPlayEndpointProto { +impl Into for WebRtcPlayEndpoint { + fn into(self) -> proto::WebRtcPlayEndpoint { + proto::WebRtcPlayEndpoint { on_start: String::new(), on_stop: String::new(), src: self.src_uri().to_string(), @@ -228,10 +224,10 @@ impl Into for WebRtcPlayEndpoint { } } -impl Into for WebRtcPlayEndpoint { - fn into(self) -> RootElementProto { - RootElementProto { - el: Some(RootElProto::WebrtcPlay(self.into())), +impl Into for WebRtcPlayEndpoint { + fn into(self) -> proto::Element { + proto::Element { + el: Some(proto::element::El::WebrtcPlay(self.into())), } } } diff --git a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs index 24c37f570..452f9c6fc 100644 --- a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs @@ -7,13 +7,7 @@ use std::{ }; use medea_client_api_proto::PeerId; -use medea_control_api_proto::grpc::medea::{ - element::El as RootElProto, - member::{element::El as MemberElProto, Element as ElementProto}, - web_rtc_publish_endpoint::P2p as WebRtcPublishEndpointP2pProto, - Element as RootElementProto, - WebRtcPublishEndpoint as WebRtcPublishEndpointProto, -}; +use medea_control_api_proto::grpc::medea as proto; use crate::{ api::control::endpoints::webrtc_publish_endpoint::{ @@ -245,10 +239,10 @@ impl WeakWebRtcPublishEndpoint { } } -impl Into for WebRtcPublishEndpoint { - fn into(self) -> WebRtcPublishEndpointProto { - let p2p: WebRtcPublishEndpointP2pProto = self.p2p().into(); - WebRtcPublishEndpointProto { +impl Into for WebRtcPublishEndpoint { + fn into(self) -> proto::WebRtcPublishEndpoint { + let p2p: proto::web_rtc_publish_endpoint::P2p = self.p2p().into(); + proto::WebRtcPublishEndpoint { p2p: p2p as i32, id: self.id().to_string(), force_relay: self.is_force_relayed(), @@ -258,18 +252,18 @@ impl Into for WebRtcPublishEndpoint { } } -impl Into for WebRtcPublishEndpoint { - fn into(self) -> ElementProto { - ElementProto { - el: Some(MemberElProto::WebrtcPub(self.into())), +impl Into for WebRtcPublishEndpoint { + fn into(self) -> proto::member::Element { + proto::member::Element { + el: Some(proto::member::element::El::WebrtcPub(self.into())), } } } -impl Into for WebRtcPublishEndpoint { - fn into(self) -> RootElementProto { - RootElementProto { - el: Some(RootElProto::WebrtcPub(self.into())), +impl Into for WebRtcPublishEndpoint { + fn into(self) -> proto::Element { + proto::Element { + el: Some(proto::element::El::WebrtcPub(self.into())), } } } diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index 107bdc6ae..6afb73281 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -12,11 +12,7 @@ use std::{ use derive_more::Display; use failure::Fail; use medea_client_api_proto::{IceServer, PeerId}; -use medea_control_api_proto::grpc::medea::{ - element::El as RootElProto, - room::{element::El as RoomElProto, Element as ElementProto}, - Element as RootElementProto, Member as MemberProto, -}; +use medea_control_api_proto::grpc::medea as proto; use crate::{ api::control::{ @@ -510,8 +506,8 @@ pub fn parse_members( Ok(members) } -impl Into for Member { - fn into(self) -> MemberProto { +impl Into for Member { + fn into(self) -> proto::Member { let member_pipeline = self .sinks() .into_iter() @@ -522,7 +518,8 @@ impl Into for Member { .map(|(id, publish)| (id.to_string(), publish.into())), ) .collect(); - MemberProto { + + proto::Member { id: self.id().to_string(), credentials: self.credentials(), on_leave: self @@ -538,18 +535,18 @@ impl Into for Member { } } -impl Into for Member { - fn into(self) -> ElementProto { - ElementProto { - el: Some(RoomElProto::Member(self.into())), +impl Into for Member { + fn into(self) -> proto::room::Element { + proto::room::Element { + el: Some(proto::room::element::El::Member(self.into())), } } } -impl Into for Member { - fn into(self) -> RootElementProto { - RootElementProto { - el: Some(RootElProto::Member(self.into())), +impl Into for Member { + fn into(self) -> proto::Element { + proto::Element { + el: Some(proto::element::El::Member(self.into())), } } } diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 6c20f92ae..07a492738 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -15,9 +15,7 @@ use futures::future::{self, FutureExt as _, LocalBoxFuture}; use medea_client_api_proto::{ Command, CommandHandler, Event, IceCandidate, PeerId, PeerMetrics, TrackId, }; -use medea_control_api_proto::grpc::medea::{ - element::El as RootElProto, Element as ElementProto, Room as RoomProto, -}; +use medea_control_api_proto::grpc::medea as proto; use crate::{ api::{ @@ -927,25 +925,25 @@ impl Actor for Room { } } -impl Into for &mut Room { - fn into(self) -> RoomProto { +impl Into for &mut Room { + fn into(self) -> proto::Room { let pipeline = self .members .members() .into_iter() .map(|(id, member)| (id.to_string(), member.into())) .collect(); - RoomProto { + proto::Room { id: self.id().to_string(), pipeline, } } } -impl Into for &mut Room { - fn into(self) -> ElementProto { - ElementProto { - el: Some(RootElProto::Room(self.into())), +impl Into for &mut Room { + fn into(self) -> proto::Element { + proto::Element { + el: Some(proto::element::El::Room(self.into())), } } } @@ -958,23 +956,24 @@ impl Into for &mut Room { /// Message for serializing this [`Room`] and [`Room`]'s elements to protobuf /// spec. #[derive(Message)] -#[rtype(result = "Result, RoomError>")] +#[rtype(result = "Result, RoomError>")] pub struct SerializeProto(pub Vec); impl Handler for Room { - type Result = Result, RoomError>; + type Result = Result, RoomError>; fn handle( &mut self, msg: SerializeProto, _: &mut Self::Context, ) -> Self::Result { - let mut serialized: HashMap = HashMap::new(); + let mut serialized: HashMap = + HashMap::new(); for fid in msg.0 { match &fid { StatefulFid::Room(room_fid) => { if room_fid.room_id() == &self.id { - let current_room: ElementProto = self.into(); + let current_room: proto::Element = self.into(); serialized.insert(fid, current_room); } else { return Err(RoomError::WrongRoomId( diff --git a/src/signalling/room_service.rs b/src/signalling/room_service.rs index f21fe4ac4..4d05c6bc2 100644 --- a/src/signalling/room_service.rs +++ b/src/signalling/room_service.rs @@ -10,7 +10,7 @@ use failure::Fail; use futures::future::{ self, FutureExt as _, LocalBoxFuture, TryFutureExt as _, }; -use medea_control_api_proto::grpc::medea::Element as ElementProto; +use medea_control_api_proto::grpc::medea as proto; use crate::{ api::control::{ @@ -490,7 +490,7 @@ impl Handler> for RoomService { /// Serialized to protobuf `Element`s which will be returned from [`Get`] on /// success result. -type SerializedElements = HashMap; +type SerializedElements = HashMap; /// Message which returns serialized to protobuf objects by provided /// [`Fid`]. diff --git a/tests/e2e/callbacks/member.rs b/tests/e2e/callbacks/member.rs index 5fee35cb0..920154e98 100644 --- a/tests/e2e/callbacks/member.rs +++ b/tests/e2e/callbacks/member.rs @@ -5,9 +5,7 @@ use std::time::Duration; use actix::{clock::delay_for, Addr, Context}; use actix_http::ws::CloseCode; use medea_client_api_proto::Event; -use medea_control_api_proto::grpc::medea_callback::{ - on_leave::Reason as OnLeaveReason, request::Event as EventProto, Request, -}; +use medea_control_api_proto::grpc::medea_callback as proto; use crate::{ callbacks::{GetCallbacks, GrpcCallbackServer}, @@ -83,7 +81,8 @@ async fn on_join() { let on_joins_count = callbacks .into_iter() .filter(|r| { - if let EventProto::OnJoin(_) = r.event.as_ref().unwrap() { + if let proto::request::Event::OnJoin(_) = r.event.as_ref().unwrap() + { true } else { false @@ -104,7 +103,7 @@ async fn on_join() { /// 3. Wait `300ms`. /// /// 4. Check that test callback server receives `on_leave` callback with -/// [`OnLeaveReason::DISONNECTED`]. +/// [`proto::on_leave::Reason::DISONNECTED`]. #[actix_rt::test] async fn on_leave_normally_disconnected() { const TEST_NAME: &str = "member_callback_on_leave"; @@ -117,14 +116,16 @@ async fn on_leave_normally_disconnected() { let on_leaves_count = callbacks .into_iter() - .filter_map(|mut req| { - if let Some(EventProto::OnLeave(on_leave)) = req.event { + .filter_map(|req| { + if let Some(proto::request::Event::OnLeave(on_leave)) = req.event { Some(on_leave.reason) } else { None } }) - .filter(|reason| reason == &(OnLeaveReason::Disconnected as i32)) + .filter(|reason| { + reason == &(proto::on_leave::Reason::Disconnected as i32) + }) .count(); assert_eq!(on_leaves_count, 1); } @@ -140,7 +141,7 @@ async fn on_leave_normally_disconnected() { /// 3. Wait `3000ms`. /// /// 4. Check that test callback server receives `on_leave` callback with -/// [`OnLeaveReason::LOST_CONNECTION`]. +/// [`proto::on_leave::Reason::LOST_CONNECTION`]. #[actix_rt::test] async fn on_leave_on_connection_loss() { const TEST_NAME: &str = "member_callback_on_leave_on_connection_loss"; @@ -154,14 +155,16 @@ async fn on_leave_on_connection_loss() { let on_leaves_count = callbacks .into_iter() - .filter_map(|mut req| { - if let Some(EventProto::OnLeave(on_leave)) = req.event { + .filter_map(|req| { + if let Some(proto::request::Event::OnLeave(on_leave)) = req.event { Some(on_leave.reason) } else { None } }) - .filter(|reason| reason == &(OnLeaveReason::LostConnection as i32)) + .filter(|reason| { + reason == &(proto::on_leave::Reason::LostConnection as i32) + }) .count(); assert_eq!(on_leaves_count, 1); } diff --git a/tests/e2e/callbacks/mod.rs b/tests/e2e/callbacks/mod.rs index d921116d1..4a76ea54c 100644 --- a/tests/e2e/callbacks/mod.rs +++ b/tests/e2e/callbacks/mod.rs @@ -5,17 +5,14 @@ mod member; use std::sync::{Arc, Mutex}; use actix::{Actor, Addr, Arbiter, Context, Handler, Message}; -use futures::{ - compat::Future01CompatExt as _, FutureExt as _, TryFutureExt as _, -}; use medea_control_api_proto::grpc::medea_callback::{ + self as proto, callback_server::{Callback, CallbackServer as TonicCallbackServer}, - Request, Response, }; use tonic::{transport::Server, Status}; /// Requests which [`GrpcCallbackServer`] will receive. -type CallbackItems = Arc>>; +type CallbackItems = Arc>>; /// gRPC Control API callback server for tests. pub struct GrpcCallbackServer { @@ -26,13 +23,13 @@ impl Actor for GrpcCallbackServer { type Context = Context; } -/// Returns all [`Request`]s which this [`GrpcCallbackServer`] received. +/// Returns all [`proto::Request`]s which this [`GrpcCallbackServer`] received. #[derive(Message)] -#[rtype(result = "Result, ()>")] +#[rtype(result = "Result, ()>")] pub struct GetCallbacks; impl Handler for GrpcCallbackServer { - type Result = Result, ()>; + type Result = Result, ()>; fn handle( &mut self, @@ -59,10 +56,10 @@ impl CallbackServer { impl Callback for CallbackServer { async fn on_event( &self, - request: tonic::Request, - ) -> Result, Status> { + request: tonic::Request, + ) -> Result, Status> { self.callbacks.lock().unwrap().push(request.into_inner()); - Ok(tonic::Response::new(Response {})) + Ok(tonic::Response::new(proto::Response {})) } } diff --git a/tests/e2e/grpc_control_api/create.rs b/tests/e2e/grpc_control_api/create.rs index 15933dd37..9d3e2bc15 100644 --- a/tests/e2e/grpc_control_api/create.rs +++ b/tests/e2e/grpc_control_api/create.rs @@ -6,11 +6,7 @@ //! [Control API]: https://tinyurl.com/yxsqplq7 use medea::api::control::error_codes::ErrorCode; -use medea_control_api_proto::grpc::medea::{ - element::El as RootEl, member::element::El as MemberEl, - room::element::El as RoomEl, - web_rtc_publish_endpoint::P2p as WebRtcPublishEndpoint_P2P, -}; +use medea_control_api_proto::grpc::medea as proto; use super::{ create_room_req, ControlClient, MemberBuilder, RoomBuilder, @@ -19,7 +15,6 @@ use super::{ mod room { use super::*; - use crate::grpc_control_api::Elem; #[actix_rt::test] async fn room() { @@ -36,12 +31,12 @@ mod room { &format!("ws://127.0.0.1:8080/ws/{}/responder/test", TEST_NAME) ); - let mut get_resp = client.get(TEST_NAME).await; + let get_resp = client.get(TEST_NAME).await; let mut room = get_resp.take_room(); let responder = room.pipeline.remove("responder").unwrap(); let responder = match responder.el.unwrap() { - RoomEl::Member(member) => member, + proto::room::element::El::Member(member) => member, _ => panic!(), }; assert_eq!(responder.credentials.as_str(), "test"); @@ -49,7 +44,7 @@ mod room { assert_eq!(responder_pipeline.len(), 1); let responder_play = responder_pipeline.remove("play").unwrap(); let responder_play = match responder_play.el.unwrap() { - MemberEl::WebrtcPlay(play) => play, + proto::member::element::El::WebrtcPlay(play) => play, _ => panic!(), }; assert_eq!( @@ -59,7 +54,7 @@ mod room { let publisher = room.pipeline.remove("publisher").unwrap(); let publisher = match publisher.el.unwrap() { - RoomEl::Member(member) => member, + proto::room::element::El::Member(member) => member, _ => panic!(), }; assert_ne!(publisher.credentials.as_str(), "test"); @@ -199,7 +194,7 @@ mod member { async fn element_id_mismatch() { let mut client = ControlClient::new().await; - let mut create_member = MemberBuilder::default() + let create_member = MemberBuilder::default() .id("asd") .build() .unwrap() @@ -226,7 +221,7 @@ mod endpoint { let create_req = WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::Never) + .p2p_mode(proto::web_rtc_publish_endpoint::P2p::Never) .build() .unwrap() .build_request(format!("{}/responder", TEST_NAME)); @@ -238,7 +233,10 @@ mod endpoint { .get(&format!("{}/responder/publish", TEST_NAME)) .await .take_webrtc_pub(); - assert_eq!(endpoint.p2p, WebRtcPublishEndpoint_P2P::Never as i32); + assert_eq!( + endpoint.p2p, + proto::web_rtc_publish_endpoint::P2p::Never as i32 + ); } #[actix_rt::test] @@ -257,7 +255,7 @@ mod endpoint { let create_play = WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::Always) + .p2p_mode(proto::web_rtc_publish_endpoint::P2p::Always) .build() .unwrap() .build_request(format!("{}/member", TEST_NAME)); @@ -277,7 +275,7 @@ mod endpoint { let create_publish = WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::Always) + .p2p_mode(proto::web_rtc_publish_endpoint::P2p::Always) .build() .unwrap() .build_request(format!("{}/member", TEST_NAME)); @@ -306,7 +304,7 @@ mod endpoint { let create_endpoint = WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::Always) + .p2p_mode(proto::web_rtc_publish_endpoint::P2p::Always) .build() .unwrap() .build_request(format!("{}/member", TEST_NAME)); @@ -356,7 +354,7 @@ mod endpoint { let create_endpoint = WebRtcPublishEndpointBuilder::default() .id("asd") - .p2p_mode(WebRtcPublishEndpoint_P2P::Always) + .p2p_mode(proto::web_rtc_publish_endpoint::P2p::Always) .build() .unwrap() .build_request("qwe"); diff --git a/tests/e2e/grpc_control_api/mod.rs b/tests/e2e/grpc_control_api/mod.rs index e877e735e..bc42e19e8 100644 --- a/tests/e2e/grpc_control_api/mod.rs +++ b/tests/e2e/grpc_control_api/mod.rs @@ -7,53 +7,35 @@ mod create; mod delete; mod signaling; -use std::{collections::HashMap, sync::Arc}; +use std::collections::HashMap; use derive_builder::*; -use medea::conf::ControlApi; use medea_control_api_proto::grpc::medea::{ - control_api_client::ControlApiClient, - create_request::El as CreateRequestEl, - element::El as RootEl, - member::{element::El as MemberEl, Element as Member_Element}, - room::{element::El as RoomEl, Element as Room_Element}, - web_rtc_publish_endpoint::P2p as WebRtcPublishEndpoint_P2P, - CreateRequest, Element, Error, IdRequest, Member as GrpcMember, - Room as GrpcRoom, WebRtcPlayEndpoint as GrpcWebRtcPlayEndpoint, - WebRtcPublishEndpoint as GrpcWebRtcPublishEndpoint, + self as proto, control_api_client::ControlApiClient, }; use tonic::transport::Channel; -pub struct Elem(pub Element); +pub struct TakeableElement(pub proto::Element); -impl Elem { - pub fn take_room(self) -> GrpcRoom { - match self.0.el.unwrap() { - RootEl::Room(room) => room, - _ => panic!("Not Room element!"), - } - } +macro_rules! gen_elem_take_fn { + ($name:tt -> $variant:tt($output:ty)) => { + pub fn $name(self) -> $output { + match self.0.el.unwrap() { + proto::element::El::$variant(elem) => elem, + _ => panic!("Not {} element!", stringify!($variant)), + } + } + }; +} - pub fn take_member(self) -> GrpcMember { - match self.0.el.unwrap() { - RootEl::Member(member) => member, - _ => panic!("Not Room element!"), - } - } +impl TakeableElement { + gen_elem_take_fn!(take_room -> Room(proto::Room)); - pub fn take_webrtc_pub(self) -> GrpcWebRtcPublishEndpoint { - match self.0.el.unwrap() { - RootEl::WebrtcPub(webrtc_pub) => webrtc_pub, - _ => panic!("Not Room element!"), - } - } + gen_elem_take_fn!(take_member -> Member(proto::Member)); - pub fn take_webrtc_play(self) -> GrpcWebRtcPlayEndpoint { - match self.0.el.unwrap() { - RootEl::WebrtcPlay(webrtc_play) => webrtc_play, - _ => panic!("Not Room element!"), - } - } + gen_elem_take_fn!( + take_webrtc_pub -> WebrtcPub(proto::WebRtcPublishEndpoint) + ); } /// Client for [Medea]'s gRPC [Control API]. @@ -78,32 +60,35 @@ impl ControlClient { ) } - /// Gets some [`Element`] by local URI. + /// Gets some [`proto::Element`] by local URI. /// /// # Panics /// /// - if [`GetResponse`] has error /// - if connection with server failed - pub async fn get(&mut self, uri: &str) -> Elem { + pub async fn get(&mut self, uri: &str) -> TakeableElement { let room = vec![uri.to_string()]; - let get_room_request = IdRequest { fid: room }; + let get_room_request = proto::IdRequest { fid: room }; let mut resp = self.0.get(get_room_request).await.unwrap().into_inner(); if let Some(err) = resp.error { panic!("{:?}", err); } - Elem(resp.elements.remove(&uri.to_string()).unwrap()) + TakeableElement(resp.elements.remove(&uri.to_string()).unwrap()) } - /// Tries to get some [`Element`] by local URI. + /// Tries to get some [`proto::Element`] by local URI. /// /// # Panics /// /// - if connection with server failed. - pub async fn try_get(&mut self, uri: &str) -> Result { + pub async fn try_get( + &mut self, + uri: &str, + ) -> Result { let room = vec![uri.to_string()]; - let get_room_request = IdRequest { fid: room }; + let get_room_request = proto::IdRequest { fid: room }; let mut resp = self.0.get(get_room_request).await.unwrap().into_inner(); if let Some(e) = resp.error { @@ -113,7 +98,7 @@ impl ControlClient { Ok(resp.elements.remove(&uri.to_string()).unwrap()) } - /// Creates `Element` and returns it sids. + /// Creates `proto::Element` and returns it sids. /// /// # Panics /// @@ -121,7 +106,7 @@ impl ControlClient { /// - if connection with server failed. pub async fn create( &mut self, - req: CreateRequest, + req: proto::CreateRequest, ) -> HashMap { let resp = self.0.create(req).await.unwrap().into_inner(); if let Some(e) = resp.error { @@ -131,16 +116,16 @@ impl ControlClient { resp.sid } - /// Tries to create `Element` and returns it sids. + /// Tries to create `proto::Element` and returns it sids. /// /// # Panics /// /// - if connection with server failed. pub async fn try_create( &mut self, - req: CreateRequest, - ) -> Result, Error> { - let mut resp = self.0.create(req).await.unwrap().into_inner(); + req: proto::CreateRequest, + ) -> Result, proto::Error> { + let resp = self.0.create(req).await.unwrap().into_inner(); if let Some(e) = resp.error { Err(e) @@ -149,17 +134,17 @@ impl ControlClient { } } - /// Deletes `Element`s by local URIs. + /// Deletes `proto::Element`s by local URIs. /// /// # Panics /// /// - if [`Response`] has error /// - if connection with server failed. - pub async fn delete(&mut self, ids: &[&str]) -> Result<(), Error> { + pub async fn delete(&mut self, ids: &[&str]) -> Result<(), proto::Error> { let delete_ids = ids.iter().map(|id| id.to_string()).collect(); - let delete_req = IdRequest { fid: delete_ids }; + let delete_req = proto::IdRequest { fid: delete_ids }; - let mut resp = self.0.delete(delete_req).await.unwrap().into_inner(); + let resp = self.0.delete(delete_req).await.unwrap().into_inner(); if let Some(e) = resp.error { Err(e) } else { @@ -178,26 +163,29 @@ pub struct Room { } impl Room { - pub fn build_request>(self, uri: T) -> CreateRequest { + pub fn build_request>( + self, + uri: T, + ) -> proto::CreateRequest { let members = self .members .into_iter() .map(|(id, member)| { - let room_element = Room_Element { - el: Some(RoomEl::Member(member.into())), + let room_element = proto::room::Element { + el: Some(proto::room::element::El::Member(member.into())), }; (id, room_element) }) .collect(); - let grpc_room = GrpcRoom { + let grpc_room = proto::Room { id: self.id, pipeline: members, }; - CreateRequest { + proto::CreateRequest { parent_fid: uri.into(), - el: Some(CreateRequestEl::Room(grpc_room)), + el: Some(proto::create_request::El::Room(grpc_room)), } } } @@ -231,15 +219,15 @@ pub struct Member { on_leave: Option, } -impl Into for Member { - fn into(self) -> GrpcMember { +impl Into for Member { + fn into(self) -> proto::Member { let pipeline = self .endpoints .into_iter() .map(|(id, element)| (id, element.into())) .collect(); - GrpcMember { + proto::Member { id: self.id, pipeline, on_leave: self.on_leave.unwrap_or_default(), @@ -250,10 +238,10 @@ impl Into for Member { } impl Member { - fn build_request>(self, url: T) -> CreateRequest { - CreateRequest { + fn build_request>(self, url: T) -> proto::CreateRequest { + proto::CreateRequest { parent_fid: url.into(), - el: Some(CreateRequestEl::Member(self.into())), + el: Some(proto::create_request::El::Member(self.into())), } } } @@ -284,18 +272,18 @@ impl Endpoint { } } -impl Into for Endpoint { - fn into(self) -> Member_Element { +impl Into for Endpoint { + fn into(self) -> proto::member::Element { let member_el = match self { Self::WebRtcPlayElement(element) => { - MemberEl::WebrtcPlay(element.into()) + proto::member::element::El::WebrtcPlay(element.into()) } Self::WebRtcPublishElement(element) => { - MemberEl::WebrtcPub(element.into()) + proto::member::element::El::WebrtcPub(element.into()) } }; - Member_Element { + proto::member::Element { el: Some(member_el), } } @@ -309,17 +297,20 @@ pub struct WebRtcPlayEndpoint { } impl WebRtcPlayEndpoint { - pub fn build_request>(self, url: T) -> CreateRequest { - CreateRequest { - el: Some(CreateRequestEl::WebrtcPlay(self.into())), + pub fn build_request>( + self, + url: T, + ) -> proto::CreateRequest { + proto::CreateRequest { + el: Some(proto::create_request::El::WebrtcPlay(self.into())), parent_fid: url.into(), } } } -impl Into for WebRtcPlayEndpoint { - fn into(self) -> GrpcWebRtcPlayEndpoint { - GrpcWebRtcPlayEndpoint { +impl Into for WebRtcPlayEndpoint { + fn into(self) -> proto::WebRtcPlayEndpoint { + proto::WebRtcPlayEndpoint { src: self.src, on_start: String::new(), on_stop: String::new(), @@ -339,21 +330,24 @@ impl Into for WebRtcPlayEndpoint { #[builder(setter(into))] pub struct WebRtcPublishEndpoint { id: String, - p2p_mode: WebRtcPublishEndpoint_P2P, + p2p_mode: proto::web_rtc_publish_endpoint::P2p, } impl WebRtcPublishEndpoint { - pub fn build_request>(self, url: T) -> CreateRequest { - CreateRequest { - el: Some(CreateRequestEl::WebrtcPub(self.into())), + pub fn build_request>( + self, + url: T, + ) -> proto::CreateRequest { + proto::CreateRequest { + el: Some(proto::create_request::El::WebrtcPub(self.into())), parent_fid: url.into(), } } } -impl Into for WebRtcPublishEndpoint { - fn into(self) -> GrpcWebRtcPublishEndpoint { - GrpcWebRtcPublishEndpoint { +impl Into for WebRtcPublishEndpoint { + fn into(self) -> proto::WebRtcPublishEndpoint { + proto::WebRtcPublishEndpoint { p2p: self.p2p_mode as i32, on_start: String::default(), on_stop: String::default(), @@ -369,10 +363,10 @@ impl Into for WebRtcPublishEndpoint { } } -/// Creates [`CreateRequest`] for creating `Room` element with provided `Room` -/// ID. +/// Creates [`proto::CreateRequest`] for creating `Room` element with provided +/// `Room` ID. /// -/// # Spec of `Room` which will be created with this [`CreateRequest`] +/// # Spec of `Room` which will be created with this [`proto::CreateRequest`] /// /// ```yaml /// kind: Room @@ -397,7 +391,7 @@ impl Into for WebRtcPublishEndpoint { /// spec: /// src: "local://{{ room_id }}/publisher/publish" /// ``` -fn create_room_req(room_id: &str) -> CreateRequest { +fn create_room_req(room_id: &str) -> proto::CreateRequest { RoomBuilder::default() .id(room_id.to_string()) .add_member( @@ -406,7 +400,7 @@ fn create_room_req(room_id: &str) -> CreateRequest { .add_endpoint( WebRtcPublishEndpointBuilder::default() .id("publish") - .p2p_mode(WebRtcPublishEndpoint_P2P::Always) + .p2p_mode(proto::web_rtc_publish_endpoint::P2p::Always) .build() .unwrap(), ) diff --git a/tests/e2e/grpc_control_api/signaling.rs b/tests/e2e/grpc_control_api/signaling.rs index 5ad2d1d7a..d50d05fd7 100644 --- a/tests/e2e/grpc_control_api/signaling.rs +++ b/tests/e2e/grpc_control_api/signaling.rs @@ -56,7 +56,7 @@ async fn signalling_starts_when_create_play_member_after_pub_member() { let mut control_client = ControlClient::new().await; - let mut create_room = RoomBuilder::default() + let create_room = RoomBuilder::default() .id(TEST_NAME) .add_member( MemberBuilder::default() @@ -234,7 +234,7 @@ async fn signalling_starts_in_loopback_scenario() { async fn peers_removed_on_delete_member() { const TEST_NAME: &str = "delete-member-check-peers-removed"; - let mut control_client = Rc::new(RefCell::new(ControlClient::new().await)); + let control_client = Rc::new(RefCell::new(ControlClient::new().await)); let create_room = RoomBuilder::default() .id(TEST_NAME) From 3244322801e63842c30aeaec7950f90cfb25f9a7 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Wed, 29 Jan 2020 20:23:00 +0300 Subject: [PATCH 014/224] Refactor [run ci] --- Cargo.lock | 184 +++++++++-------------- Cargo.toml | 7 +- mock/control-api/src/api/endpoint.rs | 5 +- mock/control-api/src/api/mod.rs | 3 +- mock/control-api/src/callback/server.rs | 4 +- mock/control-api/src/client.rs | 30 ++-- mock/control-api/src/main.rs | 1 - proto/control-api/build.rs | 8 +- src/api/control/callback/clients/grpc.rs | 2 +- src/api/control/callback/clients/mod.rs | 7 +- src/api/control/grpc/server.rs | 4 +- src/main.rs | 65 +++++--- tests/e2e/callbacks/mod.rs | 3 +- 13 files changed, 145 insertions(+), 178 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b2ce8df4f..a3ce1222c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,9 +25,9 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -43,7 +43,7 @@ dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -111,7 +111,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -152,7 +152,7 @@ dependencies = [ "actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -179,7 +179,7 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -238,7 +238,7 @@ dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -268,7 +268,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", @@ -288,7 +288,7 @@ dependencies = [ "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -318,7 +318,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "aho-corasick" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -344,7 +344,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayref" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -367,16 +367,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "async-stream" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-stream-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-stream-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "async-stream-impl" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -479,7 +479,7 @@ name = "blake2b_simd" version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -575,14 +575,6 @@ dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cmake" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "combine" version = "3.8.1" @@ -746,7 +738,7 @@ dependencies = [ "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1072,29 +1064,6 @@ dependencies = [ "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "grpcio" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "grpcio-sys" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", - "cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "h2" version = "0.2.1" @@ -1109,7 +1078,7 @@ dependencies = [ "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1145,7 +1114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1192,12 +1161,12 @@ dependencies = [ "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1254,7 +1223,7 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1378,7 +1347,6 @@ dependencies = [ "dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "humantime-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "medea-client-api-proto 0.2.0-dev", @@ -1386,7 +1354,6 @@ dependencies = [ "medea-macro 0.2.0-dev", "mockall 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1403,7 +1370,7 @@ dependencies = [ "slog-stdlog 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "smart-default 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1734,7 +1701,7 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1769,15 +1736,15 @@ dependencies = [ [[package]] name = "pin-project" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project-internal 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project-internal" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1795,11 +1762,6 @@ name = "pin-utils" version = "0.1.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "pkg-config" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "ppv-lite86" version = "0.2.6" @@ -2033,11 +1995,11 @@ dependencies = [ "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2062,7 +2024,7 @@ name = "regex" version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2204,7 +2166,7 @@ name = "serde_json" version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2223,7 +2185,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2372,7 +2334,7 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2528,7 +2490,7 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2556,7 +2518,7 @@ dependencies = [ "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2572,7 +2534,7 @@ name = "tonic" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "async-stream 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2582,10 +2544,10 @@ dependencies = [ "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "prost-derive 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tower-balance 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2632,10 +2594,10 @@ dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-load 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2651,8 +2613,8 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2664,7 +2626,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2679,8 +2641,8 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2692,8 +2654,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2704,7 +2666,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2714,7 +2676,7 @@ name = "tower-make" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2727,7 +2689,7 @@ dependencies = [ "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2737,8 +2699,8 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2753,8 +2715,8 @@ name = "tower-timeout" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2766,7 +2728,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2811,7 +2773,7 @@ name = "tracing-futures" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tracing 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2833,9 +2795,9 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2852,8 +2814,8 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2875,7 +2837,7 @@ name = "unicode-normalization" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3171,16 +3133,16 @@ dependencies = [ "checksum actix-web-codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de0878b30e62623770a4713a6338329fd0119703bafc211d3e4144f4d4a7bdd5" "checksum actix_derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c" "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" -"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5f56c476256dc249def911d6f7580b5fc7e875895b5d7ee88f5d602208035744" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" "checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" -"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" +"checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" "checksum ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" -"checksum async-stream 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58982858be7540a465c790b95aaea6710e5139bf8956b1d1344d014fa40100b0" -"checksum async-stream-impl 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393356ed99aa7bff0ac486dde592633b83ab02bd254d8c209d5b9f1d0f533480" +"checksum async-stream 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5" +"checksum async-stream-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" "checksum async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c" "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" @@ -3204,7 +3166,6 @@ dependencies = [ "checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cmake 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" "checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" "checksum config 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" "checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" @@ -3261,8 +3222,6 @@ dependencies = [ "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -"checksum grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9ac757a85603e4f8c40a9f94be06a5ad412acab80b39b4e8895ca931b6619910" -"checksum grpcio-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "7b2f22fb0327f153acccedbe91894dd0fb15bb6f202d8195665cd206af0402b0" "checksum h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" @@ -3279,7 +3238,7 @@ dependencies = [ "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f" "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" -"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" "checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" @@ -3325,11 +3284,10 @@ dependencies = [ "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" -"checksum pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "75fca1c4ff21f60ca2d37b80d72b63dab823a9d19d3cda3a81d18bc03f0ba8c5" -"checksum pin-project-internal 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6544cd4e4ecace61075a6ec78074beeef98d58aa9a3d07d053d993b2946a90d6" +"checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" +"checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" "checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" -"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum predicates 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a9bfe52247e5cc9b2f943682a85a5549fb9662245caf094504e69a2f03fe64d4" "checksum predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178" @@ -3396,7 +3354,7 @@ dependencies = [ "checksum slog-stdlog 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be4d87903baf655da2d82bc3ac3f7ef43868c58bf712b3a661fda72009304c23" "checksum slog-term 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54b50e85b73c2bd42ceb97b6ded235576d405bd1e974242ccfe634fa269f6da7" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" -"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" +"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" "checksum smart-default 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" @@ -3415,7 +3373,7 @@ dependencies = [ "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c1fc73332507b971a5010664991a441b5ee0de92017f5a0e8b00fd684573045b" +"checksum tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" "checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" "checksum tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08283643b1d483eb7f3fc77069e63b5cba3e4db93514b3d45470e67f123e4e48" diff --git a/Cargo.toml b/Cargo.toml index f1895a6f2..e522d9ce9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,8 +26,7 @@ members = [ lto = "thin" [features] -deadlock_detection = [] -default = ["deadlock_detection"] +deadlock_detection = ["parking_lot/deadlock_detection"] [dependencies] actix = "0.9" @@ -42,12 +41,11 @@ derive_more = "0.99" dotenv = "0.15" failure = "0.1" futures = { version = "0.3", features = ["compat"] } -grpcio = { version = "0.4", features = ["openssl"] } humantime-serde = "0.1" medea-client-api-proto = { path = "proto/client-api", features = ["medea"] } medea-control-api-proto = { path = "proto/control-api" } medea-macro = { path = "crates/medea-macro" } -protobuf = "2.7" +parking_lot = "0.10" rand = "0.7" redis = "0.14" rust-crypto = "0.2" @@ -64,7 +62,6 @@ tokio = { version = "0.2", features = ["signal", "time"] } tonic = "0.1" toml = "0.5" url = "2.1" -parking_lot = { version = "0.10", features = ["deadlock_detection"] } [dependencies.slog] version = "2.5" features = ["release_max_level_trace", "max_level_trace"] diff --git a/mock/control-api/src/api/endpoint.rs b/mock/control-api/src/api/endpoint.rs index 260658958..e5e2d0a59 100644 --- a/mock/control-api/src/api/endpoint.rs +++ b/mock/control-api/src/api/endpoint.rs @@ -26,6 +26,7 @@ impl Into for P2pMode { impl From for P2pMode { fn from(proto: proto::web_rtc_publish_endpoint::P2p) -> Self { use proto::web_rtc_publish_endpoint::P2p::*; + match proto { Always => Self::Always, IfPossible => Self::IfPossible, @@ -134,7 +135,7 @@ impl Endpoint { /// Converts [`Endpoint`] into protobuf [`proto::member::Element`]. #[must_use] pub fn into_proto(self, id: String) -> proto::member::Element { - let oneof = match self { + let el = match self { Self::WebRtcPlayEndpoint(spec) => { proto::member::element::El::WebrtcPlay(spec.into_proto(id)) } @@ -143,7 +144,7 @@ impl Endpoint { } }; - proto::member::Element { el: Some(oneof) } + proto::member::Element { el: Some(el) } } } diff --git a/mock/control-api/src/api/mod.rs b/mock/control-api/src/api/mod.rs index 990302919..ecdfc59f9 100644 --- a/mock/control-api/src/api/mod.rs +++ b/mock/control-api/src/api/mod.rs @@ -6,7 +6,7 @@ pub mod endpoint; pub mod member; pub mod room; -use std::collections::HashMap; +use std::{collections::HashMap, sync::Mutex}; use actix::Addr; use actix_cors::Cors; @@ -30,7 +30,6 @@ use self::{ member::Member, room::Room, }; -use std::sync::Mutex; /// Context of [`actix_web`] server. pub struct Context { diff --git a/mock/control-api/src/callback/server.rs b/mock/control-api/src/callback/server.rs index 5eb70441d..a1483651d 100644 --- a/mock/control-api/src/callback/server.rs +++ b/mock/control-api/src/callback/server.rs @@ -19,7 +19,7 @@ use crate::{callback::CallbackItem, prelude::*}; /// Type which used in [`GrpcCallbackServer`] for [`CallbackItem`] storing. type CallbackItems = Arc>>; -/// [`Actor`] wrapper for [`grpcio`] server. +/// [`Actor`] wrapper for [`tonic`] gRPC server. /// /// Also this [`Actor`] can return all received callbacks /// with [`GetCallbacks`] [`Message`]. @@ -30,8 +30,6 @@ pub struct GrpcCallbackServer { impl Actor for GrpcCallbackServer { type Context = Context; - - fn started(&mut self, _ctx: &mut Self::Context) {} } /// Implementation for [`CallbackService`] gRPC service. diff --git a/mock/control-api/src/client.rs b/mock/control-api/src/client.rs index 95e0757e5..f35d06e20 100644 --- a/mock/control-api/src/client.rs +++ b/mock/control-api/src/client.rs @@ -53,14 +53,15 @@ fn id_request(ids: Vec) -> proto::IdRequest { /// [Medea]: https://github.com/instrumentisto/medea /// [Control API]: https://tinyurl.com/yxsqplq7 pub struct ControlClient { + /// Address of the Medea's Control API. medea_addr: String, - /// [`grpcio`] gRPC client for Medea Control API. + /// [`tonic`] gRPC client for Medea Control API. grpc_client: Option>, } impl ControlClient { - /// Creates new client for Medea's Control API. + /// Creates a new client for Medea's Control API. /// /// __Note that call of this function doesn't checks availability of Control /// API gRPC server. Availability will be checked only on sending request to @@ -73,16 +74,20 @@ impl ControlClient { } } + /// Returns mutable reference to a [`ControlApiClient`]. + /// + /// If [`ControlClient::grpc_client`] is `None` then new + /// [`ControlApiClient`] will be created. async fn get_client(&mut self) -> &mut ControlApiClient { - let qq = &mut self.grpc_client; - if let Some(client) = qq { + let grpc_client = &mut self.grpc_client; + if let Some(client) = grpc_client { client } else { - let client = - new_grpcio_control_api_client(self.medea_addr.clone()).await; - *qq = Some(client); + let new_client = + new_control_api_client(self.medea_addr.clone()).await; + *grpc_client = Some(new_client); - qq.as_mut().unwrap() + grpc_client.as_mut().unwrap() } } @@ -94,6 +99,7 @@ impl ControlClient { element: Element, ) -> Result { use proto::create_request::El::*; + let el = match element { Element::Room(room) => Room(room.into_proto(id)), Element::Member(member) => Member(member.into_proto(id)), @@ -109,8 +115,6 @@ impl ControlClient { el: Some(el), }; - println!("\n\n\n\n\n{:?}\n\n\n\n\n\n", req); - self.get_client() .await .create(tonic::Request::new(req)) @@ -147,9 +151,7 @@ impl ControlClient { } } -/// Returns new [`grpcio`] gRPC client for Control API. -async fn new_grpcio_control_api_client( - addr: String, -) -> ControlApiClient { +/// Returns new [`tonic`] gRPC client for Control API. +async fn new_control_api_client(addr: String) -> ControlApiClient { ControlApiClient::connect(addr).await.unwrap() } diff --git a/mock/control-api/src/main.rs b/mock/control-api/src/main.rs index 2c7fc0aa9..3ce88ef21 100644 --- a/mock/control-api/src/main.rs +++ b/mock/control-api/src/main.rs @@ -57,7 +57,6 @@ async fn main() { let _log_guard = init_logger(); let callback_server = callback::server::run(&opts).await; - println!("Starting medea-control-api-mock."); api::run(&opts, callback_server).await; } diff --git a/proto/control-api/build.rs b/proto/control-api/build.rs index 2421b201e..72ed4548f 100644 --- a/proto/control-api/build.rs +++ b/proto/control-api/build.rs @@ -45,12 +45,6 @@ mod grpc { .build_client(true) .build_server(true) .compile(&grpc_spec_files, &[GRPC_DIR.to_string()])?; - // protoc_grpcio::compile_grpc_protos( - // &grpc_spec_files, - // &[GRPC_DIR], - // &GRPC_DIR, - // None, - // )?; break; } else { panic!("{}", e); @@ -100,7 +94,7 @@ mod grpc { .collect() } - /// Returns paths to files which will be generated by [`grpcio`] after + /// Returns paths to files which will be generated by [`tonic`] after /// compilation of Protobuf specs from [`GRPC_DIR`]. pub fn get_out_files(&self) -> Vec { self.0 diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index d154659bb..013b55379 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -18,7 +18,7 @@ use crate::api::control::callback::{ /// gRPC client for sending [`CallbackRequest`]s. pub struct GrpcCallbackClient { - /// [`grpcio`] gRPC client of Control API Callback service. + /// [`tonic`] gRPC client of Control API Callback service. client: Rc>>, } diff --git a/src/api/control/callback/clients/mod.rs b/src/api/control/callback/clients/mod.rs index db7eba1e1..d5d90cee3 100644 --- a/src/api/control/callback/clients/mod.rs +++ b/src/api/control/callback/clients/mod.rs @@ -16,11 +16,14 @@ use crate::{ /// Error of sending [`CallbackRequest`] by [`CallbackClient`]. #[derive(Debug, From)] pub enum CallbackClientError { - /// [`grpcio`] failed to send [`CallbackRequest`]. + /// [`tonic`] failed to send [`CallbackRequest`]. Tonic(tonic::Status), + /// [`MailboxError`] while sending [`CallbackRequest`] to a + /// [`CallbackClient`] [`Actor`]. Mailbox(actix::MailboxError), + /// Error while creating new [`CallbackClient`]. TonicTransport(tonic::transport::Error), } @@ -36,7 +39,7 @@ pub trait CallbackClient: Debug + Send + Sync { pub async fn build_client( url: &CallbackUrl, ) -> Result { - info!("Creating CallbackClient for url: {}", url); + info!("Creating CallbackClient for URL: {}", url); match &url { CallbackUrl::Grpc(grpc_url) => { Ok(grpc::GrpcCallbackClient::new(grpc_url).await?.start()) diff --git a/src/api/control/grpc/server.rs b/src/api/control/grpc/server.rs index 3d0437fb2..881321651 100644 --- a/src/api/control/grpc/server.rs +++ b/src/api/control/grpc/server.rs @@ -326,7 +326,7 @@ impl ControlApi for ControlApiService { } } -/// Actor wrapper for [`grpcio`] gRPC server which provides dynamic [Control +/// Actor wrapper for [`tonic`] gRPC server which provides dynamic [Control /// API]. /// /// [Control API]: https://tinyurl.com/yxsqplq7 @@ -353,7 +353,7 @@ impl Handler for GrpcServer { shutting down.", ); if let Some(grpc_shutdown) = self.0.take() { - grpc_shutdown.send(()).unwrap(); + grpc_shutdown.send(()).ok(); } } } diff --git a/src/main.rs b/src/main.rs index 2b6df9974..6762bf6b6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,43 @@ use medea::{ AppContext, }; +/// Runs [`parking_log`] deadlock detector. +/// +/// When feature `deadlock_detection` is enabled, deadlocks of +/// [`parking_lot::Mutex`], [`parking_lot::RwLock`], +/// [`parking_lot::ReentrantMutex`] will be printed into logs. +/// +/// This is _experimental_ feature and disable by default. +#[cfg(feature = "deadlock_detection")] +fn run_deadlock_detector() { + use std::{thread, time::Duration}; + + use parking_lot::deadlock; + + thread::spawn(move || loop { + thread::sleep(Duration::from_secs(10)); + let deadlocks = deadlock::check_deadlock(); + if deadlocks.is_empty() { + continue; + } + + deadlocks + .iter() + .enumerate() + .flat_map(|(i, threads)| { + threads.iter().map(move |thread| (i, thread)) + }) + .for_each(|(i, t)| { + println!( + "Deadlock #{}\nThread ID {:#?}\n{:#?}", + i, + t.thread_id(), + t.backtrace() + ) + }); + }); +} + fn main() -> Result<(), Error> { dotenv::dotenv().ok(); let config = Conf::parse()?; @@ -27,32 +64,10 @@ fn main() -> Result<(), Error> { let _scope_guard = slog_scope::set_global_logger(logger); slog_stdlog::init()?; - info!("{:?}", config); - #[cfg(feature = "deadlock_detection")] - { - // only for #[cfg] - use parking_lot::deadlock; - use std::{thread, time::Duration}; - - // Create a background thread which checks for deadlocks every 10s - thread::spawn(move || loop { - thread::sleep(Duration::from_secs(10)); - let deadlocks = deadlock::check_deadlock(); - if deadlocks.is_empty() { - continue; - } - - println!("{} deadlocks detected", deadlocks.len()); - for (i, threads) in deadlocks.iter().enumerate() { - println!("Deadlock #{}", i); - for t in threads { - println!("Thread Id {:#?}", t.thread_id()); - println!("{:#?}", t.backtrace()); - } - } - }); - } // only for #[cfg] + run_deadlock_detector(); + + info!("{:?}", config); let sys = System::new("medea"); Arbiter::spawn( diff --git a/tests/e2e/callbacks/mod.rs b/tests/e2e/callbacks/mod.rs index 4a76ea54c..5332e7fd2 100644 --- a/tests/e2e/callbacks/mod.rs +++ b/tests/e2e/callbacks/mod.rs @@ -40,7 +40,7 @@ impl Handler for GrpcCallbackServer { } } -/// [`grpcio`] server for receiving callbacks. +/// [`tonic`] server for receiving callbacks. #[derive(Clone)] pub struct CallbackServer { callbacks: CallbackItems, @@ -59,6 +59,7 @@ impl Callback for CallbackServer { request: tonic::Request, ) -> Result, Status> { self.callbacks.lock().unwrap().push(request.into_inner()); + Ok(tonic::Response::new(proto::Response {})) } } From cbb89246236d405b6baffd60faa2df405f16fd06 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Thu, 30 Jan 2020 15:53:28 +0300 Subject: [PATCH 015/224] Remove mock Client lazyness and add wait.port to Makefile --- Makefile | 16 ++++++++++ mock/control-api/src/api/mod.rs | 15 +++------ mock/control-api/src/client.rs | 55 +++++++++------------------------ 3 files changed, 34 insertions(+), 52 deletions(-) diff --git a/Makefile b/Makefile index 0a89fc86b..1368c4ba9 100644 --- a/Makefile +++ b/Makefile @@ -147,6 +147,7 @@ down.medea: docker.down.medea # make up.control up.control: + make wait.port port=6565 cargo run -p medea-control-api-mock @@ -884,6 +885,21 @@ endef +########### +# Helpers # +########### + +# Wait for an open port. +# +# Usage: +# make wait.port [port=] + +wait.port: + while ! timeout 1 bash -c "echo > /dev/tcp/localhost/$(port)"; do sleep 1; done + + + + ################## # .PHONY section # ################## diff --git a/mock/control-api/src/api/mod.rs b/mock/control-api/src/api/mod.rs index ecdfc59f9..75c711920 100644 --- a/mock/control-api/src/api/mod.rs +++ b/mock/control-api/src/api/mod.rs @@ -6,7 +6,7 @@ pub mod endpoint; pub mod member; pub mod room; -use std::{collections::HashMap, sync::Mutex}; +use std::collections::HashMap; use actix::Addr; use actix_cors::Cors; @@ -37,7 +37,7 @@ pub struct Context { /// /// [Control API]: https://tinyurl.com/yxsqplq7 /// [Medea]: https://github.com/instrumentisto/medea - client: Mutex, + client: ControlClient, /// gRPC server which receives Control API callbacks. callback_server: Addr, @@ -51,12 +51,13 @@ pub async fn run( callback_server_addr: Addr, ) { let medea_addr: String = args.value_of("medea_addr").unwrap().to_string(); + let client = ControlClient::new(medea_addr).await.unwrap(); HttpServer::new(move || { debug!("Running HTTP server..."); App::new() .wrap(Cors::new().finish()) .data(Context { - client: Mutex::new(ControlClient::new(medea_addr.clone())), + client: client.clone(), callback_server: callback_server_addr.clone(), }) .wrap(middleware::Logger::default()) @@ -111,8 +112,6 @@ macro_rules! gen_request_macro { ) -> Result { state .client - .lock() - .unwrap() .$call_fn(path.into_inner().into()) .await .map_err(|e| error!("{:?}", e)) @@ -177,8 +176,6 @@ mod create { ) -> Result { state .client - .lock() - .unwrap() .create(path.into_inner(), Fid::from(()), data.0) .await .map_err(|e| error!("{:?}", e)) @@ -193,8 +190,6 @@ mod create { let uri = path.into_inner(); state .client - .lock() - .unwrap() .create(uri.1, Fid::from(uri.0), data.0) .await .map_err(|e| error!("{:?}", e)) @@ -209,8 +204,6 @@ mod create { let uri = path.into_inner(); state .client - .lock() - .unwrap() .create(uri.2, Fid::from((uri.0, uri.1)), data.0) .await .map_err(|e| error!("{:?}", e)) diff --git a/mock/control-api/src/client.rs b/mock/control-api/src/client.rs index f35d06e20..7c874022c 100644 --- a/mock/control-api/src/client.rs +++ b/mock/control-api/src/client.rs @@ -52,12 +52,10 @@ fn id_request(ids: Vec) -> proto::IdRequest { /// /// [Medea]: https://github.com/instrumentisto/medea /// [Control API]: https://tinyurl.com/yxsqplq7 +#[derive(Clone)] pub struct ControlClient { - /// Address of the Medea's Control API. - medea_addr: String, - /// [`tonic`] gRPC client for Medea Control API. - grpc_client: Option>, + grpc_client: ControlApiClient, } impl ControlClient { @@ -67,33 +65,22 @@ impl ControlClient { /// API gRPC server. Availability will be checked only on sending request to /// gRPC server.__ #[must_use] - pub fn new(medea_addr: String) -> Self { - Self { - medea_addr, - grpc_client: None, - } + pub async fn new( + medea_addr: String, + ) -> Result { + let client = ControlApiClient::connect(medea_addr).await?; + Ok(Self { + grpc_client: client, + }) } - /// Returns mutable reference to a [`ControlApiClient`]. - /// - /// If [`ControlClient::grpc_client`] is `None` then new - /// [`ControlApiClient`] will be created. - async fn get_client(&mut self) -> &mut ControlApiClient { - let grpc_client = &mut self.grpc_client; - if let Some(client) = grpc_client { - client - } else { - let new_client = - new_control_api_client(self.medea_addr.clone()).await; - *grpc_client = Some(new_client); - - grpc_client.as_mut().unwrap() - } + fn get_client(&self) -> ControlApiClient { + self.grpc_client.clone() } /// Creates provided element with gRPC Control API. pub async fn create( - &mut self, + &self, id: String, fid: Fid, element: Element, @@ -116,42 +103,28 @@ impl ControlClient { }; self.get_client() - .await .create(tonic::Request::new(req)) .await .map(tonic::Response::into_inner) } /// Gets element from Control API by FID. - pub async fn get( - &mut self, - fid: Fid, - ) -> Result { + pub async fn get(&self, fid: Fid) -> Result { let req = id_request(vec![fid.into()]); self.get_client() - .await .get(tonic::Request::new(req)) .await .map(tonic::Response::into_inner) } /// Deletes element from Control API by FID. - pub async fn delete( - &mut self, - fid: Fid, - ) -> Result { + pub async fn delete(&self, fid: Fid) -> Result { let req = id_request(vec![fid.into()]); self.get_client() - .await .delete(tonic::Request::new(req)) .await .map(tonic::Response::into_inner) } } - -/// Returns new [`tonic`] gRPC client for Control API. -async fn new_control_api_client(addr: String) -> ControlApiClient { - ControlApiClient::connect(addr).await.unwrap() -} From 3ddef2e4c836eab3b59a6678d87f180404fab36c Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Thu, 30 Jan 2020 16:04:05 +0300 Subject: [PATCH 016/224] Remove RefCell from gRPC callback sender [run ci] --- mock/control-api/src/client.rs | 1 - src/api/control/callback/clients/grpc.rs | 14 +++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/mock/control-api/src/client.rs b/mock/control-api/src/client.rs index 7c874022c..3045b8a45 100644 --- a/mock/control-api/src/client.rs +++ b/mock/control-api/src/client.rs @@ -64,7 +64,6 @@ impl ControlClient { /// __Note that call of this function doesn't checks availability of Control /// API gRPC server. Availability will be checked only on sending request to /// gRPC server.__ - #[must_use] pub async fn new( medea_addr: String, ) -> Result { diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index 013b55379..277a7b31b 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -1,6 +1,6 @@ //! Implementation of gRPC client for sending [`CallbackRequest`]s. -use std::{cell::RefCell, fmt, rc::Rc}; +use std::fmt; use futures::future::LocalBoxFuture; #[rustfmt::skip] @@ -19,7 +19,7 @@ use crate::api::control::callback::{ /// gRPC client for sending [`CallbackRequest`]s. pub struct GrpcCallbackClient { /// [`tonic`] gRPC client of Control API Callback service. - client: Rc>>, + client: ProtoCallbackClient, } pub type ActFuture = @@ -47,13 +47,10 @@ impl Handler for GrpcCallbackClient { msg: CallbackRequest, _: &mut Self::Context, ) -> Self::Result { - let client = Rc::clone(&self.client); + let mut client = self.client.clone(); Box::new( async move { - client - .borrow_mut() - .on_event(tonic::Request::new(msg.into())) - .await?; + client.on_event(tonic::Request::new(msg.into())).await?; Ok(()) } @@ -79,8 +76,7 @@ impl GrpcCallbackClient { addr: &GrpcCallbackUrl, ) -> Result { let addr = addr.addr(); - let client = - Rc::new(RefCell::new(ProtoCallbackClient::connect(addr).await?)); + let client = ProtoCallbackClient::connect(addr).await?; Ok(Self { client }) } From a349d43767fd16db2db5f8aa24192fad2854c31c Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Thu, 30 Jan 2020 16:37:54 +0300 Subject: [PATCH 017/224] Add wait.port to .PHONY --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 1368c4ba9..c4d9a0a3d 100644 --- a/Makefile +++ b/Makefile @@ -920,4 +920,5 @@ wait.port: release release.crates release.helm release.npm \ test test.e2e test.unit \ up up.control up.coturn up.demo up.dev up.jason up.medea \ + wait.port \ yarn From c76408bbe1aec3f87dbe4c9760ebb7362b86c3ce Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Thu, 30 Jan 2020 16:48:05 +0300 Subject: [PATCH 018/224] Remove mutable reference in Room Protobuf convertation --- mock/control-api/src/client.rs | 1 + src/signalling/room.rs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mock/control-api/src/client.rs b/mock/control-api/src/client.rs index 3045b8a45..e6e3d9f23 100644 --- a/mock/control-api/src/client.rs +++ b/mock/control-api/src/client.rs @@ -73,6 +73,7 @@ impl ControlClient { }) } + /// Returns [`ControlApiClient`] of this [`ControlClient`]. fn get_client(&self) -> ControlApiClient { self.grpc_client.clone() } diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 07a492738..7044b4a3f 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -925,7 +925,7 @@ impl Actor for Room { } } -impl Into for &mut Room { +impl Into for &Room { fn into(self) -> proto::Room { let pipeline = self .members @@ -940,7 +940,7 @@ impl Into for &mut Room { } } -impl Into for &mut Room { +impl Into for &Room { fn into(self) -> proto::Element { proto::Element { el: Some(proto::element::El::Room(self.into())), @@ -973,7 +973,7 @@ impl Handler for Room { match &fid { StatefulFid::Room(room_fid) => { if room_fid.room_id() == &self.id { - let current_room: proto::Element = self.into(); + let current_room: proto::Element = (&*self).into(); serialized.insert(fid, current_room); } else { return Err(RoomError::WrongRoomId( From 84924f20c80218be84417433f387463fed6bd1cb Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Fri, 31 Jan 2020 20:18:19 +0300 Subject: [PATCH 019/224] Add on_start on_stop --- _dev/specs/relay-pub-pub-video-call.yml | 4 ++++ proto/control-api/src/grpc/callback.proto | 6 +++++ proto/control-api/src/grpc/medea_callback.rs | 12 +++++++++- .../control/endpoints/webrtc_play_endpoint.rs | 23 ++++++++++++++++++- .../endpoints/webrtc/play_endpoint.rs | 9 ++++++++ src/signalling/elements/member.rs | 6 +++++ src/signalling/room.rs | 4 ++++ 7 files changed, 62 insertions(+), 2 deletions(-) diff --git a/_dev/specs/relay-pub-pub-video-call.yml b/_dev/specs/relay-pub-pub-video-call.yml index b4d8b33ee..3fc5ed579 100644 --- a/_dev/specs/relay-pub-pub-video-call.yml +++ b/_dev/specs/relay-pub-pub-video-call.yml @@ -19,6 +19,8 @@ spec: spec: src: "local://relay-pub-pub-video-call/responder/publish" force_relay: true + on_play: "grpc://127.0.0.1:9099" + on_stop: "grpc://127.0.0.1:9099" responder: kind: Member credentials: test @@ -36,3 +38,5 @@ spec: spec: src: "local://relay-pub-pub-video-call/caller/publish" force_relay: true + on_play: "grpc://127.0.0.1:9099" + on_stop: "grpc://127.0.0.1:9099" diff --git a/proto/control-api/src/grpc/callback.proto b/proto/control-api/src/grpc/callback.proto index 173013a70..5ee356908 100644 --- a/proto/control-api/src/grpc/callback.proto +++ b/proto/control-api/src/grpc/callback.proto @@ -21,9 +21,15 @@ message Request { oneof event { OnJoin on_join = 3; OnLeave on_leave = 4; + OnPlay on_play = 5; + OnStop on_stop = 6; } } +message OnPlay {} + +message OnStop {} + // Empty response of the Callback service. // // We don't use 'google.protobuf.Empty' to be able to add diff --git a/proto/control-api/src/grpc/medea_callback.rs b/proto/control-api/src/grpc/medea_callback.rs index 0790cf18e..752a45c35 100644 --- a/proto/control-api/src/grpc/medea_callback.rs +++ b/proto/control-api/src/grpc/medea_callback.rs @@ -8,7 +8,7 @@ pub struct Request { #[prost(string, tag="2")] pub at: std::string::String, /// Occurred callback event. - #[prost(oneof="request::Event", tags="3, 4")] + #[prost(oneof="request::Event", tags="3, 4, 5, 6")] pub event: ::std::option::Option, } pub mod request { @@ -19,8 +19,18 @@ pub mod request { OnJoin(super::OnJoin), #[prost(message, tag="4")] OnLeave(super::OnLeave), + #[prost(message, tag="5")] + OnPlay(super::OnPlay), + #[prost(message, tag="6")] + OnStop(super::OnStop), } } +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct OnPlay { +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct OnStop { +} /// Empty response of the Callback service. /// /// We don't use 'google.protobuf.Empty' to be able to add diff --git a/src/api/control/endpoints/webrtc_play_endpoint.rs b/src/api/control/endpoints/webrtc_play_endpoint.rs index a8035a789..10e80430f 100644 --- a/src/api/control/endpoints/webrtc_play_endpoint.rs +++ b/src/api/control/endpoints/webrtc_play_endpoint.rs @@ -8,7 +8,9 @@ use derive_more::{Display, From, Into}; use medea_control_api_proto::grpc::medea as proto; use serde::Deserialize; -use crate::api::control::{refs::SrcUri, TryFromProtobufError}; +use crate::api::control::{ + callback::url::CallbackUrl, refs::SrcUri, TryFromProtobufError, +}; /// ID of [`WebRtcPlayEndpoint`]. #[derive( @@ -22,6 +24,10 @@ pub struct WebRtcPlayEndpoint { /// Source URI in format `local://{room_id}/{member_id}/{endpoint_id}`. pub src: SrcUri, + pub on_start: Option, + + pub on_stop: Option, + /// Option to relay all media through a TURN server forcibly. #[serde(default)] pub force_relay: bool, @@ -33,9 +39,24 @@ impl TryFrom<&proto::WebRtcPlayEndpoint> for WebRtcPlayEndpoint { fn try_from( value: &proto::WebRtcPlayEndpoint, ) -> Result { + let on_start = Some(value.on_start.clone()) + .filter(String::is_empty) + .map(CallbackUrl::try_from) + .transpose()?; + let on_stop = Some(value.on_stop.clone()) + .filter(String::is_empty) + .map(CallbackUrl::try_from) + .transpose()?; + + if (on_start.is_some() | on_stop.is_some()) && !value.force_relay { + return Err(TryFromProtobufError::) + } + Ok(Self { src: SrcUri::try_from(value.src.clone())?, force_relay: value.force_relay, + on_stop, + on_start, }) } } diff --git a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs index e80253108..db48f0341 100644 --- a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs @@ -19,6 +19,7 @@ use crate::{ }; use super::publish_endpoint::WebRtcPublishEndpoint; +use crate::api::control::callback::url::CallbackUrl; #[derive(Debug, Clone)] struct WebRtcPlayEndpointInner { @@ -48,6 +49,10 @@ struct WebRtcPlayEndpointInner { /// Indicator whether only `relay` ICE candidates are allowed for this /// [`WebRtcPlayEndpoint`]. is_force_relayed: bool, + + on_start: Option, + + on_stop: Option, } impl WebRtcPlayEndpointInner { @@ -102,6 +107,8 @@ impl WebRtcPlayEndpoint { publisher: WeakWebRtcPublishEndpoint, owner: WeakMember, is_force_relayed: bool, + on_start: Option, + on_stop: Option, ) -> Self { Self(Rc::new(RefCell::new(WebRtcPlayEndpointInner { id, @@ -110,6 +117,8 @@ impl WebRtcPlayEndpoint { owner, peer_id: None, is_force_relayed, + on_start, + on_stop, }))) } diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index 6afb73281..c81ceb763 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -190,6 +190,8 @@ impl Member { publisher.downgrade(), this_member.downgrade(), spec_play_endpoint.force_relay, + spec_play_endpoint.on_start.clone(), + spec_play_endpoint.on_stop.clone(), ); self.insert_sink(new_play_endpoint.clone()); @@ -210,6 +212,8 @@ impl Member { new_publish.downgrade(), this_member.downgrade(), spec_play_endpoint.force_relay, + spec_play_endpoint.on_start.clone(), + spec_play_endpoint.on_stop.clone(), ); new_publish.add_sink(new_self_play.downgrade()); @@ -378,6 +382,8 @@ impl Member { src.downgrade(), member.downgrade(), spec.force_relay, + spec.on_start, + spec.on_stop, ); src.add_sink(sink.downgrade()); diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 7044b4a3f..86d131274 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -628,6 +628,8 @@ impl Room { src.downgrade(), member.downgrade(), spec.force_relay, + spec.on_start, + spec.on_stop, ); src.add_sink(sink.downgrade()); @@ -703,6 +705,8 @@ impl Room { src.downgrade(), signalling_member.downgrade(), play.force_relay, + play.on_start.clone(), + play.on_stop.clone(), ); signalling_member.insert_sink(sink); From e6ac8bb03a8d788fb754ecddfed6c8f2b09ac6ff Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 3 Feb 2020 14:35:25 +0300 Subject: [PATCH 020/224] Normal 'on_start' and 'on_stop' validation --- .../control/endpoints/webrtc_play_endpoint.rs | 85 +++++++++++++++++-- src/api/control/error_codes.rs | 12 +++ src/api/control/mod.rs | 2 + 3 files changed, 94 insertions(+), 5 deletions(-) diff --git a/src/api/control/endpoints/webrtc_play_endpoint.rs b/src/api/control/endpoints/webrtc_play_endpoint.rs index 10e80430f..a1a274074 100644 --- a/src/api/control/endpoints/webrtc_play_endpoint.rs +++ b/src/api/control/endpoints/webrtc_play_endpoint.rs @@ -6,7 +6,7 @@ use std::convert::TryFrom; use derive_more::{Display, From, Into}; use medea_control_api_proto::grpc::medea as proto; -use serde::Deserialize; +use serde::{de::Deserializer, Deserialize}; use crate::api::control::{ callback::url::CallbackUrl, refs::SrcUri, TryFromProtobufError, @@ -19,7 +19,7 @@ use crate::api::control::{ pub struct WebRtcPlayId(String); /// Media element which is able to play media data for client via WebRTC. -#[derive(Clone, Deserialize, Debug)] +#[derive(Clone, Debug)] pub struct WebRtcPlayEndpoint { /// Source URI in format `local://{room_id}/{member_id}/{endpoint_id}`. pub src: SrcUri, @@ -29,7 +29,6 @@ pub struct WebRtcPlayEndpoint { pub on_stop: Option, /// Option to relay all media through a TURN server forcibly. - #[serde(default)] pub force_relay: bool, } @@ -48,8 +47,10 @@ impl TryFrom<&proto::WebRtcPlayEndpoint> for WebRtcPlayEndpoint { .map(CallbackUrl::try_from) .transpose()?; - if (on_start.is_some() | on_stop.is_some()) && !value.force_relay { - return Err(TryFromProtobufError::) + if !value.force_relay && (on_start.is_some() || on_stop.is_some()) { + return Err( + TryFromProtobufError::CallbackNotSupportedInNotRelayMode, + ); } Ok(Self { @@ -60,3 +61,77 @@ impl TryFrom<&proto::WebRtcPlayEndpoint> for WebRtcPlayEndpoint { }) } } + +impl<'de> Deserialize<'de> for WebRtcPlayEndpoint { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + use serde::de::Error as _; + + let ev = serde_json::Value::deserialize(deserializer)?; + let map = ev.as_object().ok_or_else(|| { + D::Error::custom(format!( + "unable to deserialize ClientMsg [{:?}]", + &ev + )) + })?; + + let src = map + .get("src") + .ok_or_else(|| D::Error::custom(format!("missing field `src`")))?; + let src = SrcUri::deserialize(src).map_err(|e| { + D::Error::custom(format!( + "error while deserialization of `src` field: {:?}", + e + )) + })?; + let force_relay = map + .get("force_relay") + .and_then(|force_relay| force_relay.as_bool()) + .unwrap_or_default(); + + let on_start = if let Some(on_start) = map.get("on_start") { + if !force_relay { + return Err(D::Error::custom(format!( + "`on_start` callback not supported while `force_relay` != \ + `true`" + ))); + } else { + Some(CallbackUrl::deserialize(on_start).map_err(|e| { + D::Error::custom(format!( + "error while deserialization of `on_start` field: {:?}", + e + )) + })?) + } + } else { + None + }; + + let on_stop = if let Some(on_stop) = map.get("on_stop") { + if !force_relay { + return Err(D::Error::custom(format!( + "`on_stop` callback not supported while `force_relay` != \ + `true`" + ))); + } else { + Some(CallbackUrl::deserialize(on_stop).map_err(|e| { + D::Error::custom(format!( + "error while deserialization of `on_stop` field: {:?}", + e + )) + })?) + } + } else { + None + }; + + Ok(Self { + src, + force_relay, + on_start, + on_stop, + }) + } +} diff --git a/src/api/control/error_codes.rs b/src/api/control/error_codes.rs index e7ee7e841..00c1183b4 100644 --- a/src/api/control/error_codes.rs +++ b/src/api/control/error_codes.rs @@ -279,6 +279,15 @@ pub enum ErrorCode { #[display(fmt = "Invalid callback URL.")] InvalidCallbackUrl = 1022, + /// `on_start` and `on_stop` callbacks of `WebRtcPlayEndpoint` + /// not supported while `relay_mode` is not `true`. + /// + /// Code: __1033__. + #[display(fmt = "'on_start' and 'on_stop' callbacks of \ + 'WebRtcPlayEndpoint' not supported while 'relay_mode' \ + is not 'true'.")] + CallbackNotSupportedInNotRelayMode = 1023, + /// Unexpected server error. /// /// Use this [`ErrorCode`] only with [`ErrorResponse::unexpected`] @@ -338,6 +347,9 @@ impl From for ErrorResponse { String::from("No element was provided"), Some(id), ), + CallbackNotSupportedInNotRelayMode => { + Self::without_id(ErrorCode::CallbackNotSupportedInNotRelayMode) + } } } } diff --git a/src/api/control/mod.rs b/src/api/control/mod.rs index fdecc1736..3403f9c0f 100644 --- a/src/api/control/mod.rs +++ b/src/api/control/mod.rs @@ -73,6 +73,8 @@ pub enum TryFromProtobufError { #[display(fmt = "Error while parsing callback URL. {:?}", _0)] CallbackUrlParseErr(CallbackUrlParseError), + + CallbackNotSupportedInNotRelayMode, } impl From for TryFromProtobufError { From da8e50ce034dfc0d2bfca95df907c4f5d91c8085 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Mon, 3 Feb 2020 13:36:25 +0200 Subject: [PATCH 021/224] refactor, add todo --- Cargo.lock | 160 ++++++++++------------- Cargo.toml | 4 - src/api/control/callback/clients/grpc.rs | 68 ++++------ src/api/control/callback/clients/mod.rs | 14 +- src/api/control/callback/service.rs | 36 +++-- src/api/control/grpc/server.rs | 3 +- src/main.rs | 40 ------ src/signalling/room_repo.rs | 14 +- tests/e2e/callbacks/member.rs | 12 +- tests/e2e/callbacks/mod.rs | 3 +- tests/e2e/grpc_control_api/create.rs | 15 +-- tests/e2e/grpc_control_api/mod.rs | 32 ++--- 12 files changed, 159 insertions(+), 242 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3ce1222c..88870d8b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,7 +6,7 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -113,9 +113,9 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -139,7 +139,7 @@ dependencies = [ "bytestring 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -269,9 +269,9 @@ dependencies = [ "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -432,13 +432,13 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace" -version = "0.3.42" +version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", @@ -597,7 +597,7 @@ dependencies = [ "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde-hjson 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -647,6 +647,14 @@ dependencies = [ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-channel" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-channel" version = "0.4.0" @@ -686,6 +694,15 @@ dependencies = [ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-utils" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-utils" version = "0.7.0" @@ -786,7 +803,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -833,7 +850,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -848,7 +865,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "dtoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -880,7 +897,7 @@ name = "failure" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -895,11 +912,6 @@ dependencies = [ "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "fixedbitset" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "fixedbitset" version = "0.2.0" @@ -1150,7 +1162,7 @@ dependencies = [ [[package]] name = "hyper" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1353,17 +1365,16 @@ dependencies = [ "medea-control-api-proto 0.1.0-dev", "medea-macro 0.2.0-dev", "mockall 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-async 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-envlogger 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1383,7 +1394,7 @@ dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "medea-macro 0.2.0-dev", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1401,11 +1412,11 @@ dependencies = [ "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-async 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-envlogger 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-stdlog 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-term 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-term 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1433,7 +1444,7 @@ dependencies = [ "mockall 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "tracerr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1652,11 +1663,6 @@ dependencies = [ "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "ordermap" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "parking_lot" version = "0.9.0" @@ -1695,14 +1701,11 @@ name = "parking_lot_core" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1716,15 +1719,6 @@ name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "petgraph" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "petgraph" version = "0.5.0" @@ -1776,7 +1770,7 @@ dependencies = [ "float-cmp 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "normalize-line-endings 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1992,7 +1986,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2021,18 +2015,18 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.3" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2147,7 +2141,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2163,7 +2157,7 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2184,7 +2178,7 @@ name = "serde_urlencoded" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2195,7 +2189,7 @@ name = "serde_yaml" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2247,12 +2241,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "slog-async" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2261,12 +2256,12 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-async 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-stdlog 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-term 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-term 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2276,7 +2271,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2314,14 +2309,14 @@ dependencies = [ [[package]] name = "slog-term" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2444,24 +2439,6 @@ dependencies = [ "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "thread-id" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "thread_local" version = "1.0.1" @@ -2542,7 +2519,7 @@ dependencies = [ "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prost 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2914,7 +2891,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3148,7 +3125,7 @@ dependencies = [ "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7601d4d1d7ef2335d6597a41b5fe069f6ab799b85f53565ab390e7b7065aac5" -"checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b" +"checksum backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" @@ -3174,10 +3151,12 @@ dependencies = [ "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" "checksum crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" +"checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" "checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" "checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" "checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" "checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" +"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" "checksum darling 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" "checksum darling_core 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" @@ -3194,13 +3173,12 @@ dependencies = [ "checksum dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d0a1279c96732bc6800ce6337b6a614697b0e74ae058dc03c62ebeb78b4d86" "checksum dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" "checksum downcast 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d" -"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" +"checksum dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28" "checksum enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "900a6c7fbe523f4c2884eaf26b57b81bb69b6810a01a236390a7ac021d09492e" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" -"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" "checksum flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd6d6f4752952feb71363cffc9ebac9411b75b87c6ab6058c40c8900cf43c0f" "checksum float-cmp 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75224bec9bfe1a65e2d34132933f2de7fe79900c96a0174307554244ece8150e" @@ -3231,7 +3209,7 @@ dependencies = [ "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" "checksum humantime-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8f59e8a805c18bc9ded3f4e596cb5f0157d88a235e875480a7593b5926f95065" -"checksum hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf49cfb32edee45d890537d9057d1b02ed55f53b7b6a30bae83a38c9231749e" +"checksum hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fa1c527bbc634be72aa7ba31e4e4def9bbb020f5416916279b7c705cd838893e" "checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" "checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" @@ -3275,14 +3253,12 @@ dependencies = [ "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" "checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" -"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" "checksum parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" "checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum petgraph 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" "checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" "checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" @@ -3317,8 +3293,8 @@ dependencies = [ "checksum redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d69c054daeca01bc1bee4af75b04dffa3458d6702cb7a74c2f38518c130fb624" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" -"checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87" -"checksum regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e734e891f5b408a29efbf8309e656876276f49ab6a6ac208600b4419bd893d90" +"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb" "checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" @@ -3336,7 +3312,7 @@ dependencies = [ "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde-hjson 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "eab8f15f15d6c41a154c1b128a22f2dfabe350ef53c40953d84e36155c91192b" +"checksum serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)" = "21b01d7f0288608a01dca632cf1df859df6fd6ffa885300fc275ce2ba6221953" "checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" "checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" @@ -3346,13 +3322,13 @@ dependencies = [ "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99" -"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" +"checksum slog-async 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78ca925b180da88ccc595cbe4a3d378d79cb49fe5906c2cbc2488eaf700913ee" "checksum slog-envlogger 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "906a1a0bc43fed692df4b82a5e2fbfc3733db8dad8bb514ab27a4f23ad04f5c0" "checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" "checksum slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c44c89dd8b0ae4537d1ae318353eaf7840b4869c536e31c41e963d1ea523ee6" "checksum slog-stdlog 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f1c469573d1e3f36f9eee66cd132206caf47b50c94b1f6c6e7b4d8235e9ecf01" "checksum slog-stdlog 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be4d87903baf655da2d82bc3ac3f7ef43868c58bf712b3a661fda72009304c23" -"checksum slog-term 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54b50e85b73c2bd42ceb97b6ded235576d405bd1e974242ccfe634fa269f6da7" +"checksum slog-term 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "124501187c410b6a46fe8a47a48435ae462fae4e02d03c558d358f40b17308cb" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" "checksum smart-default 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" @@ -3368,8 +3344,6 @@ dependencies = [ "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" diff --git a/Cargo.toml b/Cargo.toml index e522d9ce9..a62924835 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,9 +25,6 @@ members = [ [profile.release] lto = "thin" -[features] -deadlock_detection = ["parking_lot/deadlock_detection"] - [dependencies] actix = "0.9" actix-web = "2.0" @@ -45,7 +42,6 @@ humantime-serde = "0.1" medea-client-api-proto = { path = "proto/client-api", features = ["medea"] } medea-control-api-proto = { path = "proto/control-api" } medea-macro = { path = "crates/medea-macro" } -parking_lot = "0.10" rand = "0.7" redis = "0.14" rust-crypto = "0.2" diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index 277a7b31b..e94ab0e28 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -2,12 +2,11 @@ use std::fmt; -use futures::future::LocalBoxFuture; +use async_trait::async_trait; #[rustfmt::skip] use medea_control_api_proto::grpc::medea_callback::{ callback_client::CallbackClient as ProtoCallbackClient }; -use actix::{Actor, ActorFuture, Addr, Context, Handler, WrapFuture}; use tonic::transport::Channel; use crate::api::control::callback::{ @@ -22,40 +21,32 @@ pub struct GrpcCallbackClient { client: ProtoCallbackClient, } -pub type ActFuture = - Box>; +impl GrpcCallbackClient { + /// Returns gRPC client for provided [`GrpcCallbackUrl`]. + /// + /// Note that this function doesn't check availability of gRPC server on + /// provided [`GrpcCallbackUrl`]. + pub async fn new( + addr: &GrpcCallbackUrl, + ) -> Result { + let addr = addr.addr(); + let client = ProtoCallbackClient::connect(addr).await?; -impl Actor for GrpcCallbackClient { - type Context = Context; + Ok(Self { client }) + } } -impl CallbackClient for Addr { - fn send( +#[async_trait] +impl CallbackClient for GrpcCallbackClient { + async fn send( &self, request: CallbackRequest, - ) -> LocalBoxFuture<'static, Result<(), CallbackClientError>> { - let this = self.clone(); - Box::pin(async move { Ok(this.send(request).await??) }) - } -} - -impl Handler for GrpcCallbackClient { - type Result = ActFuture>; - - fn handle( - &mut self, - msg: CallbackRequest, - _: &mut Self::Context, - ) -> Self::Result { - let mut client = self.client.clone(); - Box::new( - async move { - client.on_event(tonic::Request::new(msg.into())).await?; - - Ok(()) - } - .into_actor(self), - ) + ) -> Result<(), CallbackClientError> { + self.client + .clone() + .on_event(tonic::Request::new(request.into())) + .await?; + Ok(()) } } @@ -66,18 +57,3 @@ impl fmt::Debug for GrpcCallbackClient { .finish() } } - -impl GrpcCallbackClient { - /// Returns gRPC client for provided [`GrpcCallbackUrl`]. - /// - /// Note that this function doesn't check availability of gRPC server on - /// provided [`GrpcCallbackUrl`]. - pub async fn new( - addr: &GrpcCallbackUrl, - ) -> Result { - let addr = addr.addr(); - let client = ProtoCallbackClient::connect(addr).await?; - - Ok(Self { client }) - } -} diff --git a/src/api/control/callback/clients/mod.rs b/src/api/control/callback/clients/mod.rs index d5d90cee3..33df42793 100644 --- a/src/api/control/callback/clients/mod.rs +++ b/src/api/control/callback/clients/mod.rs @@ -4,9 +4,8 @@ pub mod grpc; use std::fmt::Debug; -use actix::Actor; +use async_trait::async_trait; use derive_more::From; -use futures::future::LocalBoxFuture; use crate::{ api::control::callback::{url::CallbackUrl, CallbackRequest}, @@ -19,19 +18,16 @@ pub enum CallbackClientError { /// [`tonic`] failed to send [`CallbackRequest`]. Tonic(tonic::Status), - /// [`MailboxError`] while sending [`CallbackRequest`] to a - /// [`CallbackClient`] [`Actor`]. - Mailbox(actix::MailboxError), - /// Error while creating new [`CallbackClient`]. TonicTransport(tonic::transport::Error), } +#[async_trait] pub trait CallbackClient: Debug + Send + Sync { - fn send( + async fn send( &self, request: CallbackRequest, - ) -> LocalBoxFuture<'static, Result<(), CallbackClientError>>; + ) -> Result<(), CallbackClientError>; } /// Creates [`CallbackClient`] basing on provided [`CallbackUrl`]. @@ -42,7 +38,7 @@ pub async fn build_client( info!("Creating CallbackClient for URL: {}", url); match &url { CallbackUrl::Grpc(grpc_url) => { - Ok(grpc::GrpcCallbackClient::new(grpc_url).await?.start()) + grpc::GrpcCallbackClient::new(grpc_url).await } } } diff --git a/src/api/control/callback/service.rs b/src/api/control/callback/service.rs index ab3739b01..5c4e7529d 100644 --- a/src/api/control/callback/service.rs +++ b/src/api/control/callback/service.rs @@ -1,9 +1,12 @@ //! Service which stores and lazily creates [`CallbackRequest`] clients. -use std::{collections::hash_map::HashMap, fmt::Debug, sync::Arc}; +use std::{ + collections::hash_map::HashMap, + fmt::Debug, + sync::{Arc, RwLock}, +}; use actix::Arbiter; -use parking_lot::RwLock; use crate::{ api::control::{ @@ -19,13 +22,15 @@ use crate::{ use super::{clients::build_client, CallbackRequest}; +// TODO: wrap in actor + /// Service which stores and lazily creates [`CallbackRequest`] clients. #[derive(Clone, Debug, Default)] pub struct CallbackService( // TODO: Hashmap entries are not dropped anywhere. some kind of // [expiring map](https://github.com/jhalterman/expiringmap) // would fit here. - Arc>>>, + Arc>>>, ); impl CallbackService { @@ -39,17 +44,30 @@ impl CallbackService { request, callback_url ); - let read_lock = self.0.read(); - if let Some(client) = read_lock.get(&callback_url) { - client.send(request).await?; + // TODO: refactor this when there will be some trustworthy thread safe + // HashMap with atomic `compute if absent`. + let read_lock = self.0.read().unwrap(); + let client = if let Some(client) = read_lock.get(&callback_url) { + Arc::clone(client) } else { drop(read_lock); - let new_client = build_client(&callback_url).await?; - new_client.send(request).await?; - self.0.write().insert(callback_url, Box::new(new_client)); + // We are building client while holding write lock to avoid races, + // that can lead to creating multiple clients to same uri. + let mut write_lock = self.0.write().unwrap(); + if let Some(client) = write_lock.get(&callback_url) { + Arc::clone(client) + } else { + let new_client: Arc = + Arc::new(build_client(&callback_url).await?); + write_lock.insert(callback_url, Arc::clone(&new_client)); + + new_client + } }; + client.send(request).await?; + Ok(()) } diff --git a/src/api/control/grpc/server.rs b/src/api/control/grpc/server.rs index 881321651..07ab32262 100644 --- a/src/api/control/grpc/server.rs +++ b/src/api/control/grpc/server.rs @@ -8,6 +8,7 @@ use std::{ }; use actix::{Actor, Addr, Arbiter, Context, Handler, MailboxError}; +use async_trait::async_trait; use derive_more::{Display, From}; use failure::Fail; use futures::future::{self, BoxFuture, FutureExt as _, TryFutureExt as _}; @@ -274,7 +275,7 @@ impl ControlApiService { } } -#[tonic::async_trait] +#[async_trait] impl ControlApi for ControlApiService { async fn create( &self, diff --git a/src/main.rs b/src/main.rs index 6762bf6b6..007e366b4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,43 +15,6 @@ use medea::{ AppContext, }; -/// Runs [`parking_log`] deadlock detector. -/// -/// When feature `deadlock_detection` is enabled, deadlocks of -/// [`parking_lot::Mutex`], [`parking_lot::RwLock`], -/// [`parking_lot::ReentrantMutex`] will be printed into logs. -/// -/// This is _experimental_ feature and disable by default. -#[cfg(feature = "deadlock_detection")] -fn run_deadlock_detector() { - use std::{thread, time::Duration}; - - use parking_lot::deadlock; - - thread::spawn(move || loop { - thread::sleep(Duration::from_secs(10)); - let deadlocks = deadlock::check_deadlock(); - if deadlocks.is_empty() { - continue; - } - - deadlocks - .iter() - .enumerate() - .flat_map(|(i, threads)| { - threads.iter().map(move |thread| (i, thread)) - }) - .for_each(|(i, t)| { - println!( - "Deadlock #{}\nThread ID {:#?}\n{:#?}", - i, - t.thread_id(), - t.backtrace() - ) - }); - }); -} - fn main() -> Result<(), Error> { dotenv::dotenv().ok(); let config = Conf::parse()?; @@ -64,9 +27,6 @@ fn main() -> Result<(), Error> { let _scope_guard = slog_scope::set_global_logger(logger); slog_stdlog::init()?; - #[cfg(feature = "deadlock_detection")] - run_deadlock_detector(); - info!("{:?}", config); let sys = System::new("medea"); diff --git a/src/signalling/room_repo.rs b/src/signalling/room_repo.rs index a623ddfdd..01989094f 100644 --- a/src/signalling/room_repo.rs +++ b/src/signalling/room_repo.rs @@ -1,9 +1,11 @@ //! Repository that stores [`Room`]s addresses. -use std::{collections::HashMap, sync::Arc}; +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; use actix::Addr; -use parking_lot::Mutex; use crate::{api::control::RoomId, signalling::Room}; @@ -27,23 +29,23 @@ impl RoomRepository { /// Returns [`Room`] by its ID. pub fn get(&self, id: &RoomId) -> Option> { - let rooms = self.rooms.lock(); + let rooms = self.rooms.lock().unwrap(); rooms.get(id).cloned() } /// Removes [`Room`] from [`RoomRepository`] by [`RoomId`]. pub fn remove(&self, id: &RoomId) { - self.rooms.lock().remove(id); + self.rooms.lock().unwrap().remove(id); } /// Adds new [`Room`] into [`RoomRepository`]. pub fn add(&self, id: RoomId, room: Addr) { - self.rooms.lock().insert(id, room); + self.rooms.lock().unwrap().insert(id, room); } /// Checks existence of [`Room`] in [`RoomRepository`] by provided /// [`RoomId`]. pub fn contains_room_with_id(&self, id: &RoomId) -> bool { - self.rooms.lock().contains_key(id) + self.rooms.lock().unwrap().contains_key(id) } } diff --git a/tests/e2e/callbacks/member.rs b/tests/e2e/callbacks/member.rs index 920154e98..88c898457 100644 --- a/tests/e2e/callbacks/member.rs +++ b/tests/e2e/callbacks/member.rs @@ -4,8 +4,9 @@ use std::time::Duration; use actix::{clock::delay_for, Addr, Context}; use actix_http::ws::CloseCode; -use medea_client_api_proto::Event; +use medea_client_api_proto::Event as RpcEvent; use medea_control_api_proto::grpc::medea_callback as proto; +use proto::request::Event; use crate::{ callbacks::{GetCallbacks, GrpcCallbackServer}, @@ -51,7 +52,7 @@ async fn callback_test(name: &'static str, port: u16) -> CallbackTestItem { let create_response = control_client.create(member).await; let on_event = - move |_: &Event, _: &mut Context, _: Vec<&Event>| {}; + move |_: &RpcEvent, _: &mut Context, _: Vec<&RpcEvent>| {}; let deadline = Some(Duration::from_secs(5)); let client = TestMember::connect( create_response.get(name).unwrap(), @@ -81,8 +82,7 @@ async fn on_join() { let on_joins_count = callbacks .into_iter() .filter(|r| { - if let proto::request::Event::OnJoin(_) = r.event.as_ref().unwrap() - { + if let Some(Event::OnJoin(_)) = &r.event { true } else { false @@ -117,7 +117,7 @@ async fn on_leave_normally_disconnected() { let on_leaves_count = callbacks .into_iter() .filter_map(|req| { - if let Some(proto::request::Event::OnLeave(on_leave)) = req.event { + if let Some(Event::OnLeave(on_leave)) = req.event { Some(on_leave.reason) } else { None @@ -156,7 +156,7 @@ async fn on_leave_on_connection_loss() { let on_leaves_count = callbacks .into_iter() .filter_map(|req| { - if let Some(proto::request::Event::OnLeave(on_leave)) = req.event { + if let Some(Event::OnLeave(on_leave)) = req.event { Some(on_leave.reason) } else { None diff --git a/tests/e2e/callbacks/mod.rs b/tests/e2e/callbacks/mod.rs index 5332e7fd2..103b67a7d 100644 --- a/tests/e2e/callbacks/mod.rs +++ b/tests/e2e/callbacks/mod.rs @@ -5,6 +5,7 @@ mod member; use std::sync::{Arc, Mutex}; use actix::{Actor, Addr, Arbiter, Context, Handler, Message}; +use async_trait::async_trait; use medea_control_api_proto::grpc::medea_callback::{ self as proto, callback_server::{Callback, CallbackServer as TonicCallbackServer}, @@ -52,7 +53,7 @@ impl CallbackServer { } } -#[tonic::async_trait] +#[async_trait] impl Callback for CallbackServer { async fn on_event( &self, diff --git a/tests/e2e/grpc_control_api/create.rs b/tests/e2e/grpc_control_api/create.rs index 9d3e2bc15..688c66faf 100644 --- a/tests/e2e/grpc_control_api/create.rs +++ b/tests/e2e/grpc_control_api/create.rs @@ -8,6 +8,8 @@ use medea::api::control::error_codes::ErrorCode; use medea_control_api_proto::grpc::medea as proto; +use crate::grpc_control_api::{take_member, take_room, take_webrtc_pub}; + use super::{ create_room_req, ControlClient, MemberBuilder, RoomBuilder, WebRtcPlayEndpointBuilder, WebRtcPublishEndpointBuilder, @@ -31,8 +33,7 @@ mod room { &format!("ws://127.0.0.1:8080/ws/{}/responder/test", TEST_NAME) ); - let get_resp = client.get(TEST_NAME).await; - let mut room = get_resp.take_room(); + let mut room = take_room(client.get(TEST_NAME).await); let responder = room.pipeline.remove("responder").unwrap(); let responder = match responder.el.unwrap() { @@ -135,10 +136,8 @@ mod member { format!("ws://127.0.0.1:8080/ws/{}/test-member/qwerty", TEST_NAME) ); - let member = client - .get(&format!("{}/test-member", TEST_NAME)) - .await - .take_member(); + let member = client.get(&format!("{}/test-member", TEST_NAME)).await; + let member = take_member(member); assert_eq!(member.pipeline.len(), 1); assert_eq!(member.credentials.as_str(), "qwerty"); } @@ -231,8 +230,8 @@ mod endpoint { let endpoint = client .get(&format!("{}/responder/publish", TEST_NAME)) - .await - .take_webrtc_pub(); + .await; + let endpoint = take_webrtc_pub(endpoint); assert_eq!( endpoint.p2p, proto::web_rtc_publish_endpoint::P2p::Never as i32 diff --git a/tests/e2e/grpc_control_api/mod.rs b/tests/e2e/grpc_control_api/mod.rs index bc42e19e8..303425380 100644 --- a/tests/e2e/grpc_control_api/mod.rs +++ b/tests/e2e/grpc_control_api/mod.rs @@ -15,28 +15,24 @@ use medea_control_api_proto::grpc::medea::{ }; use tonic::transport::Channel; -pub struct TakeableElement(pub proto::Element); - macro_rules! gen_elem_take_fn { - ($name:tt -> $variant:tt($output:ty)) => { - pub fn $name(self) -> $output { - match self.0.el.unwrap() { - proto::element::El::$variant(elem) => elem, - _ => panic!("Not {} element!", stringify!($variant)), - } + ($name:tt -> $variant:tt($output:ty)) => { + pub fn $name(el: proto::Element) -> $output { + match el.el.unwrap() { + proto::element::El::$variant(elem) => elem, + _ => panic!("Not {} element!", stringify!($variant)), } - }; + } + }; } -impl TakeableElement { - gen_elem_take_fn!(take_room -> Room(proto::Room)); +gen_elem_take_fn!(take_room -> Room(proto::Room)); - gen_elem_take_fn!(take_member -> Member(proto::Member)); +gen_elem_take_fn!(take_member -> Member(proto::Member)); - gen_elem_take_fn!( +gen_elem_take_fn!( take_webrtc_pub -> WebrtcPub(proto::WebRtcPublishEndpoint) ); -} /// Client for [Medea]'s gRPC [Control API]. /// @@ -66,7 +62,7 @@ impl ControlClient { /// /// - if [`GetResponse`] has error /// - if connection with server failed - pub async fn get(&mut self, uri: &str) -> TakeableElement { + pub async fn get(&mut self, uri: &str) -> proto::Element { let room = vec![uri.to_string()]; let get_room_request = proto::IdRequest { fid: room }; @@ -74,8 +70,7 @@ impl ControlClient { if let Some(err) = resp.error { panic!("{:?}", err); } - - TakeableElement(resp.elements.remove(&uri.to_string()).unwrap()) + resp.elements.remove(&uri.to_string()).unwrap() } /// Tries to get some [`proto::Element`] by local URI. @@ -94,7 +89,6 @@ impl ControlClient { if let Some(e) = resp.error { return Err(e); } - Ok(resp.elements.remove(&uri.to_string()).unwrap()) } @@ -141,7 +135,7 @@ impl ControlClient { /// - if [`Response`] has error /// - if connection with server failed. pub async fn delete(&mut self, ids: &[&str]) -> Result<(), proto::Error> { - let delete_ids = ids.iter().map(|id| id.to_string()).collect(); + let delete_ids = ids.iter().map(|id| (*id).to_string()).collect(); let delete_req = proto::IdRequest { fid: delete_ids }; let resp = self.0.delete(delete_req).await.unwrap().into_inner(); From dec70ae8c81c61d7b6fe961e5313d6d238fdcc8c Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 4 Feb 2020 15:45:54 +0300 Subject: [PATCH 022/224] Mock CallbackFactory and CallbackClient, add tests for it, refactor --- src/api/control/callback/clients/grpc.rs | 18 +-- src/api/control/callback/clients/mod.rs | 54 ++++++--- src/api/control/callback/service.rs | 141 ++++++++++++++++++++--- src/api/mod.rs | 6 +- src/lib.rs | 7 +- src/signalling/room.rs | 6 +- src/utils/mod.rs | 31 +++++ 7 files changed, 211 insertions(+), 52 deletions(-) diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index e94ab0e28..5a113e6fc 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -2,11 +2,11 @@ use std::fmt; -use async_trait::async_trait; #[rustfmt::skip] use medea_control_api_proto::grpc::medea_callback::{ callback_client::CallbackClient as ProtoCallbackClient }; +use futures::future::LocalBoxFuture; use tonic::transport::Channel; use crate::api::control::callback::{ @@ -36,17 +36,17 @@ impl GrpcCallbackClient { } } -#[async_trait] impl CallbackClient for GrpcCallbackClient { - async fn send( + fn send( &self, request: CallbackRequest, - ) -> Result<(), CallbackClientError> { - self.client - .clone() - .on_event(tonic::Request::new(request.into())) - .await?; - Ok(()) + ) -> LocalBoxFuture<'static, Result<(), CallbackClientError>> { + let mut client = self.client.clone(); + + Box::pin(async move { + client.on_event(tonic::Request::new(request.into())).await?; + Ok(()) + }) } } diff --git a/src/api/control/callback/clients/mod.rs b/src/api/control/callback/clients/mod.rs index 33df42793..d2d733036 100644 --- a/src/api/control/callback/clients/mod.rs +++ b/src/api/control/callback/clients/mod.rs @@ -2,16 +2,18 @@ pub mod grpc; -use std::fmt::Debug; +use std::fmt; -use async_trait::async_trait; use derive_more::From; +use futures::future::LocalBoxFuture; use crate::{ api::control::callback::{url::CallbackUrl, CallbackRequest}, log::prelude::*, }; +type Result = std::result::Result; + /// Error of sending [`CallbackRequest`] by [`CallbackClient`]. #[derive(Debug, From)] pub enum CallbackClientError { @@ -22,23 +24,45 @@ pub enum CallbackClientError { TonicTransport(tonic::transport::Error), } -#[async_trait] -pub trait CallbackClient: Debug + Send + Sync { - async fn send( +#[cfg_attr(test, mockall::automock)] +pub trait CallbackClient: fmt::Debug + Send + Sync { + /// Sends provided [`CallbackRequest`]. + fn send( &self, request: CallbackRequest, - ) -> Result<(), CallbackClientError>; + ) -> LocalBoxFuture<'static, Result<()>>; +} + +#[cfg(test)] +impl_debug_by_struct_name!(MockCallbackClient); + +/// Factory for a [`CallbackClient`]s. +#[cfg_attr(test, mockall::automock)] +pub trait CallbackClientFactory { + /// Creates [`CallbackClient`] basing on provided [`CallbackUrl`]. + fn build( + url: CallbackUrl, + ) -> LocalBoxFuture<'static, Result>>; } -/// Creates [`CallbackClient`] basing on provided [`CallbackUrl`]. -#[inline] -pub async fn build_client( - url: &CallbackUrl, -) -> Result { - info!("Creating CallbackClient for URL: {}", url); - match &url { - CallbackUrl::Grpc(grpc_url) => { - grpc::GrpcCallbackClient::new(grpc_url).await +#[cfg(test)] +impl_debug_by_struct_name!(MockCallbackClientFactory); + +/// Implementation of the [`CallbackClientFactory`]. +#[derive(Clone, Debug, Default)] +pub struct CallbackClientFactoryImpl; + +impl CallbackClientFactory for CallbackClientFactoryImpl { + #[inline] + fn build( + url: CallbackUrl, + ) -> LocalBoxFuture<'static, Result>> { + info!("Creating CallbackClient for URL: {}", url); + match url { + CallbackUrl::Grpc(grpc_url) => Box::pin(async move { + Ok(Box::new(grpc::GrpcCallbackClient::new(&grpc_url).await?) + as Box) + }), } } } diff --git a/src/api/control/callback/service.rs b/src/api/control/callback/service.rs index 5c4e7529d..aac9720af 100644 --- a/src/api/control/callback/service.rs +++ b/src/api/control/callback/service.rs @@ -1,39 +1,45 @@ //! Service which stores and lazily creates [`CallbackRequest`] clients. use std::{ - collections::hash_map::HashMap, - fmt::Debug, - sync::{Arc, RwLock}, + collections::hash_map::HashMap, fmt::Debug, marker::PhantomData, sync::Arc, }; use actix::Arbiter; +use tokio::sync::RwLock; use crate::{ api::control::{ callback::{ - clients::{CallbackClient, CallbackClientError}, + clients::{ + CallbackClient, CallbackClientError, CallbackClientFactory, + }, url::CallbackUrl, - CallbackEvent, + CallbackEvent, CallbackRequest, }, refs::StatefulFid, }, log::prelude::*, }; -use super::{clients::build_client, CallbackRequest}; - -// TODO: wrap in actor +type CallbackClientArc = Arc>; /// Service which stores and lazily creates [`CallbackRequest`] clients. -#[derive(Clone, Debug, Default)] -pub struct CallbackService( +#[derive(Debug, Default)] +pub struct CallbackService( // TODO: Hashmap entries are not dropped anywhere. some kind of // [expiring map](https://github.com/jhalterman/expiringmap) // would fit here. - Arc>>>, + Arc>>, + PhantomData, ); -impl CallbackService { +impl Clone for CallbackService { + fn clone(&self) -> Self { + Self(self.0.clone(), self.1) + } +} + +impl CallbackService { async fn send_request( &self, request: CallbackRequest, @@ -44,9 +50,7 @@ impl CallbackService { request, callback_url ); - // TODO: refactor this when there will be some trustworthy thread safe - // HashMap with atomic `compute if absent`. - let read_lock = self.0.read().unwrap(); + let read_lock = self.0.read().await; let client = if let Some(client) = read_lock.get(&callback_url) { Arc::clone(client) } else { @@ -54,12 +58,12 @@ impl CallbackService { // We are building client while holding write lock to avoid races, // that can lead to creating multiple clients to same uri. - let mut write_lock = self.0.write().unwrap(); + let mut write_lock = self.0.write().await; if let Some(client) = write_lock.get(&callback_url) { Arc::clone(client) } else { - let new_client: Arc = - Arc::new(build_client(&callback_url).await?); + let new_client: CallbackClientArc = + Arc::new(B::build(callback_url.clone()).await?); write_lock.insert(callback_url, Arc::clone(&new_client)); new_client @@ -93,3 +97,104 @@ impl CallbackService { }) } } + +#[cfg(test)] +mod tests { + use std::{convert::TryFrom as _, time::Duration}; + + use futures::channel::oneshot; + use serial_test_derive::serial; + + use crate::api::control::callback::{ + clients::{MockCallbackClient, MockCallbackClientFactory}, + OnJoinEvent, + }; + + use super::*; + + /// Returns [`CallbackRequest`] to a `foo` element. + fn callback_request() -> CallbackRequest { + CallbackRequest::new( + StatefulFid::try_from("foo".to_string()).unwrap(), + CallbackEvent::OnJoin(OnJoinEvent), + ) + } + + /// Returns [`CallbackUrl`] to a `grpc://127.0.0.1:6565`. + fn callback_url() -> CallbackUrl { + CallbackUrl::try_from("grpc://127.0.0.1:6565".to_string()).unwrap() + } + + /// Tests that only 1 [`CallbackClient`] will be created on 10 calls of + /// [`CallbackService::send_request`]. + #[actix_rt::test] + #[serial] + async fn only_one_client_will_be_created() { + const SEND_COUNT: usize = 10; + + let mut client_mock = MockCallbackClient::new(); + client_mock + .expect_send() + .times(SEND_COUNT) + .returning(|_| Box::pin(async { Ok(()) })); + + let client_builder_ctx = MockCallbackClientFactory::build_context(); + client_builder_ctx.expect().times(1).return_once(move |_| { + Box::pin(async move { + Ok(Box::new(client_mock) as Box) + }) + }); + + let callback_service = + CallbackService::::default(); + for _ in 0..SEND_COUNT { + callback_service + .send_request(callback_request(), callback_url()) + .await + .unwrap(); + } + } + + /// Tests that two simultaneous calls of [`CallbackService::send_request`] + /// from two threads will create only one [`CallbackClient`]. + #[actix_rt::test] + #[serial] + async fn only_one_client_will_be_created_on_multithread() { + let mut client_mock = MockCallbackClient::new(); + client_mock + .expect_send() + .times(2) + .returning(|_| Box::pin(async { Ok(()) })); + + let client_builder_ctx = MockCallbackClientFactory::build_context(); + client_builder_ctx.expect().times(1).return_once(move |_| { + Box::pin(async move { + tokio::time::delay_for(Duration::from_millis(50)).await; + Ok(Box::new(client_mock) as Box) + }) + }); + + let callback_service = + CallbackService::::default(); + + let (wait_for_another_arbiter_tx, wait_for_another_arbiter_rx) = + oneshot::channel(); + let another_arbiter_callback_service = callback_service.clone(); + Arbiter::new().exec_fn(move || { + futures::executor::block_on(Box::pin(async move { + another_arbiter_callback_service + .send_request(callback_request(), callback_url()) + .await + .unwrap(); + wait_for_another_arbiter_tx.send(()).unwrap(); + })) + }); + + callback_service + .send_request(callback_request(), callback_url()) + .await + .unwrap(); + + wait_for_another_arbiter_rx.await.unwrap(); + } +} diff --git a/src/api/mod.rs b/src/api/mod.rs index 51d12daac..47759224f 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -44,8 +44,4 @@ pub trait RpcServer: Debug + Send { } #[cfg(test)] -impl Debug for MockRpcServer { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "MockRpcServer") - } -} +impl_debug_by_struct_name!(MockRpcServer); diff --git a/src/lib.rs b/src/lib.rs index e30354869..8919683d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,10 @@ pub mod turn; use std::sync::Arc; use crate::{ - api::control::callback::service::CallbackService, conf::Conf, + api::control::callback::{ + clients::CallbackClientFactoryImpl, service::CallbackService, + }, + conf::Conf, turn::TurnAuthService, }; @@ -35,7 +38,7 @@ pub struct AppContext { /// Service for sending [`CallbackEvent`]s. /// /// [`CallbackEvent`]: crate::api::control::callbacks::CallbackEvent - pub callbacks: CallbackService, + pub callbacks: CallbackService, } impl AppContext { diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 7044b4a3f..6bde9dcd5 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -25,8 +25,8 @@ use crate::{ }, control::{ callback::{ - service::CallbackService, OnJoinEvent, OnLeaveEvent, - OnLeaveReason, + clients::CallbackClientFactoryImpl, service::CallbackService, + OnJoinEvent, OnLeaveEvent, OnLeaveReason, }, endpoints::{ WebRtcPlayEndpoint as WebRtcPlayEndpointSpec, @@ -160,7 +160,7 @@ pub struct Room { /// Service for sending [`CallbackEvent`]s. /// /// [`CallbackEvent`]: crate::api::control::callbacks::CallbackEvent - callbacks: CallbackService, + callbacks: CallbackService, /// [`Member`]s and associated [`RpcConnection`]s of this [`Room`], handles /// [`RpcConnection`] authorization, establishment, message sending. diff --git a/src/utils/mod.rs b/src/utils/mod.rs index ac8d6988c..d1fa4bfb9 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -42,6 +42,37 @@ macro_rules! hashmap { }; } +/// Generates [`Debug`] implementation for a provided structure with name of +/// this structure. +/// +/// In debug print of this structure will be printed just name of the provided +/// structure. +/// +/// # Example +/// +/// ``` +/// struct Foo; +/// +/// impl_debug_by_struct_name!(Foo); +/// +/// assert_eq!(format!("{:?}", Foo), "Foo") +/// ``` +/// +/// [`Debug`]: std::fmt::Debug +#[macro_export] +macro_rules! impl_debug_by_struct_name { + ($mock:ty) => { + impl ::std::fmt::Debug for $mock { + fn fmt( + &self, + f: &mut ::std::fmt::Formatter<'_>, + ) -> ::std::result::Result<(), ::std::fmt::Error> { + f.debug_struct(stringify!($mock)).finish() + } + } + }; +} + // TODO: remove after https://github.com/actix/actix/pull/313 /// Specialized future for asynchronous message handling. Exists because /// [`actix::ResponseFuture`] implements [`actix::dev::MessageResponse`] only From e28c51e20875a0df12382fdfb44ed2d9f5aa6f0f Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 4 Feb 2020 17:13:24 +0300 Subject: [PATCH 023/224] Fix 'clippy::missing_errors_doc' lints [run ci] --- jason/src/peer/conn.rs | 20 ++++++++++++++++++++ jason/src/peer/media.rs | 17 +++++++++++++++-- jason/src/peer/mod.rs | 11 +++++++++++ jason/src/peer/repo.rs | 5 +++++ jason/src/peer/stream_request.rs | 16 ++++++++++++++++ jason/src/rpc/mod.rs | 5 +++++ jason/src/utils/event_listener.rs | 8 ++++++++ src/api/client/server.rs | 5 +++++ src/api/control/mod.rs | 16 ++++++++++++++++ src/api/control/room.rs | 5 +++++ src/conf/mod.rs | 4 ++++ src/media/peer.rs | 21 +++++++++++++++++++-- src/signalling/elements/member.rs | 12 ++++++++++++ src/signalling/participants.rs | 13 +++++++++++-- src/signalling/peers.rs | 15 +++++++++++++++ src/signalling/room.rs | 19 ++++++++++++++++++- src/signalling/room_service.rs | 5 +++++ src/turn/repo.rs | 4 ++++ src/turn/service.rs | 5 +++++ 19 files changed, 199 insertions(+), 7 deletions(-) diff --git a/jason/src/peer/conn.rs b/jason/src/peer/conn.rs index ce168e393..eca932f39 100644 --- a/jason/src/peer/conn.rs +++ b/jason/src/peer/conn.rs @@ -211,6 +211,11 @@ pub struct RtcPeerConnection { impl RtcPeerConnection { /// Instantiates new [`RtcPeerConnection`]. + /// + /// # Errors + /// + /// Will return [`RTCPeerConnectionError::PeerCreationError`] if + /// [`SysRtcPeerConnection`] creation fails. pub fn new(ice_servers: I, is_force_relayed: bool) -> Result where I: IntoIterator, @@ -240,6 +245,11 @@ impl RtcPeerConnection { /// Sets handler for [`RtcTrackEvent`] event (see [RTCTrackEvent][1] and /// [`ontrack` callback][2]). /// + /// # Errors + /// + /// Will return [`RTCPeerConnectionError::PeerConnectionEventBindFailed`] if + /// [`EventListener`] binding fails. + /// /// [1]: https://www.w3.org/TR/webrtc/#rtctrackevent /// [2]: https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-ontrack pub fn on_track(&self, f: Option) -> Result<()> @@ -270,6 +280,11 @@ impl RtcPeerConnection { /// Sets handler for [`RtcPeerConnectionIceEvent`] event /// (see [RTCPeerConnectionIceEvent][1] and [`onicecandidate` callback][2]). /// + /// # Errors + /// + /// Will return [`RTCPeerConnectionError::PeerConnectionEventBindFailed`] if + /// [`EventListener`] binding fails. + /// /// [1]: https://www.w3.org/TR/webrtc/#dom-rtcpeerconnectioniceevent /// [2]: https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection-onicecandidate pub fn on_ice_candidate(&self, f: Option) -> Result<()> @@ -309,6 +324,11 @@ impl RtcPeerConnection { /// Sets handler for [`iceconnectionstatechange`][1] event. /// + /// # Errors + /// + /// Will return [`RTCPeerConnectionError::PeerConnectionEventBindFailed`] if + /// [`EventListener`] binding fails. + /// /// [1]: https://www.w3.org/TR/webrtc/#event-iceconnectionstatechange pub fn on_ice_connection_state_change(&self, f: Option) -> Result<()> where diff --git a/jason/src/peer/media.rs b/jason/src/peer/media.rs index 2bc2feee6..737e34fff 100644 --- a/jason/src/peer/media.rs +++ b/jason/src/peer/media.rs @@ -157,6 +157,17 @@ impl MediaConnections { /// Returns mapping from a [`MediaTrack`] ID to a `mid` of /// this track's [`RtcRtpTransceiver`]. + /// + /// # Errors + /// + /// Will return [`MediaConnectionsError::SendersWithoutMids`] if some + /// [`Sender`] doesn't have [`mid`]. + /// + /// Will return [`MediaConnectionsError::ReceiversWithoutMids`] if some + /// [`Receiver`] doesn't have [`mid`]. + /// + /// [`mid`]: + /// https://developer.mozilla.org/en-US/docs/Web/API/RTCRtpTransceiver/mid pub fn get_mids(&self) -> Result> { let mut s = self.0.borrow_mut(); let mut mids = @@ -188,8 +199,10 @@ impl MediaConnections { /// and [`Receiver`]s for each new [`Track`], and updates [`Track`] if /// its settings has been changed. /// - /// Returns [`StreamRequest`] in case a new local [`MediaStream`] - /// is required. + /// # Errors + /// + /// Will return [`MediaConnectionsError`] if some error happen while + /// creating new [`Sender`] or [`Receiver`]. // TODO: Doesnt really updates anything, but only generates new senders // and receivers atm. pub fn update_tracks>( diff --git a/jason/src/peer/mod.rs b/jason/src/peer/mod.rs index 70efa96ac..2f15f8a09 100644 --- a/jason/src/peer/mod.rs +++ b/jason/src/peer/mod.rs @@ -175,6 +175,14 @@ impl PeerConnection { /// this peer. /// /// Provided `ice_servers` will be used by created [`RtcPeerConnection`]. + /// + /// # Errors + /// + /// Will return [`PeerError::RtcPeerConnection`] if [`RtcPeerConnection`] + /// creating fails. + /// + /// Will return [`PeerError::RtcPeerConnection`] if some callback of + /// [`RtcPeerConnection`] can't be set. pub fn new>( id: Id, peer_events_sender: mpsc::UnboundedSender, @@ -348,6 +356,9 @@ impl PeerConnection { /// [`RtcPeerConnection`]. mid is id of [`m= section`][1]. mids are received /// directly from registered [`RTCRtpTransceiver`][2]s, and are being /// allocated on sdp update. + /// + /// # Errors + /// /// Errors if finds transceiver without mid, so must be called after setting /// local description if offerrer, and remote if answerer. /// diff --git a/jason/src/peer/repo.rs b/jason/src/peer/repo.rs index 8b7b52cb3..b24fdc27e 100644 --- a/jason/src/peer/repo.rs +++ b/jason/src/peer/repo.rs @@ -18,6 +18,11 @@ pub trait PeerRepository { /// [`IceServer`]s, [`PeerEvent`] sender and stored [`MediaManager`]. /// /// [`PeerConnection`] can be created with muted audio or video [`Track`]s. + /// + /// # Errors + /// + /// Will return [`PeerError`] if error while creating [`PeerConnection`] + /// happens. fn create_peer( &mut self, id: PeerId, diff --git a/jason/src/peer/stream_request.rs b/jason/src/peer/stream_request.rs index bcbe9d669..dbf615934 100644 --- a/jason/src/peer/stream_request.rs +++ b/jason/src/peer/stream_request.rs @@ -107,6 +107,22 @@ pub struct SimpleStreamRequest { impl SimpleStreamRequest { /// Parses raw [`SysMediaStream`] and returns [`MediaStream`] wrapper. + /// + /// # Errors + /// + /// Will return [`StreamRequestError::InvalidAudioTrack`] if some audio + /// [`MediaTrack`] from provided [`SysMediaStream`] not satisfies + /// contained constrains. + /// + /// Will return [`StreamRequestError::ExpectedAudioTracks`] if provided + /// [`SysMediaStream`] doesn't have expected audio [`MediaTrack`]. + /// + /// Will return [`StreamRequestError::InvalidVideoTrack`] if some video + /// [`MediaTrack`] from provided [`SysMediaStream`] not satisfies + /// contained constrains. + /// + /// Will return [`StreamRequestError::ExpectedVideoTracks`] if provided + /// [`SysMediaStream`] doesn't have exepcted video [`MediaTrack`]. pub fn parse_stream(&self, stream: &SysMediaStream) -> Result { use StreamRequestError::*; diff --git a/jason/src/rpc/mod.rs b/jason/src/rpc/mod.rs index b6eab7851..05c9517e6 100644 --- a/jason/src/rpc/mod.rs +++ b/jason/src/rpc/mod.rs @@ -310,6 +310,11 @@ pub trait RpcTransport { fn set_close_reason(&self, reason: ClientDisconnect); /// Sends given [`ClientMsg`] to a server. + /// + /// # Errors + /// + /// Will return [`TransportError`] if some error while [`ClientMsg`] sending + /// happens. fn send(&self, msg: &ClientMsg) -> Result<(), Traced>; /// Subscribes to a [`RpcTransport`]'s [`State`] changes. diff --git a/jason/src/utils/event_listener.rs b/jason/src/utils/event_listener.rs index d5e30b602..4d48aec20 100644 --- a/jason/src/utils/event_listener.rs +++ b/jason/src/utils/event_listener.rs @@ -29,6 +29,10 @@ where A: FromWasmAbi + 'static, { /// Creates new [`EventListener`] from a given [`FnMut`] `closure`. + /// + /// # Errors + /// + /// Will return [`EventListenerBindError`] if [`EventListener`] bound fails. pub fn new_mut( target: Rc, event_name: &'static str, @@ -56,6 +60,10 @@ where } /// Creates new [`EventListener`] from a given [`FnOnce`] `closure`. + /// + /// # Errors + /// + /// Will return [`EventListenerBindError`] if [`EventListener`] bound fails. pub fn new_once( target: Rc, event_name: &'static str, diff --git a/src/api/client/server.rs b/src/api/client/server.rs index ff5a51c02..f548563a5 100644 --- a/src/api/client/server.rs +++ b/src/api/client/server.rs @@ -103,6 +103,11 @@ pub struct Server(ActixServer); impl Server { /// Starts Client API HTTP server. + /// + /// # Errors + /// + /// Will return [`io::Error`] if some error while binding [`HttpServer`] + /// happens. pub fn run(rooms: RoomRepository, config: Conf) -> io::Result> { let server_addr = config.server.client.http.bind_addr(); diff --git a/src/api/control/mod.rs b/src/api/control/mod.rs index fdecc1736..739579ddf 100644 --- a/src/api/control/mod.rs +++ b/src/api/control/mod.rs @@ -175,6 +175,17 @@ impl From for LoadStaticControlSpecsError { } /// Loads [`RoomSpec`] from file with YAML format. +/// +/// # Errors +/// +/// Will return [`LoadStaticControlSpecError::IoError`] if reading of provided +/// [`Path`] to file fails. +/// +/// Will return [`LoadStaticControlSpecsError::YamlDeserializationError`] if +/// YAML deserialization fails. +/// +/// Will return [`LoadStaticControlSpecsError::TryFromElementError`] if +/// [`RoomSpec`] convertation fails. pub fn load_from_yaml_file>( path: P, ) -> Result { @@ -187,6 +198,11 @@ pub fn load_from_yaml_file>( } /// Loads all [`RoomSpec`] from YAML files from provided path. +/// +/// # Errors +/// +/// Will return [`LoadStateControlSpecsError::SpecDirReadError`] if error while +/// reading provided [`Path`] happened. pub fn load_static_specs_from_dir>( path: P, ) -> Result, LoadStaticControlSpecsError> { diff --git a/src/api/control/room.rs b/src/api/control/room.rs index 1762b9fb2..3e2647e70 100644 --- a/src/api/control/room.rs +++ b/src/api/control/room.rs @@ -90,6 +90,11 @@ impl TryFrom for RoomSpec { impl RoomSpec { /// Returns all [`MemberSpec`]s of this [`RoomSpec`]. + /// + /// # Errors + /// + /// Will return [`TryFromElementError::NotMember`] if not [`MemberSpec`] + /// was found in a this [`RoomSpec`]'s pipeline. pub fn members( &self, ) -> Result, TryFromElementError> { diff --git a/src/conf/mod.rs b/src/conf/mod.rs index f75778624..ee763f4a8 100644 --- a/src/conf/mod.rs +++ b/src/conf/mod.rs @@ -62,6 +62,10 @@ impl Conf { /// - configuration file, the name of which is given as a command line /// parameter or environment variable; /// - environment variables. + /// + /// # Errors + /// + /// Will return [`Error`] if some error while parsing happens. pub fn parse() -> Result { let mut cfg = Config::new(); diff --git a/src/media/peer.rs b/src/media/peer.rs index 023e32629..70cc0c058 100644 --- a/src/media/peer.rs +++ b/src/media/peer.rs @@ -327,9 +327,17 @@ impl Peer { } } - /// Sets tracks `mids`. + /// Sets tracks [`mid`]s. /// - /// Provided `mids` must have entries for all [`Peer`]s tracks. + /// Provided [`mid`]s must have entries for all [`Peer`]s tracks. + /// + /// # Errors + /// + /// Will return [`PeerError::MidsMismatch`] if `Peer` is sending `Track` + /// without providing its [`mid`]. + /// + /// [`mid`]: + /// https://developer.mozilla.org/en-US/docs/Web/API/RTCRtpTransceiver/mid pub fn set_mids( &mut self, mut mids: HashMap, @@ -374,6 +382,15 @@ impl Peer { } impl Peer { + /// Returns [`mid`]s of this [`Peer`]. + /// + /// # Errors + /// + /// Will return [`PeerError::MidsMismatch`] if `Peer` is sending `Track` + /// without providing its [`mid`]. + /// + /// [`mid`]: + /// https://developer.mozilla.org/en-US/docs/Web/API/RTCRtpTransceiver/mid pub fn get_mids(&self) -> Result, PeerError> { let mut mids = HashMap::with_capacity(self.context.senders.len()); for (track_id, track) in &self.context.senders { diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index 6afb73281..5a7d1615e 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -386,6 +386,11 @@ impl Member { /// Lookups [`WebRtcPublishEndpoint`] and [`WebRtcPlayEndpoint`] at one /// moment by ID. + /// + /// # Errors + /// + /// Will return [`MemberError::EndpointNotFound`] if `Endpoint` with + /// provided ID not found. pub fn get_endpoint_by_id( &self, id: String, @@ -456,6 +461,13 @@ impl WeakMember { /// loads all related to this [`Member`]s sources and sinks endpoints. /// /// Returns store of all [`Member`]s loaded from [`RoomSpec`]. +/// +/// # Errors +/// +/// Will return [`MembersLoadError::TryFromError`] if some error happens while +/// converting getting [`MemberSpec`]s from [`RoomSpec`]. +/// +/// Will return [`MembersLoadError`] if error while [`Member`] loading happens. pub fn parse_members( room_spec: &RoomSpec, ) -> Result, MembersLoadError> { diff --git a/src/signalling/participants.rs b/src/signalling/participants.rs index 4fc5cba16..07c663873 100644 --- a/src/signalling/participants.rs +++ b/src/signalling/participants.rs @@ -114,6 +114,11 @@ pub struct ParticipantService { impl ParticipantService { /// Creates new [`ParticipantService`] from [`RoomSpec`]. + /// + /// # Errors + /// + /// Returns [`MemberLoadError`] if error while [`RoomSpec`] transformation + /// happened. pub fn new( room_spec: &RoomSpec, context: &AppContext, @@ -144,6 +149,8 @@ impl ParticipantService { /// Lookups [`Member`] by [`MemberId`]. /// + /// # Errors + /// /// Returns [`ParticipantServiceErr::ParticipantNotFound`] if [`Member`] not /// found. pub fn get_member( @@ -165,10 +172,12 @@ impl ParticipantService { /// Lookups [`Member`] by provided [`MemberId`] and credentials. /// - /// Returns [`AuthorizationError::MemberNotExists`] if lookup by + /// # Errors + /// + /// Will return [`AuthorizationError::MemberNotExists`] if lookup by /// [`MemberId`] failed. /// - /// Returns [`AuthorizationError::InvalidCredentials`] if [`Member`] + /// Will return [`AuthorizationError::InvalidCredentials`] if [`Member`] /// was found, but incorrect credentials were provided. pub fn get_member_by_id_and_credentials( &self, diff --git a/src/signalling/peers.rs b/src/signalling/peers.rs index 30795dd16..d0049ef20 100644 --- a/src/signalling/peers.rs +++ b/src/signalling/peers.rs @@ -68,6 +68,11 @@ impl PeerRepository { } /// Returns borrowed [`PeerStateMachine`] by its ID. + /// + /// # Errors + /// + /// Will return [`RoomError::PeerNotFound`] if requested [`PeerId`] + /// not exists in [`PeerRepository`]. pub fn get_peer_by_id( &self, peer_id: PeerId, @@ -138,6 +143,11 @@ impl PeerRepository { } /// Returns borrowed [`Peer`] by its ID. + /// + /// # Errors + /// + /// Will return [`RoomError::PeerNotFound`] if requested [`PeerId`] + /// not exists in [`PeerRepository`]. pub fn get_inner_peer_by_id<'a, S>( &'a self, peer_id: PeerId, @@ -165,6 +175,11 @@ impl PeerRepository { } /// Returns owned [`Peer`] by its ID. + /// + /// # Errors + /// + /// Will return [`RoomError::PeerNotFound`] if requested [`PeerId`] + /// not exists in [`PeerRepository`]. pub fn take_inner_peer( &mut self, peer_id: PeerId, diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 6bde9dcd5..4316170dd 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -178,7 +178,9 @@ pub struct Room { impl Room { /// Creates new instance of [`Room`]. /// - /// Returns [`RoomError::BadRoomSpec`] when errs while `Element` + /// # Errors + /// + /// Will return [`RoomError::BadRoomSpec`] when errs while `Element` /// transformation happens. pub fn new( room_spec: &RoomSpec, @@ -542,6 +544,11 @@ impl Room { /// /// Returns [`RoomError::EndpointAlreadyExists`] when /// [`WebRtcPublishEndpoint`]'s ID already presented in [`Member`]. + /// + /// # Errors + /// + /// Will return [`RoomError::ParticipantServiceErr`] if [`Member`] with + /// provided [`MemberId`] not found in [`ParticipantService`]. pub fn create_src_endpoint( &mut self, member_id: &MemberId, @@ -590,6 +597,11 @@ impl Room { /// /// Returns [`RoomError::EndpointAlreadyExists`] when /// [`WebRtcPlayEndpoint`]'s ID already presented in [`Member`]. + /// + /// # Errors + /// + /// Will return [`RoomError::ParticipantServiceErr`] if `Member` with + /// provided [`MemberId`] not exists. pub fn create_sink_endpoint( &mut self, member_id: &MemberId, @@ -656,6 +668,11 @@ impl Room { /// /// Returns [`RoomError::MemberAlreadyExists`] when /// [`Member`]'s ID already presented in [`ParticipantService`]. + /// + /// # Errors + /// + /// Will return [`RoomError::MemberAlreadyExists`] if `Member` with + /// provided [`MemberId`] already exists in [`ParticipantService`]. pub fn create_member( &mut self, id: MemberId, diff --git a/src/signalling/room_service.rs b/src/signalling/room_service.rs index 4d05c6bc2..15edb7297 100644 --- a/src/signalling/room_service.rs +++ b/src/signalling/room_service.rs @@ -391,6 +391,11 @@ impl DeleteElements { /// Validates request. It must have at least one fid, all fids must share /// same [`RoomId`]. + /// + /// # Errors + /// + /// Will return [`RoomServiceError::EmptyUrisList`] if [`DeleteElements`] + /// consists of an empty [`Vec`] of [`StatefulFid`]s. pub fn validate( self, ) -> Result, RoomServiceError> { diff --git a/src/turn/repo.rs b/src/turn/repo.rs index ba3dd3ebb..60f34366e 100644 --- a/src/turn/repo.rs +++ b/src/turn/repo.rs @@ -32,6 +32,10 @@ pub struct TurnDatabase { impl TurnDatabase { /// Creates new [`TurnDatabase`]. + /// + /// # Errors + /// + /// Will return [`TurnDatabaseErr`] if authentication in [Redis] was failed. pub fn new( conn_timeout: Duration, conn_info: S, diff --git a/src/turn/service.rs b/src/turn/service.rs index 7a4a0fcd6..15cfb2e6e 100644 --- a/src/turn/service.rs +++ b/src/turn/service.rs @@ -135,6 +135,11 @@ impl TurnAuthService for Service { } /// Create new instance [`TurnAuthService`]. +/// +/// # Errors +/// +/// Will return [`TurnServiceErr::TurnAuthRepoErr`] if authentication in [Redis] +/// was failed. pub fn new_turn_auth_service<'a>( cf: &conf::Turn, ) -> Result, TurnServiceErr> { From 9d7163b18d6ea19d66bd415cca066ca210737d58 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 4 Feb 2020 17:29:29 +0300 Subject: [PATCH 024/224] Fix new clippy lints [run ci] --- jason/src/peer/media.rs | 8 +++----- proto/control-api/build.rs | 11 ++++------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/jason/src/peer/media.rs b/jason/src/peer/media.rs index 737e34fff..fb437a883 100644 --- a/jason/src/peer/media.rs +++ b/jason/src/peer/media.rs @@ -139,8 +139,7 @@ impl MediaConnections { self.0 .borrow() .iter_senders_with_kind(TransceiverKind::Audio) - .skip_while(|s| s.is_track_enabled()) - .next() + .find(|s| !s.is_track_enabled()) .is_none() } @@ -150,8 +149,7 @@ impl MediaConnections { self.0 .borrow() .iter_senders_with_kind(TransceiverKind::Video) - .skip_while(|s| s.is_track_enabled()) - .next() + .find(|s| !s.is_track_enabled()) .is_none() } @@ -510,6 +508,6 @@ impl Receiver { if self.mid.is_none() && self.transceiver.is_some() { self.mid = self.transceiver.as_ref().unwrap().mid() } - self.mid.as_ref().map(String::as_str) + self.mid.as_deref() } } diff --git a/proto/control-api/build.rs b/proto/control-api/build.rs index 72ed4548f..53f722bb4 100644 --- a/proto/control-api/build.rs +++ b/proto/control-api/build.rs @@ -66,17 +66,14 @@ mod grpc { /// Loads [`ProtoNames`] from [`GRPC_DIR`] directory. pub fn load() -> io::Result { let proto_names = fs::read_dir(GRPC_DIR)? - .into_iter() .collect::, _>>()? .into_iter() .map(|entry| entry.path()) .filter(|path| { - path.extension() - .map(|ext| { - path.is_file() - && ext.to_string_lossy() == Cow::from("proto") - }) - .unwrap_or(false) + path.extension().map_or(false, |ext| { + path.is_file() + && ext.to_string_lossy() == Cow::from("proto") + }) }) .filter_map(|path| { path.file_stem() From 8a8f9323af7cf39dcd7caabb127289dd4dacdfbd Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 4 Feb 2020 17:54:14 +0300 Subject: [PATCH 025/224] Temporary disable wasm-opt because it broken [run ci] --- jason/Cargo.toml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jason/Cargo.toml b/jason/Cargo.toml index f29dfa632..a85eb317e 100644 --- a/jason/Cargo.toml +++ b/jason/Cargo.toml @@ -69,3 +69,8 @@ wee_alloc = { version = "0.4", optional = true } [dev-dependencies] wasm-bindgen-test = "0.3" + +[metadata] +# TODO: remove this when https://github.com/rustwasm/wasm-pack/issues/782 +# issue will be resolved. +wasm-opt = false From 0c8b07129fb935e350e6d552ec8f76920704c671 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 4 Feb 2020 18:08:39 +0300 Subject: [PATCH 026/224] Minor docs fix [run ci] --- src/signalling/room.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 4316170dd..5a9492ae6 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -595,11 +595,11 @@ impl Room { /// This function will check that new [`WebRtcPlayEndpoint`]'s ID is not /// present in [`ParticipantService`]. /// - /// Returns [`RoomError::EndpointAlreadyExists`] when - /// [`WebRtcPlayEndpoint`]'s ID already presented in [`Member`]. - /// /// # Errors /// + /// Will return [`RoomError::EndpointAlreadyExists`] when + /// [`WebRtcPlayEndpoint`]'s ID already presented in [`Member`]. + /// /// Will return [`RoomError::ParticipantServiceErr`] if `Member` with /// provided [`MemberId`] not exists. pub fn create_sink_endpoint( @@ -666,9 +666,6 @@ impl Room { /// This function will check that new [`Member`]'s ID is not present in /// [`ParticipantService`]. /// - /// Returns [`RoomError::MemberAlreadyExists`] when - /// [`Member`]'s ID already presented in [`ParticipantService`]. - /// /// # Errors /// /// Will return [`RoomError::MemberAlreadyExists`] if `Member` with From 44fde68829248d3dd15b1e0bcfeeea0308f997c4 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Fri, 7 Feb 2020 15:24:24 +0300 Subject: [PATCH 027/224] IceUsers now is creating for Peers --- mock/control-api/src/callback/mod.rs | 34 ++++++++ proto/control-api/src/grpc/callback.proto | 4 +- proto/control-api/src/grpc/medea_callback.rs | 4 +- .../control/endpoints/webrtc_play_endpoint.rs | 4 +- src/media/ice_user.rs | 8 +- src/media/peer.rs | 1 + src/signalling/elements/member.rs | 19 ---- src/signalling/participants.rs | 86 ++----------------- src/signalling/peers.rs | 60 ++++++++++--- src/signalling/room.rs | 85 +++++++++--------- src/turn/service.rs | 10 ++- 11 files changed, 148 insertions(+), 167 deletions(-) diff --git a/mock/control-api/src/callback/mod.rs b/mock/control-api/src/callback/mod.rs index 2522d5028..443743810 100644 --- a/mock/control-api/src/callback/mod.rs +++ b/mock/control-api/src/callback/mod.rs @@ -11,6 +11,8 @@ use serde::Serialize; pub enum CallbackEvent { OnJoin(join::OnJoin), OnLeave(leave::OnLeave), + OnStart(on_start::OnStart), + OnStop(on_stop::OnStop), } impl From for CallbackEvent { @@ -22,6 +24,12 @@ impl From for CallbackEvent { proto::request::Event::OnJoin(on_join) => { Self::OnJoin(on_join.into()) } + proto::request::Event::OnStart(on_start) => { + Self::OnStart(on_start.into()) + } + proto::request::Event::OnStop(on_stop) => { + Self::OnStop(on_stop.into()) + } } } } @@ -65,6 +73,32 @@ mod join { } } +mod on_start { + use super::*; + + #[derive(Clone, Serialize)] + pub struct OnStart; + + impl From for OnStart { + fn from(_: proto::OnStart) -> Self { + Self + } + } +} + +mod on_stop { + use super::*; + + #[derive(Clone, Serialize)] + pub struct OnStop; + + impl From for OnStop { + fn from(_: proto::OnStop) -> Self { + Self + } + } +} + /// `on_leave` callback's related entities and implementations. mod leave { use medea_control_api_proto::grpc::medea_callback as proto; diff --git a/proto/control-api/src/grpc/callback.proto b/proto/control-api/src/grpc/callback.proto index 5ee356908..d5ef5a177 100644 --- a/proto/control-api/src/grpc/callback.proto +++ b/proto/control-api/src/grpc/callback.proto @@ -21,12 +21,12 @@ message Request { oneof event { OnJoin on_join = 3; OnLeave on_leave = 4; - OnPlay on_play = 5; + OnStart on_start = 5; OnStop on_stop = 6; } } -message OnPlay {} +message OnStart {} message OnStop {} diff --git a/proto/control-api/src/grpc/medea_callback.rs b/proto/control-api/src/grpc/medea_callback.rs index 752a45c35..27f85e75e 100644 --- a/proto/control-api/src/grpc/medea_callback.rs +++ b/proto/control-api/src/grpc/medea_callback.rs @@ -20,13 +20,13 @@ pub mod request { #[prost(message, tag="4")] OnLeave(super::OnLeave), #[prost(message, tag="5")] - OnPlay(super::OnPlay), + OnStart(super::OnStart), #[prost(message, tag="6")] OnStop(super::OnStop), } } #[derive(Clone, PartialEq, ::prost::Message)] -pub struct OnPlay { +pub struct OnStart { } #[derive(Clone, PartialEq, ::prost::Message)] pub struct OnStop { diff --git a/src/api/control/endpoints/webrtc_play_endpoint.rs b/src/api/control/endpoints/webrtc_play_endpoint.rs index a1a274074..8b28eb938 100644 --- a/src/api/control/endpoints/webrtc_play_endpoint.rs +++ b/src/api/control/endpoints/webrtc_play_endpoint.rs @@ -39,11 +39,11 @@ impl TryFrom<&proto::WebRtcPlayEndpoint> for WebRtcPlayEndpoint { value: &proto::WebRtcPlayEndpoint, ) -> Result { let on_start = Some(value.on_start.clone()) - .filter(String::is_empty) + .filter(|s| !s.is_empty()) .map(CallbackUrl::try_from) .transpose()?; let on_stop = Some(value.on_stop.clone()) - .filter(String::is_empty) + .filter(|s| !s.is_empty()) .map(CallbackUrl::try_from) .transpose()?; diff --git a/src/media/ice_user.rs b/src/media/ice_user.rs index 6832c147a..2c95fa979 100644 --- a/src/media/ice_user.rs +++ b/src/media/ice_user.rs @@ -2,9 +2,9 @@ //! //! [coturn]: https://github.com/coturn/coturn -use medea_client_api_proto::IceServer; +use medea_client_api_proto::{IceServer, PeerId}; -use crate::api::control::RoomId; +use crate::api::control::{EndpointId, RoomId}; /// Credentials on Turn server. #[derive(Clone, Debug)] @@ -26,12 +26,12 @@ impl IceUser { pub fn build( address: String, room_id: &RoomId, - name: &str, + peer_id: PeerId, pass: String, ) -> Self { Self { address, - user: format!("{}_{}", room_id, name), + user: format!("{}_{}", room_id, peer_id), pass, is_static: false, } diff --git a/src/media/peer.rs b/src/media/peer.rs index 70cc0c058..baee2653c 100644 --- a/src/media/peer.rs +++ b/src/media/peer.rs @@ -71,6 +71,7 @@ impl PeerError { #[enum_delegate(pub fn partner_peer_id(&self) -> Id)] #[enum_delegate(pub fn partner_member_id(&self) -> MemberId)] #[enum_delegate(pub fn is_force_relayed(&self) -> bool)] +#[enum_delegate(pub fn tracks(&self) -> Vec)] #[derive(Debug)] pub enum PeerStateMachine { New(Peer), diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index 1b0688161..3078a0b73 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -82,9 +82,6 @@ struct MemberInner { /// Credentials for this [`Member`]. credentials: String, - /// [`IceUser`] of this [`Member`]. - ice_user: Option, - /// URL to which `on_join` Control API callback will be sent. on_join: Option, @@ -103,7 +100,6 @@ impl Member { srcs: HashMap::new(), sinks: HashMap::new(), credentials, - ice_user: None, room_id, on_leave: None, on_join: None, @@ -274,21 +270,6 @@ impl Member { .for_each(|(_, p)| p.reset()); } - /// Returns list of [`IceServer`] for this [`Member`]. - pub fn servers_list(&self) -> Option> { - self.0.borrow().ice_user.as_ref().map(IceUser::servers_list) - } - - /// Returns and sets to `None` [`IceUser`] of this [`Member`]. - pub fn take_ice_user(&self) -> Option { - self.0.borrow_mut().ice_user.take() - } - - /// Replaces and returns [`IceUser`] of this [`Member`]. - pub fn replace_ice_user(&self, new_ice_user: IceUser) -> Option { - self.0.borrow_mut().ice_user.replace(new_ice_user) - } - /// Returns [`MemberId`] of this [`Member`]. pub fn id(&self) -> MemberId { self.0.borrow().id.clone() diff --git a/src/signalling/participants.rs b/src/signalling/participants.rs index 07c663873..8bdb25953 100644 --- a/src/signalling/participants.rs +++ b/src/signalling/participants.rs @@ -15,7 +15,7 @@ use std::{ use actix::{ fut::wrap_future, ActorFuture as _, AsyncContext, Context, - ContextFutureSpawner as _, SpawnHandle, + ContextFutureSpawner as _, SpawnHandle, WrapFuture, }; use derive_more::Display; use failure::Fail; @@ -255,27 +255,8 @@ impl ParticipantService { let turn_service = self.turn_service.clone(); let cloned_member_id = member_id.clone(); let room_id = self.room_id.clone(); - Box::new( - wrap_future(async move { - turn_service - .create( - cloned_member_id, - room_id, - UnreachablePolicy::ReturnErr, - ) - .await - }) - .map(move |result, room: &mut Room, _| { - match result { - Ok(ice_user) => { - room.members.insert_connection(member_id, conn); - member.replace_ice_user(ice_user); - Ok(member) - } - Err(e) => Err(ParticipantServiceErr::from(e)), - } - }), - ) + self.insert_connection(member_id, conn); + Box::new(wrap_future(future::ok(member))) } } @@ -303,18 +284,6 @@ impl ParticipantService { ClosedReason::Closed { .. } => { debug!("Connection for member [id = {}] removed.", member_id); self.connections.remove(&member_id); - wrap_future::<_, Room>( - self.delete_ice_user(&member_id) - .map_err(move |e| { - error!( - "Error deleting IceUser of Member [id = {}]. \ - {:?}", - member_id, e, - ) - }) - .map(|_| ()), - ) - .spawn(ctx); // TODO: we have no way to handle absence of RpcConnection right // now. } @@ -336,25 +305,6 @@ impl ParticipantService { } } - /// Deletes [`IceUser`] associated with provided [`Member`]. - fn delete_ice_user( - &mut self, - member_id: &MemberId, - ) -> LocalBoxFuture<'static, Result<(), TurnServiceErr>> { - match self.get_member_by_id(&member_id) { - None => future::ok(()).boxed_local(), - Some(member) => { - if let Some(ice_user) = member.take_ice_user() { - let turn_service = self.turn_service.clone(); - async move { turn_service.delete(&[ice_user]).await } - .boxed_local() - } else { - future::ok(()).boxed_local() - } - } - } - } - /// Cancels all connection close tasks, closes all [`RpcConnection`]s and /// deletes all [`IceUser`]s. pub fn drop_connections( @@ -380,23 +330,7 @@ impl ParticipantService { }, )); - // deleting all IceUsers - let ice_users: Vec<_> = self - .members - .values() - .filter_map(Member::take_ice_user) - .collect(); - - let turn_service = self.turn_service.clone(); - let delete_ice_users = async move { - if let Err(e) = turn_service.delete(ice_users.as_slice()).await { - error!("Error removing IceUsers {:?}", e) - }; - }; - - future::join(close_rpc_connections, delete_ice_users) - .map(|_| ()) - .boxed_local() + close_rpc_connections.map(|_| ()).boxed_local() } /// Deletes [`Member`] from [`ParticipantService`], removes this user from @@ -420,17 +354,7 @@ impl ParticipantService { .spawn(ctx); } - if let Some(member) = self.members.remove(member_id) { - if let Some(ice_user) = member.take_ice_user() { - let turn_service = self.turn_service.clone(); - wrap_future::<_, Room>(async move { - if let Err(e) = turn_service.delete(&[ice_user]).await { - error!("Error removing IceUser {:?}", e) - } - }) - .spawn(ctx); - } - } + self.members.remove(member_id); } /// Inserts given [`Member`] into [`ParticipantService`]. diff --git a/src/signalling/peers.rs b/src/signalling/peers.rs index d0049ef20..04f6e943e 100644 --- a/src/signalling/peers.rs +++ b/src/signalling/peers.rs @@ -12,19 +12,27 @@ use derive_more::Display; use medea_client_api_proto::{Incrementable, PeerId, TrackId}; use crate::{ - api::control::MemberId, + api::control::{MemberId, RoomId}, log::prelude::*, - media::{New, Peer, PeerStateMachine}, + media::{IceUser, New, Peer, PeerStateMachine}, signalling::{ elements::endpoints::webrtc::{ WebRtcPlayEndpoint, WebRtcPublishEndpoint, }, room::RoomError, }, + turn::{TurnAuthService, UnreachablePolicy}, }; +use std::{cell::RefCell, future::Future, rc::Rc, sync::Arc}; #[derive(Debug)] pub struct PeerRepository { + room_id: RoomId, + + ice_users: Rc>>, + + turn_service: Arc, + /// [`Peer`]s of [`Member`]s in this [`Room`]. /// /// [`Member`]: crate::signalling::elements::member::Member @@ -59,6 +67,20 @@ impl Counter { } impl PeerRepository { + pub fn new( + room_id: RoomId, + turn_service: Arc, + ) -> Self { + Self { + room_id, + turn_service, + ice_users: Rc::new(RefCell::new(HashMap::new())), + peers: HashMap::new(), + peers_count: Counter::default(), + tracks_count: Counter::default(), + } + } + /// Store [`Peer`] in [`Room`]. /// /// [`Room`]: crate::signalling::Room @@ -82,6 +104,30 @@ impl PeerRepository { .ok_or_else(|| RoomError::PeerNotFound(peer_id)) } + pub fn get_ice_user( + &mut self, + peer_id: PeerId, + ) -> impl Future { + let ice_users = Rc::clone(&self.ice_users); + let turn_service = Arc::clone(&self.turn_service); + let room_id = self.room_id.clone(); + + async move { + let ice_user = ice_users.borrow().get(&peer_id).cloned(); + if let Some(ice_user) = ice_user { + ice_user + } else { + let ice_user = turn_service + .create(room_id, peer_id, UnreachablePolicy::ReturnErr) + .await + .unwrap(); + ice_users.borrow_mut().insert(peer_id, ice_user.clone()); + + ice_user + } + } + } + /// Creates interconnected [`Peer`]s for provided [`Member`]s. pub fn create_peers( &mut self, @@ -345,13 +391,3 @@ impl PeerRepository { None } } - -impl From> for PeerRepository { - fn from(peers: HashMap) -> Self { - Self { - peers, - peers_count: Counter::default(), - tracks_count: Counter::default(), - } - } -} diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 82901ffb4..ab9422496 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -7,7 +7,7 @@ use std::collections::{HashMap, HashSet}; use actix::{ Actor, ActorFuture, Addr, Context, ContextFutureSpawner as _, Handler, - Message, WrapFuture as _, + Message, WrapFuture as _, WrapFuture, }; use derive_more::Display; use failure::Fail; @@ -57,6 +57,7 @@ use crate::{ utils::ResponseActAnyFuture, AppContext, }; +use futures::TryFutureExt; /// Ergonomic type alias for using [`ActorFuture`] for [`Room`]. pub type ActFuture = Box>; @@ -188,7 +189,10 @@ impl Room { ) -> Result { Ok(Self { id: room_spec.id().clone(), - peers: PeerRepository::from(HashMap::new()), + peers: PeerRepository::new( + room_spec.id().clone(), + context.turn_service.clone(), + ), members: ParticipantService::new(room_spec, context)?, state: State::Started, callbacks: context.callbacks.clone(), @@ -236,26 +240,26 @@ impl Room { let sender = sender.start(); let member_id = sender.member_id(); - let ice_servers = self - .members - .get_member(&member_id)? - .servers_list() - .ok_or_else(|| { - RoomError::NoTurnCredentials(member_id.clone()) - })?; - let peer_created = Event::PeerCreated { - peer_id: sender.id(), - sdp_offer: None, - tracks: sender.tracks(), - ice_servers, - force_relay: sender.is_force_relayed(), - }; + let sender_peer_id = sender.id(); self.peers.add_peer(sender); - Ok(Box::new( - self.members - .send_event_to_member(member_id, peer_created) - .into_actor(self), - )) + let fut = self.peers.get_ice_user(sender_peer_id); + + Ok(Box::new(fut.into_actor(self).then( + move |ice_user, this, ctx| { + let sender = this.peers.get_peer_by_id(sender_peer_id).unwrap(); + let peer_created = Event::PeerCreated { + peer_id: sender.id(), + sdp_offer: None, + tracks: sender.tracks(), + ice_servers: ice_user.servers_list(), + force_relay: sender.is_force_relayed(), + }; + + this.members + .send_event_to_member(member_id, peer_created) + .into_actor(this) + }, + ))) } /// Sends [`Event::PeersRemoved`] to [`Member`]. @@ -815,30 +819,29 @@ impl CommandHandler for Room { let to_peer = to_peer.set_remote_sdp(sdp_offer.clone()); let to_member_id = to_peer.member_id(); - let ice_servers = self - .members - .get_member(&to_member_id)? - .servers_list() - .ok_or_else(|| { - RoomError::NoTurnCredentials(to_member_id.clone()) - })?; - - let event = Event::PeerCreated { - peer_id: to_peer.id(), - sdp_offer: Some(sdp_offer), - tracks: to_peer.tracks(), - ice_servers, - force_relay: to_peer.is_force_relayed(), - }; + let to_peer_id = to_peer.id(); self.peers.add_peer(from_peer); self.peers.add_peer(to_peer); - Ok(Box::new( - self.members - .send_event_to_member(to_member_id, event) - .into_actor(self), - )) + let fut = self.peers.get_ice_user(to_peer_id); + + Ok(Box::new(fut.into_actor(self).then( + move |ice_user, this, ctx| { + let to_peer = this.peers.get_peer_by_id(to_peer_id).unwrap(); + let event = Event::PeerCreated { + peer_id: to_peer.id(), + sdp_offer: Some(sdp_offer), + tracks: to_peer.tracks(), + ice_servers: ice_user.servers_list(), + force_relay: to_peer.is_force_relayed(), + }; + + this.members + .send_event_to_member(to_member_id, event) + .into_actor(this) + }, + ))) } /// Sends [`Event::SdpAnswerMade`] to provided [`Peer`] partner. Provided diff --git a/src/turn/service.rs b/src/turn/service.rs index 15cfb2e6e..f3765373b 100644 --- a/src/turn/service.rs +++ b/src/turn/service.rs @@ -12,11 +12,13 @@ use rand::{distributions::Alphanumeric, Rng}; use redis::ConnectionInfo; use crate::{ - api::control::{MemberId, RoomId}, + api::control::{EndpointId, RoomId}, conf, media::IceUser, turn::repo::{TurnDatabase, TurnDatabaseErr}, }; +use medea_client_api_proto::PeerId; +use std::collections::HashMap; static TURN_PASS_LEN: usize = 16; @@ -49,8 +51,8 @@ pub trait TurnAuthService: fmt::Debug + Send + Sync { /// Generates and registers Turn credentials. async fn create( &self, - member_id: MemberId, room_id: RoomId, + peer_id: PeerId, policy: UnreachablePolicy, ) -> Result; @@ -102,14 +104,14 @@ impl TurnAuthService for Service { /// random password. Inserts created [`IceUser`] into [`TurnDatabase`]. async fn create( &self, - member_id: MemberId, room_id: RoomId, + peer_id: PeerId, policy: UnreachablePolicy, ) -> Result { let ice_user = IceUser::build( self.turn_address.clone(), &room_id, - &member_id.0, + peer_id, Self::generate_pass(TURN_PASS_LEN), ); From 0acf3af30cbaefd7274a83db18b9869aa8e383bc Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 10 Feb 2020 18:44:35 +0300 Subject: [PATCH 028/224] Add coturn stats fetching and processing --- _dev/coturn/turnserver.conf | 4 +- src/main.rs | 7 +- src/turn/coturn_stats.rs | 357 ++++++++++++++++++++++++++++++++++++ src/turn/mod.rs | 1 + src/turn/service.rs | 7 +- 5 files changed, 372 insertions(+), 4 deletions(-) create mode 100644 src/turn/coturn_stats.rs diff --git a/_dev/coturn/turnserver.conf b/_dev/coturn/turnserver.conf index 699ac5315..ee4616e3b 100644 --- a/_dev/coturn/turnserver.conf +++ b/_dev/coturn/turnserver.conf @@ -1,8 +1,10 @@ lt-cred-mech fingerprint -no-cli +# no-cli no-tls no-dtls realm=medea redis-userdb="ip=127.0.0.1 port=6379 dbname=0 password=turn" user=USER:PASS +redis-statsdb="ip=127.0.0.1 port=6379 dbname=0 password=turn" +cli-password="qwerty" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 007e366b4..86e87c141 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,10 @@ use medea::{ log::{self, prelude::*}, shutdown::{self, GracefulShutdown}, signalling::{room_repo::RoomRepository, room_service::RoomService}, - turn::new_turn_auth_service, + turn::{ + coturn_stats::{new_coturn_stats_watcher, CoturnStatsWatcher}, + new_turn_auth_service, + }, AppContext, }; @@ -33,6 +36,8 @@ fn main() -> Result<(), Error> { Arbiter::spawn( async move { let turn_service = new_turn_auth_service(&config.turn)?; + let coturn_stats_watcher = + new_coturn_stats_watcher(&config.turn).unwrap().start(); let graceful_shutdown = GracefulShutdown::new(config.shutdown.timeout).start(); let app_context = AppContext::new(config.clone(), turn_service); diff --git a/src/turn/coturn_stats.rs b/src/turn/coturn_stats.rs new file mode 100644 index 000000000..295e7b696 --- /dev/null +++ b/src/turn/coturn_stats.rs @@ -0,0 +1,357 @@ +use std::{fmt, sync::Arc}; + +use async_trait::async_trait; +use derive_more::{Display, From}; +use failure::Fail; +use rand::{distributions::Alphanumeric, Rng}; +use redis::{ConnectionInfo, IntoConnectionInfo, PubSub}; + +use crate::{ + api::control::{EndpointId, MemberId, RoomId}, + conf, + log::prelude::*, + media::IceUser, + turn::repo::{TurnDatabase, TurnDatabaseErr}, +}; +use actix::{Actor, AsyncContext, StreamHandler}; +use futures::channel::mpsc; +use medea_client_api_proto::PeerId; +use std::{collections::HashMap, time::Duration}; + +#[derive(Debug)] +pub enum CoturnAllocationEvent { + New { + lifetime: Duration, + }, + Refreshed { + lifetime: Duration, + }, + Traffic { + received_packets: u64, + received_bytes: u64, + sent_packets: u64, + sent_bytes: u64, + }, + TotalTraffic { + received_packets: u64, + received_bytes: u64, + sent_packets: u64, + sent_bytes: u64, + }, + Deleted, +} + +impl CoturnAllocationEvent { + pub fn parse( + event_type: &str, + body: String, + ) -> Result { + match event_type { + "total_traffic" => { + let mut items: HashMap<&str, u64> = body + .split(", ") + .map(|i| { + let mut splitted_item = i.split('='); + let key = splitted_item.next().ok_or_else(|| { + CoturnEventParseError::FailedToParseTrafficMap( + body.clone(), + ) + })?; + let value: u64 = splitted_item + .next() + .ok_or_else(|| { + CoturnEventParseError::FailedToParseTrafficMap( + body.clone(), + ) + })? + .parse() + .map_err(|_| { + CoturnEventParseError::FailedToParseTrafficMap( + body.clone(), + ) + })?; + + Ok((key, value)) + }) + .collect::>()?; + + let received_packets = + items.remove("rcvp").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "rcvp".to_string(), + ) + })?; + let received_bytes = items.remove("rcvb").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "rcvb".to_string(), + ) + })?; + let sent_packets = items.remove("sentp").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "sentp".to_string(), + ) + })?; + let sent_bytes = items.remove("sentb").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "sentb".to_string(), + ) + })?; + + Ok(CoturnAllocationEvent::TotalTraffic { + received_bytes, + received_packets, + sent_bytes, + sent_packets, + }) + } + "traffic" => { + let mut items: HashMap<&str, u64> = body + .split(", ") + .map(|i| { + let mut splitted_item = i.split('='); + let key = splitted_item.next().ok_or_else(|| { + CoturnEventParseError::FailedToParseTrafficMap( + body.clone(), + ) + })?; + let value: u64 = splitted_item + .next() + .ok_or_else(|| { + CoturnEventParseError::FailedToParseTrafficMap( + body.clone(), + ) + })? + .parse() + .map_err(|_| { + CoturnEventParseError::FailedToParseTrafficMap( + body.clone(), + ) + })?; + + Ok((key, value)) + }) + .collect::>()?; + + let received_packets = + items.remove("rcvp").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "rcvp".to_string(), + ) + })?; + let received_bytes = items.remove("rcvb").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "rcvb".to_string(), + ) + })?; + let sent_packets = items.remove("sentp").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "sentp".to_string(), + ) + })?; + let sent_bytes = items.remove("sentb").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "sentb".to_string(), + ) + })?; + + Ok(CoturnAllocationEvent::Traffic { + received_bytes, + received_packets, + sent_bytes, + sent_packets, + }) + } + "status" => { + let mut splitted = body.split(' '); + let status = splitted + .next() + .ok_or(CoturnEventParseError::EmptyStatus)?; + match status { + "deleted" => Ok(CoturnAllocationEvent::Deleted), + "new" => { + let lifetime = splitted + .next() + .ok_or(CoturnEventParseError::NoMetadataInStatus)? + .replace("lifetime=", "") + .parse() + .map_err(|_| { + CoturnEventParseError::FailedLifetimeParsing + })?; + Ok(CoturnAllocationEvent::New { + lifetime: Duration::from_secs(lifetime), + }) + } + "refreshed" => { + let lifetime = splitted + .next() + .ok_or(CoturnEventParseError::NoMetadataInStatus)? + .replace("lifetime=", "") + .parse() + .map_err(|_| { + CoturnEventParseError::FailedLifetimeParsing + })?; + Ok(CoturnAllocationEvent::Refreshed { + lifetime: Duration::from_secs(lifetime), + }) + } + _ => Err(CoturnEventParseError::UnsupportedStatus( + status.to_string(), + )), + } + } + _ => { + debug!("Body: {}", body); + Err(CoturnEventParseError::UnsupportedEventType( + event_type.to_string(), + )) + } + } + } +} + +#[derive(Debug)] +pub struct CoturnEvent { + event: CoturnAllocationEvent, + member_id: MemberId, + peer_id: PeerId, + allocation_id: u64, +} + +impl CoturnEvent { + pub fn parse(msg: redis::Msg) -> Result { + let channel: String = msg + .get_channel() + .map_err(|_| CoturnEventParseError::NoChannelInfo)?; + let mut channel_splitted = channel.split('/').skip(4); + + let (member_id, peer_id) = { + let user = channel_splitted + .next() + .ok_or(CoturnEventParseError::NoUserInfo)?; + let mut user_splitted = user.split('_'); + let member_id = MemberId( + user_splitted + .next() + .ok_or(CoturnEventParseError::NoMemberId)? + .to_string(), + ); + let peer_id = PeerId( + user_splitted + .next() + .ok_or(CoturnEventParseError::NoPeerId)? + .parse() + .map_err(|_| CoturnEventParseError::NoPeerId)?, + ); + + (member_id, peer_id) + }; + + let mut channel_splitted = channel_splitted.skip(1); + + let allocation_id: u64 = channel_splitted + .next() + .ok_or(CoturnEventParseError::NoAllocationId)? + .parse() + .map_err(|_| CoturnEventParseError::NoAllocationId)?; + let event_type = channel_splitted + .next() + .ok_or(CoturnEventParseError::NoEventType)?; + + let event = CoturnAllocationEvent::parse( + event_type, + msg.get_payload().unwrap(), + )?; + + Ok(CoturnEvent { + event, + member_id, + peer_id, + allocation_id, + }) + } +} + +#[derive(Debug)] +pub enum CoturnEventParseError { + UnsupportedStatus(String), + UnsupportedEventType(String), + FieldNotFoundInTrafficUpdate(String), + FailedToParseTrafficMap(String), + EmptyStatus, + NoMetadataInStatus, + FailedLifetimeParsing, + NoChannelInfo, + NoUserInfo, + NoMemberId, + NoPeerId, + NoAllocationId, + NoEventType, +} + +pub struct CoturnStatsWatcher { + client: redis::Client, +} + +impl CoturnStatsWatcher { + pub fn new( + conf: T, + ) -> Result { + let client = redis::Client::open(conf)?; + + Ok(Self { client }) + } +} + +impl Actor for CoturnStatsWatcher { + type Context = actix::Context; + + fn started(&mut self, ctx: &mut Self::Context) { + let mut conn = self.client.get_connection().unwrap(); + let (tx, rx) = mpsc::unbounded(); + std::thread::spawn(move || { + let mut pubsub = conn.as_pubsub(); + pubsub + .psubscribe("turn/realm/*/user/*/allocation/*") + .unwrap(); + loop { + let msg = pubsub.get_message().unwrap(); + if tx.unbounded_send(msg).is_err() { + break; + } + } + }); + ctx.add_stream(rx); + } +} + +impl StreamHandler for CoturnStatsWatcher { + fn handle(&mut self, item: redis::Msg, ctx: &mut Self::Context) { + match CoturnEvent::parse(item) { + Ok(event) => { + debug!("Coturn stats: {:?}", event); + } + Err(e) => { + error!("Coturn stats parse error: {:?}", e); + } + } + } +} + +pub fn new_coturn_stats_watcher( + cf: &conf::Turn, +) -> Result { + let turn_db = CoturnStatsWatcher::new(ConnectionInfo { + addr: Box::new(redis::ConnectionAddr::Tcp( + cf.db.redis.ip.to_string(), + cf.db.redis.port, + )), + db: cf.db.redis.db_number, + passwd: if cf.db.redis.pass.is_empty() { + None + } else { + Some(cf.db.redis.pass.clone()) + }, + })?; + + Ok(turn_db) +} diff --git a/src/turn/mod.rs b/src/turn/mod.rs index 2200d2a6e..bc8575089 100644 --- a/src/turn/mod.rs +++ b/src/turn/mod.rs @@ -2,6 +2,7 @@ //! //! [TURN]: https://webrtcglossary.com/turn +pub mod coturn_stats; pub mod repo; pub mod service; diff --git a/src/turn/service.rs b/src/turn/service.rs index f3765373b..a8f1121e2 100644 --- a/src/turn/service.rs +++ b/src/turn/service.rs @@ -9,14 +9,17 @@ use async_trait::async_trait; use derive_more::{Display, From}; use failure::Fail; use rand::{distributions::Alphanumeric, Rng}; -use redis::ConnectionInfo; +use redis::{ConnectionInfo, IntoConnectionInfo, PubSub}; use crate::{ - api::control::{EndpointId, RoomId}, + api::control::{EndpointId, MemberId, RoomId}, conf, + log::prelude::*, media::IceUser, turn::repo::{TurnDatabase, TurnDatabaseErr}, }; +use actix::{Actor, AsyncContext, StreamHandler}; +use futures::channel::mpsc; use medea_client_api_proto::PeerId; use std::collections::HashMap; From 926b879152e008c84eb4412f372b1c1b37a6e0c6 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 14:04:56 +0200 Subject: [PATCH 029/224] wip --- Cargo.lock | 622 +++++++++++++------------ Cargo.toml | 4 +- Dockerfile | 2 + _dev/coturn/turnserver.conf | 2 +- config.toml | 18 + crates/coturn-telnet/CHANGELOG.md | 26 ++ crates/coturn-telnet/Cargo.toml | 27 ++ crates/coturn-telnet/LICENSE-APACHE.md | 194 ++++++++ crates/coturn-telnet/LICENSE-MIT.md | 25 + crates/coturn-telnet/README.md | 33 ++ crates/coturn-telnet/src/codec.rs | 292 ++++++++++++ crates/coturn-telnet/src/connection.rs | 186 ++++++++ crates/coturn-telnet/src/lib.rs | 8 + crates/coturn-telnet/src/pool.rs | 79 ++++ jason/demo/index.html | 14 +- jason/e2e-demo/js/index.js | 6 +- jason/src/lib.rs | 2 + jason/src/peer/media.rs | 8 +- proto/control-api/build.rs | 11 +- src/conf/turn.rs | 19 + src/lib.rs | 2 + src/media/ice_user.rs | 19 +- src/media/mod.rs | 2 +- src/signalling/participants.rs | 55 ++- src/signalling/room.rs | 4 +- src/turn/cli.rs | 73 +++ src/turn/mod.rs | 1 + src/turn/repo.rs | 52 +-- src/turn/service.rs | 288 ++++-------- 29 files changed, 1514 insertions(+), 560 deletions(-) create mode 100644 crates/coturn-telnet/CHANGELOG.md create mode 100644 crates/coturn-telnet/Cargo.toml create mode 100644 crates/coturn-telnet/LICENSE-APACHE.md create mode 100644 crates/coturn-telnet/LICENSE-MIT.md create mode 100644 crates/coturn-telnet/README.md create mode 100644 crates/coturn-telnet/src/codec.rs create mode 100644 crates/coturn-telnet/src/connection.rs create mode 100644 crates/coturn-telnet/src/lib.rs create mode 100644 crates/coturn-telnet/src/pool.rs create mode 100644 src/turn/cli.rs diff --git a/Cargo.lock b/Cargo.lock index f8e1148d4..a7d449dac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,7 +6,7 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -27,11 +27,11 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -44,16 +44,16 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix_derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-resolver 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -67,8 +67,8 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -77,11 +77,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -99,8 +99,8 @@ dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -115,7 +115,7 @@ dependencies = [ "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -160,23 +160,23 @@ dependencies = [ "hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -194,7 +194,7 @@ dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -202,24 +202,24 @@ dependencies = [ "encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -243,7 +243,7 @@ dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -256,7 +256,7 @@ dependencies = [ "bytestring 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -268,10 +268,10 @@ dependencies = [ "actix-threadpool 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -282,8 +282,8 @@ dependencies = [ "actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -300,11 +300,11 @@ dependencies = [ "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-signal 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -316,7 +316,7 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -331,8 +331,8 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -348,8 +348,8 @@ name = "actix-service" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -364,8 +364,8 @@ dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -377,7 +377,7 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-server 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -402,7 +402,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -421,7 +421,7 @@ dependencies = [ "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -436,8 +436,8 @@ dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -449,11 +449,11 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -483,9 +483,9 @@ dependencies = [ "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -509,18 +509,18 @@ dependencies = [ "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web-codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -535,9 +535,9 @@ dependencies = [ "actix-codec 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -595,7 +595,7 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -621,7 +621,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "arrayref" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -644,7 +644,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "async-trait" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -689,9 +689,9 @@ dependencies = [ "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -704,21 +704,21 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace" -version = "0.3.42" +version = "0.3.43" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", @@ -741,7 +741,7 @@ name = "base64" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -759,7 +759,7 @@ name = "blake2b_simd" version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -784,12 +784,12 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.1.2" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.3.2" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -797,13 +797,13 @@ name = "bytes" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bytes" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -811,7 +811,7 @@ name = "bytestring" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -878,7 +878,7 @@ version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -894,7 +894,7 @@ dependencies = [ "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde-hjson 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -936,6 +936,22 @@ name = "copyless" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "coturn-telnet" +version = "0.1.0-dev" +dependencies = [ + "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-test 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crc32fast" version = "1.2.0" @@ -1065,25 +1081,25 @@ name = "deadpool" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "config 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "deadpool-redis" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "config 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "redis 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1129,7 +1145,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1176,7 +1192,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1191,7 +1207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "dtoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1233,7 +1249,7 @@ name = "failure" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1257,7 +1273,7 @@ dependencies = [ "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1304,50 +1320,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-channel" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-core" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-executor" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-io" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-macro" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1358,26 +1374,26 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-task" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-util" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-macro 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1390,7 +1406,7 @@ name = "fxhash" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1445,16 +1461,16 @@ name = "h2" version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1462,16 +1478,16 @@ name = "h2" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1521,7 +1537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1529,9 +1545,9 @@ name = "http" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1583,7 +1599,7 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1610,7 +1626,7 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1731,17 +1747,18 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web-actors 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "config 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "coturn-telnet 0.1.0-dev", "deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "deadpool-redis 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "deadpool-redis 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "derive_builder 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "grpcio 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "humantime-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1751,22 +1768,22 @@ dependencies = [ "mockall 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "redis 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-async 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-envlogger 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-stdlog 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "smart-default 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1778,7 +1795,7 @@ dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "medea-macro 0.2.0-dev", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1796,11 +1813,11 @@ dependencies = [ "protobuf 2.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-async 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-envlogger 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-stdlog 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-term 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-term 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1821,14 +1838,14 @@ dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "downcast 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "medea-client-api-proto 0.2.0-dev", "medea-macro 0.2.0-dev", "mockall 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "tracerr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1883,7 +1900,7 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2118,7 +2135,7 @@ dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2134,15 +2151,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pin-project" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pin-project-internal 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pin-project-internal" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2179,7 +2196,7 @@ dependencies = [ "float-cmp 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "normalize-line-endings 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2446,19 +2463,19 @@ dependencies = [ [[package]] name = "redis" -version = "0.14.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2480,18 +2497,18 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.3" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2606,7 +2623,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2622,10 +2639,10 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.44" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2643,8 +2660,8 @@ name = "serde_urlencoded" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2654,7 +2671,7 @@ name = "serde_yaml" version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2685,15 +2702,6 @@ name = "sha1" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "signal-hook" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "signal-hook-registry" version = "1.2.0" @@ -2715,12 +2723,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "slog-async" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "take_mut 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2729,12 +2738,12 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-async 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-stdlog 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-term 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slog-term 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2744,7 +2753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2782,14 +2791,14 @@ dependencies = [ [[package]] name = "slog-term" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2802,7 +2811,7 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2920,14 +2929,6 @@ dependencies = [ "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "thread_local" version = "1.0.1" @@ -2956,12 +2957,12 @@ dependencies = [ [[package]] name = "tokio" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2971,40 +2972,41 @@ dependencies = [ "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-codec" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-current-thread" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-executor" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-io" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3012,12 +3014,22 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-reactor" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3025,30 +3037,30 @@ dependencies = [ "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-signal" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-sync" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3057,40 +3069,50 @@ dependencies = [ [[package]] name = "tokio-tcp" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-test" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-timer" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-udp" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3098,12 +3120,12 @@ name = "tokio-util" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3132,7 +3154,7 @@ name = "trust-dns-proto" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "enum-as-inner 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3142,12 +3164,12 @@ dependencies = [ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3156,17 +3178,17 @@ name = "trust-dns-proto" version = "0.18.0-alpha.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", + "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3184,7 +3206,7 @@ dependencies = [ "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-proto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3195,14 +3217,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3219,7 +3241,7 @@ name = "unicode-normalization" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3297,7 +3319,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3306,7 +3328,7 @@ name = "wasm-bindgen-backend" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3524,21 +3546,21 @@ dependencies = [ "checksum actix_derive 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c" "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6f33b5018f120946c1dcf279194f238a9f146725593ead1c08fa47ff22b0b5d3" -"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" "checksum arc-swap 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b8a9123b8027467bce0099fe556c628a53c8d83df0507084c31e9ba2e39aff" -"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" +"checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" "checksum ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" -"checksum async-trait 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c" +"checksum async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "750b1c38a1dfadd108da0f01c08f4cdc7ff1bb39b325f9c82cc972361780a6e1" "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum awc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5e995283278dd3bf0449e7534e77184adb1570c0de8b6a50bf7c9d01ad8db8c4" "checksum awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7601d4d1d7ef2335d6597a41b5fe069f6ab799b85f53565ab390e7b7065aac5" -"checksum backtrace 0.3.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b4b1549d804b6c73f4817df2ba073709e96e426f12987127c48e6745568c350b" +"checksum backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" @@ -3546,10 +3568,10 @@ dependencies = [ "checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" "checksum brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" "checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -"checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" -"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +"checksum bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" +"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" +"checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" "checksum bytestring 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fc267467f58ef6cc8874064c62a0423eb0d099362c8a23edd1c6d044f46eead4" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" "checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" @@ -3579,7 +3601,7 @@ dependencies = [ "checksum darling_core 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" "checksum darling_macro 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" "checksum deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "38ce52b0b1ad88ed0b2be2bc3c65ad39dd1a5d9633b1a8a314fc017fbe0027d2" -"checksum deadpool-redis 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "061442c74bf11e8a19ddca0ea9bf46a2590f854df98e9830447601be097b8fe4" +"checksum deadpool-redis 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7655c3211e78315e7ee4b1ed8ce4a6fce0509deb4da8562dfb20d5fdfd4ad85c" "checksum derive_builder 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" "checksum derive_builder_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" "checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839" @@ -3591,7 +3613,7 @@ dependencies = [ "checksum dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d0a1279c96732bc6800ce6337b6a614697b0e74ae058dc03c62ebeb78b4d86" "checksum dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" "checksum downcast 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d" -"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" +"checksum dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28" "checksum enum-as-inner 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d58266c97445680766be408285e798d3401c6d4c378ec5552e78737e681e37d" @@ -3606,15 +3628,15 @@ dependencies = [ "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" -"checksum futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" -"checksum futures-channel 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" -"checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" -"checksum futures-executor 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" -"checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" -"checksum futures-macro 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52e7c56c15537adb4f76d0b7a76ad131cb4d2f4f32d3b0bcabcbe1c7c5e87764" -"checksum futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" -"checksum futures-task 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0bae52d6b29cf440e298856fec3965ee6fa71b06aa7495178615953fd669e5f9" -"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" +"checksum futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780" +"checksum futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8" +"checksum futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" +"checksum futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba" +"checksum futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" +"checksum futures-macro 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" +"checksum futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6" +"checksum futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" +"checksum futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" @@ -3636,10 +3658,10 @@ dependencies = [ "checksum ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" -"checksum indexmap 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" +"checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f" -"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" "checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" @@ -3660,7 +3682,7 @@ dependencies = [ "checksum memory_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" "checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" "checksum miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" -"checksum miniz_oxide 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6f3f74f726ae935c3f514300cc6773a0c9492abc5e972d42ba0c0ebb88757625" +"checksum miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" @@ -3685,8 +3707,8 @@ dependencies = [ "checksum parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -"checksum pin-project 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "75fca1c4ff21f60ca2d37b80d72b63dab823a9d19d3cda3a81d18bc03f0ba8c5" -"checksum pin-project-internal 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6544cd4e4ecace61075a6ec78074beeef98d58aa9a3d07d053d993b2946a90d6" +"checksum pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" +"checksum pin-project-internal 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" "checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" @@ -3722,11 +3744,11 @@ dependencies = [ "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redis 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d69c054daeca01bc1bee4af75b04dffa3458d6702cb7a74c2f38518c130fb624" +"checksum redis 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb1fe3fc011cde97315f370bc88e4db3c23b08709a04915921e02b1d363b20" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" -"checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87" -"checksum regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e734e891f5b408a29efbf8309e656876276f49ab6a6ac208600b4419bd893d90" +"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb" "checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" @@ -3744,26 +3766,25 @@ dependencies = [ "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde-hjson 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" +"checksum serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "15913895b61e0be854afd32fd4163fcd2a3df34142cf2cb961b310ce694cbf90" "checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" "checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" "checksum serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f74862f16557830c73deefde614c906f8af0157e064b64f156e32a0b12d7114c" "checksum serial_test_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c188479c8b700998829c168d7a4c21032660b0dd2ed87a0b166c85811750740" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum signal-hook 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "7a9c17dd3ba2d36023a5c9472ecddeda07e27fd0b05436e8c1e0c8f178185652" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99" -"checksum slog-async 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e544d16c6b230d84c866662fe55e31aacfca6ae71e6fc49ae9a311cb379bfc2f" +"checksum slog-async 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "78ca925b180da88ccc595cbe4a3d378d79cb49fe5906c2cbc2488eaf700913ee" "checksum slog-envlogger 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "906a1a0bc43fed692df4b82a5e2fbfc3733db8dad8bb514ab27a4f23ad04f5c0" "checksum slog-json 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc0d2aff1f8f325ef660d9a0eb6e6dcd20b30b3f581a5897f58bf42d061c37a" "checksum slog-scope 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c44c89dd8b0ae4537d1ae318353eaf7840b4869c536e31c41e963d1ea523ee6" "checksum slog-stdlog 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f1c469573d1e3f36f9eee66cd132206caf47b50c94b1f6c6e7b4d8235e9ecf01" "checksum slog-stdlog 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "be4d87903baf655da2d82bc3ac3f7ef43868c58bf712b3a661fda72009304c23" -"checksum slog-term 2.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54b50e85b73c2bd42ceb97b6ded235576d405bd1e974242ccfe634fa269f6da7" +"checksum slog-term 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "124501187c410b6a46fe8a47a48435ae462fae4e02d03c558d358f40b17308cb" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" -"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" +"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" "checksum smart-default 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" @@ -3778,21 +3799,22 @@ dependencies = [ "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum term 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tokio 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c1fc73332507b971a5010664991a441b5ee0de92017f5a0e8b00fd684573045b" -"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" -"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" -"checksum tokio-executor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" -"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -"checksum tokio-reactor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "6732fe6b53c8d11178dcb77ac6d9682af27fc6d4cb87789449152e5377377146" -"checksum tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd6dc5276ea05ce379a16de90083ec80836440d5ef8a6a39545a3207373b8296" -"checksum tokio-sync 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" -"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-timer 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1739638e364e558128461fc1ad84d997702c8e31c2e6b18fb99842268199e827" -"checksum tokio-udp 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" +"checksum tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" +"checksum tokio-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "25b2998660ba0e70d18684de5d06b70b70a3a747469af9dea7618cc59e75976b" +"checksum tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" +"checksum tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" +"checksum tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" +"checksum tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" +"checksum tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" +"checksum tokio-signal 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c34c6e548f101053321cba3da7cbb87a610b85555884c41b07da2eb91aff12" +"checksum tokio-sync 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" +"checksum tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" +"checksum tokio-test 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09cf9705471976fa5fc6817d3fbc9c4ff9696a6647af0e5c1870c81ca7445b05" +"checksum tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" +"checksum tokio-udp 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a0b10e610b39c38b031a2fcab08e4b82f16ece36504988dcbd81dbba650d82" "checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" "checksum tracerr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64ee75bed80b548ecaede0ed297636fa16e05d7407aefdc64cb214ad3b8ebd53" diff --git a/Cargo.toml b/Cargo.toml index ac67ac4d8..31797e511 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ include = ["/src/", "/Cargo.*", "/CHANGELOG.md", "/LICENSE.md", "/README.md"] [workspace] members = [ "crates/medea-macro", + "crates/coturn-telnet", "jason", "mock/control-api", "proto/client-api", @@ -32,6 +33,7 @@ actix-web-actors = "2.0" async-trait = "0.1" chrono = "0.4" config = "0.10" +coturn-telnet = {path = "crates/coturn-telnet"} deadpool = "0.5" deadpool-redis = "0.5" derive_more = "0.99" @@ -45,7 +47,7 @@ medea-control-api-proto = { path = "proto/control-api" } medea-macro = { path = "crates/medea-macro" } protobuf = "2.7" rand = "0.7" -redis = "0.14" +redis = "0.15" rust-crypto = "0.2" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/Dockerfile b/Dockerfile index 24e4a87dc..644ca68d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,6 +26,7 @@ RUN apt-get update \ # Prepare Cargo workspace for building dependencies only. COPY crates/medea-macro/Cargo.toml /app/crates/medea-macro/ +COPY crates/coturn-telnet/Cargo.toml /app/crates/coturn-telnet/ COPY mock/control-api/Cargo.toml /app/mock/control-api/ COPY proto/client-api/Cargo.toml /app/proto/client-api/ COPY proto/control-api/Cargo.toml /app/proto/control-api/ @@ -38,6 +39,7 @@ COPY jason/Cargo.toml /app/jason/ COPY Cargo.toml Cargo.lock /app/ WORKDIR /app/ RUN mkdir -p crates/medea-macro/src/ && touch crates/medea-macro/src/lib.rs \ + && mkdir -p crates/coturn-telnet/src/ && touch crates/coturn-telnet/src/lib.rs \ && mkdir -p mock/control-api/src/ && touch mock/control-api/src/lib.rs \ && mkdir -p proto/client-api/src/ && touch proto/client-api/src/lib.rs \ && mkdir -p proto/control-api/src/ && touch proto/control-api/src/lib.rs \ diff --git a/_dev/coturn/turnserver.conf b/_dev/coturn/turnserver.conf index 699ac5315..47082fe91 100644 --- a/_dev/coturn/turnserver.conf +++ b/_dev/coturn/turnserver.conf @@ -1,8 +1,8 @@ lt-cred-mech fingerprint -no-cli no-tls no-dtls realm=medea redis-userdb="ip=127.0.0.1 port=6379 dbname=0 password=turn" user=USER:PASS +cli-password=turn diff --git a/config.toml b/config.toml index c45967be7..d4175eee1 100644 --- a/config.toml +++ b/config.toml @@ -125,6 +125,24 @@ # Default: # connection_timeout = "5s" +[turn.cli] +# Coturn server host. +# +# Env var: MEDEA_TURN__CLI__HOST +# Default: +# host = "127.0.0.1" + +# Port of Coturn's Redis database for client connections. +# +# Env var: MEDEA_TURN__CLI__PORT +# Default: +# port = 5766 + +# Port of Coturn's Redis database for client connections. +# +# Env var: MEDEA_TURN__CLI__PASS +# Default: +# pass = "turn" diff --git a/crates/coturn-telnet/CHANGELOG.md b/crates/coturn-telnet/CHANGELOG.md new file mode 100644 index 000000000..6421f07f6 --- /dev/null +++ b/crates/coturn-telnet/CHANGELOG.md @@ -0,0 +1,26 @@ +`coturn-telnet` changelog +======================= + +All user visible changes to this project will be documented in this file. This project uses [Semantic Versioning 2.0.0]. + + + + +## TBD [0.1.0] · 2019-??-?? +[0.1.0]: /../../tree/coturn-telnet-0.1.0/crates/coturn-telnet + +### Added + +- Asynchronous [Coturn] client. +- Connection pool. +- Requests: + - `ps [username]`, that prints sessions, with optional exact user match. + - `cs `, that forcefully cancels session. + + + + + + +[Semantic Versioning 2.0.0]: https://semver.org +[Coturn]: https://github.com/coturn/coturn diff --git a/crates/coturn-telnet/Cargo.toml b/crates/coturn-telnet/Cargo.toml new file mode 100644 index 000000000..03f768a3b --- /dev/null +++ b/crates/coturn-telnet/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "coturn-telnet" +version = "0.1.0-dev" +edition = "2018" +description = "Coturn TURN server telnet cli client" +authors = ["Instrumentisto Team "] +license = "MIT/Apache-2.0" +documentation = "https://docs.rs/coturn-telnet" +homepage = "https://github.com/instrumentisto/medea/tree/master/crates/coturn-telnet" +repository = "https://github.com/instrumentisto/medea/tree/master/crates/coturn-telnet" +readme = "README.md" +keywords = ["coturn", "telnet", "cli"] +categories = ["web-programming"] + +[dependencies] +async-trait = "0.1" +bytes = "0.5" +deadpool = "0.5" +derive_more = "0.99" +futures = "0.3" +lazy_static = "1.4" +regex = "1.3" +tokio = { version = "0.2", features = ["dns", "macros"] } +tokio-util = { version = "0.2", features = ["codec"] } + +[dev-dependencies] +tokio-test = "0.2" diff --git a/crates/coturn-telnet/LICENSE-APACHE.md b/crates/coturn-telnet/LICENSE-APACHE.md new file mode 100644 index 000000000..24e951b55 --- /dev/null +++ b/crates/coturn-telnet/LICENSE-APACHE.md @@ -0,0 +1,194 @@ +Apache License +============== + +_Version 2.0, January 2004_ +_<>_ + +### Terms and Conditions for use, reproduction, and distribution + +#### 1. Definitions + +“License” shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +“Licensor” shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +“Legal Entity” shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, “control” means **(i)** the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the +outstanding shares, or **(iii)** beneficial ownership of such entity. + +“You” (or “Your”) shall mean an individual or Legal Entity exercising +permissions granted by this License. + +“Source” form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +“Object” form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +“Work” shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +“Derivative Works” shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +“Contribution” shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +“submitted” means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as “Not a Contribution.” + +“Contributor” shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +#### 2. Grant of Copyright License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +#### 3. Grant of Patent License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +#### 4. Redistribution + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +* **(a)** You must give any other recipients of the Work or Derivative Works a copy of +this License; and +* **(b)** You must cause any modified files to carry prominent notices stating that You +changed the files; and +* **(c)** You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. + +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +#### 5. Submission of Contributions + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +#### 6. Trademarks + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +#### 7. Disclaimer of Warranty + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +#### 8. Limitation of Liability + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +#### 9. Accepting Warranty or Additional Liability + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +_END OF TERMS AND CONDITIONS_ + +### APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets `[]` replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same “printed page” as the copyright notice for easier identification within +third-party archives. + + Copyright © 2019 Instrumentisto Team, https://github.com/instrumentisto + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/crates/coturn-telnet/LICENSE-MIT.md b/crates/coturn-telnet/LICENSE-MIT.md new file mode 100644 index 000000000..8852bcc25 --- /dev/null +++ b/crates/coturn-telnet/LICENSE-MIT.md @@ -0,0 +1,25 @@ +The MIT License (MIT) +===================== + +Copyright © 2019 Instrumentisto Team, https://github.com/instrumentisto + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the “Software”), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/crates/coturn-telnet/README.md b/crates/coturn-telnet/README.md new file mode 100644 index 000000000..3411b4d2b --- /dev/null +++ b/crates/coturn-telnet/README.md @@ -0,0 +1,33 @@ +coturn-telnet +=========== + +[![Crates.io](https://img.shields.io/crates/v/coturn-telnet)](https://crates.io/crates/coturn-telnet) +![Crates.io license](https://img.shields.io/crates/l/coturn-telnet) + +[API Docs](https://docs.rs/coturn-telnet) | +[Changelog](https://github.com/instrumentisto/medea/blob/master/crates/coturn-telnet/CHANGELOG.md) + +[Coturn] telnet cli client implementation. + + + + +## License + +This project is licensed under either of + +- Apache License, Version 2.0, ([LICENSE-APACHE](https://github.com/instrumentisto/medea/blob/master/crates/coturn-telnet/LICENSE-APACHE.md) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](https://github.com/instrumentisto/medea/blob/master/crates/coturn-telnet/LICENSE-MIT.md) or http://opensource.org/licenses/MIT) + +at your option. + + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + + + + + +[Coturn]: https://github.com/coturn/coturn diff --git a/crates/coturn-telnet/src/codec.rs b/crates/coturn-telnet/src/codec.rs new file mode 100644 index 000000000..2420d585f --- /dev/null +++ b/crates/coturn-telnet/src/codec.rs @@ -0,0 +1,292 @@ +//! Contains definitions for messages sent to [Coturn] server telnet interface +//! [`CoturnCliRequest`], messages received from Coturn server telnet interface: +//! [`CoturnCliResponse`]. [`CoturnCliCodec`] which encodes and decodes those +//! messages. +//! +//! [Coturn]: https://github.com/coturn/coturn + +use std::{ + convert::TryFrom, + io, + str::{from_utf8, Utf8Error}, +}; + +use bytes::{BufMut as _, Bytes, BytesMut}; +use regex::Regex; +use tokio_util::codec::{Decoder, Encoder}; + +// Cursor is received when telnet server has finished writing response and is +// ready to receive new requests. +static CURSOR: &str = "> "; + +// Received when telnet server awaits for password. +static NEED_PASS: &str = "Enter password: \r\n"; + +/// Received when telnet server did not recognized last command. +static UNKNOWN_COMMAND: &str = "Unknown command\r\n\r\n"; + +lazy_static::lazy_static! { + // Used to check is message can be parsed to CoturnCliResponse::Sessions. + static ref IS_SESSIONS_REGEX: Regex = + Regex::new(r#"Total sessions: \d"#).unwrap(); + + // Used to extract session ids from CoturnCliResponse::Sessions. + static ref EXTRACT_SESSIONS_REGEX: Regex = + Regex::new(r"\d\) id=(.*),").unwrap(); +} + +/// Messages that can be received from Coturn telnet server. +#[derive(Clone, Debug, PartialEq)] +pub enum CoturnCliResponse { + /// Current telnet connection requires authentication. Next message sent to + /// server should be [`CoturnCliRequest::Auth`]. + EnterPassword, + + /// Coturn server finished processing latest telnet request and is ready to + /// accept next. You should wait for this message after sending request + /// to make sure that request succeeded. + Ready, + + /// Answer to [`CoturnCliRequest::PrintSessions`], contains list of session + /// ids associated with username provided in + /// [`CoturnCliRequest::PrintSessions`] message. + Sessions(Vec), + + /// Coturn telnet server did not recognized last command. + UnknownCommand, +} + +/// Errors that can happen when parsing message received from Coturn via telnet +/// connection. +#[derive(Debug)] +pub enum CoturnResponseParseError { + /// Could not represent byte slice as `String`. + BadString(Utf8Error), + + /// Could not determine concrete response type. + CannotDetermineResponseType(String), + + /// Could not parse provided bytes to determined response type. + BadResponseFormat(String), +} + +impl TryFrom for CoturnCliResponse { + type Error = CoturnResponseParseError; + + fn try_from(mut msg: BytesMut) -> Result { + // delete cursor if message ends with it + if msg.ends_with(CURSOR.as_bytes()) { + msg.truncate(msg.len() - CURSOR.as_bytes().len()); + } + + let msg = + from_utf8(&msg).map_err(CoturnResponseParseError::BadString)?; + + if msg.is_empty() { + return Ok(CoturnCliResponse::Ready); + } + + if msg.ends_with(NEED_PASS) { + return Ok(CoturnCliResponse::EnterPassword); + } + + if msg.ends_with(UNKNOWN_COMMAND) { + return Ok(CoturnCliResponse::UnknownCommand); + } + + if IS_SESSIONS_REGEX.is_match(msg) { + let mut session_ids: Vec = Vec::new(); + for mat in EXTRACT_SESSIONS_REGEX.captures_iter(msg) { + if let Some(id) = mat.get(1) { + session_ids.push(id.as_str().to_owned()); + } else { + return Err(CoturnResponseParseError::BadResponseFormat( + msg.to_owned(), + )); + } + } + return Ok(CoturnCliResponse::Sessions(session_ids)); + } + + Err(CoturnResponseParseError::CannotDetermineResponseType( + msg.to_owned(), + )) + } +} + +/// Messages that can be sent to Coturn telnet client. +pub enum CoturnCliRequest { + /// Request to authenticate. Contains password. Should be sent when + /// [`CoturnCliResponse::EnterPassword`] is received. + Auth(Bytes), + + /// Get Coturn session ids by username. + PrintSessions(String), + + /// Close Coturn session by its id. + CloseSession(String), + + /// Ping + Ping, +} + +impl Into for CoturnCliRequest { + fn into(self) -> Bytes { + match self { + CoturnCliRequest::Auth(pass) => pass, + CoturnCliRequest::PrintSessions(username) => { + format!("ps {}", username).into() + } + CoturnCliRequest::CloseSession(session_id) => { + format!("cs {}", session_id).into() + } + CoturnCliRequest::Ping => "ping".into(), + } + } +} + +#[derive(Debug)] +pub enum CoturnCliCodecError { + IoError(io::Error), + CannotParseResponse(CoturnResponseParseError), +} + +impl From for CoturnCliCodecError { + fn from(err: io::Error) -> Self { + CoturnCliCodecError::IoError(err) + } +} + +impl From for CoturnCliCodecError { + fn from(err: CoturnResponseParseError) -> Self { + CoturnCliCodecError::CannotParseResponse(err) + } +} + +/// Adapter that encodes requests and decodes responses received from or sent to +/// [Coturn] server telnet interface. +/// +/// [Coturn]: https://github.com/coturn/coturn +#[derive(Default)] +pub struct CoturnCliCodec; + +impl Decoder for CoturnCliCodec { + type Error = CoturnCliCodecError; + type Item = CoturnCliResponse; + + fn decode( + &mut self, + src: &mut BytesMut, + ) -> Result, Self::Error> { + if src.ends_with(CURSOR.as_bytes()) { + let frame = CoturnCliResponse::try_from(src.split())?; + Ok(Some(frame)) + } else if src.ends_with(NEED_PASS.as_bytes()) { + src.clear(); + Ok(Some(CoturnCliResponse::EnterPassword)) + } else { + Ok(None) + } + } +} + +impl Encoder for CoturnCliCodec { + type Error = io::Error; + type Item = CoturnCliRequest; + + fn encode( + &mut self, + item: Self::Item, + dst: &mut BytesMut, + ) -> Result<(), Self::Error> { + let item: Bytes = item.into(); + dst.reserve(item.len()); + dst.put(item); + Ok(()) + } +} + +#[cfg(test)] +mod test { + + use bytes::BytesMut; + + use super::*; + + #[tokio::test] + async fn parse_greeting() { + let mut codec = CoturnCliCodec::default(); + let mut greeting: BytesMut = "TURN Server\r\nCoturn-4.5.1.1 'dan \ + Eider'\r\n\r\nType '?' for \ + help\r\nEnter password: \r\n" + .into(); + + assert_eq!( + codec.decode(&mut greeting).unwrap().unwrap(), + CoturnCliResponse::EnterPassword + ); + } + + #[tokio::test] + async fn parse_empty_sessions() { + let mut codec = CoturnCliCodec::default(); + let mut greeting = "\r\n Total sessions: 0\r\n\r\n> ".into(); + + match codec.decode(&mut greeting).unwrap().unwrap() { + CoturnCliResponse::Sessions(sessions) => { + assert!(sessions.is_empty()); + } + _ => unreachable!(), + } + } + + #[tokio::test] + async fn parse_sessions() { + let mut codec = CoturnCliCodec::default(); + let mut greeting = "\r\n 1) id=007000000000000001, user + :\r\n realm: medea\r\n started 49 secs ago\r\n + expiring in 551 secs\r\n client protocol UDP, relay protocol + UDP\r\n client addr 192.168.31.183:39514, server addr + 127.0.0.1:3478\r\n relay addr 127.0.0.1:55869\r\n + fingerprints enforced: OFF\r\n mobile: OFF\r\n usage: rp=6, + rb=480, sp=4, sb=440\r\n rate: r=0, s=0, total=0 (bytes per + sec)\r\n\r\n 2) id=010000000000000002, user :\r\n + realm: medea\r\n started 49 secs ago\r\n expiring in 551 + secs\r\n client protocol TCP, relay protocol UDP\r\n client + addr [::1]:33710, server addr [::1]:3478\r\n relay addr + [::1]:60216\r\n fingerprints enforced: OFF\r\n mobile: + OFF\r\n usage: rp=4, rb=348, sp=3, sb=336\r\n rate: r=0, + s=0, total=0 (bytes per sec)\r\n peers:\r\n ::1\r\n\r\n + 3) id=000000000000000001, user :\r\n realm: medea\r\n + started 49 secs ago\r\n expiring in 551 secs\r\n client + protocol UDP, relay protocol UDP\r\n client addr + 192.168.31.183:59996, server addr 127.0.0.1:3478\r\n relay addr + 127.0.0.1:54289\r\n fingerprints enforced: OFF\r\n mobile: + OFF\r\n usage: rp=5, rb=344, sp=4, sb=440\r\n rate: r=0, + s=0, total=0 (bytes per sec)\r\n\r\n 4) id=005000000000000001, + user :\r\n realm: medea\r\n started 49 secs + ago\r\n expiring in 551 secs\r\n client protocol TCP, relay + protocol UDP\r\n client addr [::1]:33712, server addr + [::1]:3478\r\n relay addr [::1]:52934\r\n fingerprints + enforced: OFF\r\n mobile: OFF\r\n usage: rp=12288, + rb=10012764, sp=12288, sb=10022892\r\n rate: r=222505, + s=222730, total=445235 (bytes per sec)\r\n peers:\r\n + ::1\r\n [::1]:62869\r\n\r\n Total sessions: 4\r\n\r\n> " + .into(); + + match codec.decode(&mut greeting).unwrap().unwrap() { + CoturnCliResponse::Sessions(sessions) => { + assert_eq!( + sessions, + vec![ + "007000000000000001", + "010000000000000002", + "000000000000000001", + "005000000000000001" + ] + ); + } + _ => unreachable!(), + } + } +} diff --git a/crates/coturn-telnet/src/connection.rs b/crates/coturn-telnet/src/connection.rs new file mode 100644 index 000000000..9ad42dc97 --- /dev/null +++ b/crates/coturn-telnet/src/connection.rs @@ -0,0 +1,186 @@ +//! Contains [`CoturnTelnetConnection`]. + +use std::io; + +use bytes::Bytes; +use futures::{SinkExt, StreamExt}; +use tokio::net::{TcpStream, ToSocketAddrs}; +use tokio_util::codec::Framed; + +use crate::codec::{ + CoturnCliCodec, CoturnCliCodecError, CoturnCliRequest, CoturnCliResponse, + CoturnResponseParseError, +}; + +#[derive(Debug, derive_more::Display, derive_more::From)] +pub enum CoturnTelnetError { + /// Underlying transport encountered [`io::Error`]. You should try + /// recreating [`CoturnTelnetClient`]. + #[display(fmt = "Underlying transport encountered IoError: {}", _0)] + IoError(io::Error), + /// Underlying stream exhausted. You should try recreating + /// [`CoturnTelnetClient`]. + #[display(fmt = "Disconnected from Coturn telnet server")] + Disconnected, + /// Unable to parse response from Coturn telnet server. This is + /// unrecoverable error. + #[display(fmt = "Unable to parse Coturn response: {:?}", _0)] + MessageParseError(CoturnResponseParseError), + /// Coturn answered with unexpected message. This is unrecoverable error. + #[display(fmt = "Unexpected response received {:?}", _0)] + UnexpectedMessage(CoturnCliResponse), + /// Authentication failed. This is unrecoverable error. + #[display(fmt = "Coturn server rejected provided password")] + WrongPassword, +} + +impl From for CoturnTelnetError { + fn from(err: CoturnCliCodecError) -> Self { + match err { + CoturnCliCodecError::IoError(err) => Self::from(err), + CoturnCliCodecError::CannotParseResponse(err) => Self::from(err), + } + } +} + +/// Asynchronous connection to remote [Coturn] server telnet interface. You can +/// use this directly, but it is recommended to use this with connection pool +/// from `crate::pool`, which takes care of connection life cycle. +/// +/// [Coturn]: https://github.com/coturn/coturn. +pub struct CoturnTelnetConnection(Framed); + +impl CoturnTelnetConnection { + /// Opens a telnet connection to a remote host using a `TcpStream` and + /// performs authentication. + pub async fn connect>( + addr: A, + pass: B, + ) -> Result { + let stream = TcpStream::connect(addr).await?; + let mut this = Self(Framed::new(stream, CoturnCliCodec::default())); + this.auth(pass.into()).await?; + + Ok(this) + } + + /// Returns session ids associated with provided username. + /// + /// 1. Sends [`CoturnTelnetClientError::PrintSessions`] with provided + /// username. + /// 2. Awaits for [`CoturnCliResponse::Sessions`]. + pub async fn print_sessions( + &mut self, + username: String, + ) -> Result, CoturnTelnetError> { + // Send `CoturnCliRequest::PrintSessions`. + self.0 + .send(CoturnCliRequest::PrintSessions(username)) + .await?; + + // Await for `CoturnCliResponse::Sessions`. + let response: CoturnCliResponse = self + .0 + .next() + .await + .ok_or_else(|| CoturnTelnetError::Disconnected)??; + match response { + CoturnCliResponse::Sessions(sessions) => Ok(sessions), + _ => Err(CoturnTelnetError::UnexpectedMessage(response)), + } + } + + /// Closes session on Coturn server destroying this session allocations and + /// channels. + /// + /// 1. Sends [`CoturnCliRequest::CloseSession`] with specified session id. + /// 2. Awaits for [`CoturnCliResponse::Ready`]. + pub async fn delete_session( + &mut self, + session_id: String, + ) -> Result<(), CoturnTelnetError> { + self.0 + .send(CoturnCliRequest::CloseSession(session_id)) + .await?; + + // Await for `CoturnCliResponse::Ready`. + let response: CoturnCliResponse = self + .0 + .next() + .await + .ok_or_else(|| CoturnTelnetError::Disconnected)??; + match response { + CoturnCliResponse::Ready => Ok(()), + _ => Err(CoturnTelnetError::UnexpectedMessage(response)), + } + } + + /// Closes sessions on Coturn server destroying provided sessions + /// allocations and channels. + /// + /// For each provided session id: + /// 1. Sends [`CoturnCliRequest::CloseSession`] with specified session id. + /// 2. Awaits for [`CoturnCliResponse::Ready`]. + pub async fn delete_sessions>( + &mut self, + session_ids: T, + ) -> Result<(), CoturnTelnetError> { + for session_id in session_ids { + self.delete_session(session_id).await?; + } + Ok(()) + } + + /// Authenticates [`CoturnTelnetClient`]. + /// + /// 1. Awaits for [`CoturnCliResponse::EnterPassword`]. + /// 2. Sends [`CoturnCliRequest::Auth`]. + /// 3. Awaits for [`CoturnCliResponse::Ready`]. + async fn auth(&mut self, pass: Bytes) -> Result<(), CoturnTelnetError> { + // Wait for `CoturnCliResponse::EnterPassword`; + let response = self + .0 + .next() + .await + .ok_or_else(|| CoturnTelnetError::Disconnected)??; + + if let CoturnCliResponse::EnterPassword = response { + } else { + return Err(CoturnTelnetError::UnexpectedMessage(response)); + }; + + // Send `CoturnCliRequest::Auth` with provided password. + self.0.send(CoturnCliRequest::Auth(pass)).await?; + + // Wait for `CoturnCliResponse::Ready`. + let response = self + .0 + .next() + .await + .ok_or_else(|| CoturnTelnetError::Disconnected)??; + match response { + CoturnCliResponse::EnterPassword => { + Err(CoturnTelnetError::WrongPassword) + } + CoturnCliResponse::Ready => Ok(()), + _ => Err(CoturnTelnetError::UnexpectedMessage(response)), + } + } + + /// Pings Coturn telnet server. + pub async fn ping(&mut self) -> Result<(), CoturnTelnetError> { + self.0.send(CoturnCliRequest::Ping).await?; + + let response: CoturnCliResponse = self + .0 + .next() + .await + .ok_or_else(|| CoturnTelnetError::Disconnected)??; + if let CoturnCliResponse::UnknownCommand = response { + } else { + return Err(CoturnTelnetError::UnexpectedMessage(response)); + }; + + Ok(()) + } +} diff --git a/crates/coturn-telnet/src/lib.rs b/crates/coturn-telnet/src/lib.rs new file mode 100644 index 000000000..321641c49 --- /dev/null +++ b/crates/coturn-telnet/src/lib.rs @@ -0,0 +1,8 @@ +#![allow(clippy::module_name_repetitions)] + +mod codec; +mod connection; +mod pool; + +pub use connection::{CoturnTelnetConnection, CoturnTelnetError}; +pub use pool::{Connection, Manager, Pool, PoolError}; diff --git a/crates/coturn-telnet/src/pool.rs b/crates/coturn-telnet/src/pool.rs new file mode 100644 index 000000000..5a7795d9b --- /dev/null +++ b/crates/coturn-telnet/src/pool.rs @@ -0,0 +1,79 @@ +//! Deadpool simple async pool for [`CoturnTelnetConnection`]'s. +//! +//! You should not need to use `deadpool` directly. Use the `Pool` type +//! provided by this crate instead. +//! +//! # Example +//! +//! ```rust +//! use coturn_telnet::{Manager, Pool}; +//! +//! let mgr = Manager::new((String::from("localhost", 5766)), "turn") +//! .unwrap(); +//! let pool = Pool::new(mgr, 16); +//! let mut conn = pool.get().await.unwrap(); +//! +//! conn.deref_mut() +//! .print_sessions(String::from("username")) +//! .await +//! .unwrap(); +//! ``` + +use async_trait::async_trait; +use bytes::Bytes; + +use crate::connection::{CoturnTelnetConnection, CoturnTelnetError}; + +/// A type alias for using [`deadpool::managed::Pool`] with +/// [`CoturnTelnetConnection`]. +pub type Pool = + deadpool::managed::Pool; + +/// A type alias for using [`deadpool::managed::PoolError`] with +/// [`CoturnTelnetConnection`]. +pub type PoolError = deadpool::managed::PoolError; + +/// A type alias for using [`deadpool::managed::Object`] with +/// [`CoturnTelnetConnection`]. +pub type Connection = + deadpool::managed::Object; + +type RecycleResult = deadpool::managed::RecycleResult; + +/// The manager for creating and recycling Coturn telnet connections +pub struct Manager { + addr: (String, u16), + pass: Bytes, +} + +impl Manager { + pub fn new>(addr: (String, u16), pass: P) -> Self { + Self { + addr, + pass: pass.into(), + } + } +} + +#[async_trait] +impl deadpool::managed::Manager + for Manager +{ + async fn create( + &self, + ) -> Result { + let connection = CoturnTelnetConnection::connect( + (self.addr.0.as_str(), self.addr.1), + self.pass.clone(), + ) + .await?; + Ok(connection) + } + + async fn recycle( + &self, + connection: &mut CoturnTelnetConnection, + ) -> RecycleResult { + connection.ping().await.map_err(From::from) + } +} diff --git a/jason/demo/index.html b/jason/demo/index.html index b73503ae1..0be70f5eb 100644 --- a/jason/demo/index.html +++ b/jason/demo/index.html @@ -17,6 +17,7 @@ let inited = false; const controlUrl = document.location.protocol + "//" + document.location.host + "/control-api/"; + var isForceRelay = false; async function createRoom(roomId) { try { @@ -40,7 +41,7 @@ publish: { kind: 'WebRtcPublishEndpoint', p2p: 'Always', - force_relay: false, + force_relay: isForceRelay, }, }; @@ -52,6 +53,7 @@ pipeline["play-" + memberId] = { kind: 'WebRtcPlayEndpoint', src: 'local://' + roomId + '/' + memberId + "/publish", + force_relay: isForceRelay, }; } @@ -73,6 +75,7 @@ data: { kind: 'WebRtcPlayEndpoint', src: 'local://' + roomId + '/' + memberId + '/publish', + force_relay: controlRoom.data.element.pipeline[id].pipeline.publish.force_relay, } }) } @@ -154,6 +157,7 @@ let audioSelect = document.getElementById('connect__select-device_audio'); let videoSelect = document.getElementById('connect__select-device_video'); let localVideo = document.getElementById('local-video__video'); + let isForceRelayCheckbox = document.getElementById("is_force_relay"); let joinCallerButton = document.getElementById('join__join'); let usernameInput = document.getElementById('join__username'); @@ -266,6 +270,9 @@ connectBtnsDiv.style.display = 'none'; controlBtns.style.display = 'block'; + isForceRelay = isForceRelayCheckbox.checked; + isForceRelayCheckbox.disabled = true; + try { let username = usernameInput.value; try { @@ -390,6 +397,11 @@ Closed +
+ + +
+ diff --git a/jason/e2e-demo/js/index.js b/jason/e2e-demo/js/index.js index 3e2a5b09f..6250d3663 100644 --- a/jason/e2e-demo/js/index.js +++ b/jason/e2e-demo/js/index.js @@ -49,7 +49,8 @@ async function createMember(roomId, memberId) { memberIds.push(memberId); pipeline["play-" + memberId] = { kind: 'WebRtcPlayEndpoint', - src: 'local://' + roomId + '/' + memberId + "/publish" + src: 'local://' + roomId + '/' + memberId + "/publish", + force_relay: false } } @@ -73,7 +74,8 @@ async function createMember(roomId, memberId) { url: controlUrl + roomId + "/" + id + '/' + 'play-' + memberId, data: { kind: 'WebRtcPlayEndpoint', - src: 'local://' + roomId + '/' + memberId + '/publish' + src: 'local://' + roomId + '/' + memberId + '/publish', + force_relay: false } }) } diff --git a/jason/src/lib.rs b/jason/src/lib.rs index 6dce1acde..f83a24a1b 100644 --- a/jason/src/lib.rs +++ b/jason/src/lib.rs @@ -7,6 +7,8 @@ #![allow(clippy::module_name_repetitions, clippy::must_use_candidate)] #![cfg_attr(not(feature = "mockable"), warn(missing_docs))] #![cfg_attr(feature = "mockable", allow(missing_docs))] +// TODO: REVERT ME BEFORE MERGE!!! +#![allow(clippy::missing_errors_doc)] #[macro_use] pub mod utils; diff --git a/jason/src/peer/media.rs b/jason/src/peer/media.rs index 2bc2feee6..209f207fb 100644 --- a/jason/src/peer/media.rs +++ b/jason/src/peer/media.rs @@ -139,8 +139,7 @@ impl MediaConnections { self.0 .borrow() .iter_senders_with_kind(TransceiverKind::Audio) - .skip_while(|s| s.is_track_enabled()) - .next() + .find(|s| !s.is_track_enabled()) .is_none() } @@ -150,8 +149,7 @@ impl MediaConnections { self.0 .borrow() .iter_senders_with_kind(TransceiverKind::Video) - .skip_while(|s| s.is_track_enabled()) - .next() + .find(|s| !s.is_track_enabled()) .is_none() } @@ -497,6 +495,6 @@ impl Receiver { if self.mid.is_none() && self.transceiver.is_some() { self.mid = self.transceiver.as_ref().unwrap().mid() } - self.mid.as_ref().map(String::as_str) + self.mid.as_deref() } } diff --git a/proto/control-api/build.rs b/proto/control-api/build.rs index e3a4ead07..cb9b1cb9c 100644 --- a/proto/control-api/build.rs +++ b/proto/control-api/build.rs @@ -66,17 +66,14 @@ mod grpc { /// Loads [`ProtoNames`] from [`GRPC_DIR`] directory. pub fn load() -> io::Result { let proto_names = fs::read_dir(GRPC_DIR)? - .into_iter() .collect::, _>>()? .into_iter() .map(|entry| entry.path()) .filter(|path| { - path.extension() - .map(|ext| { - path.is_file() - && ext.to_string_lossy() == Cow::from("proto") - }) - .unwrap_or(false) + path.extension().map_or(false, |ext| { + path.is_file() + && ext.to_string_lossy() == Cow::from("proto") + }) }) .filter_map(|path| { path.file_stem() diff --git a/src/conf/turn.rs b/src/conf/turn.rs index 836073c60..72e4d6089 100644 --- a/src/conf/turn.rs +++ b/src/conf/turn.rs @@ -15,6 +15,8 @@ use smart_default::SmartDefault; pub struct Turn { /// Database settings pub db: Db, + /// Coturn cli connection settings. + pub cli: CoturnCli, /// Host of STUN/TURN server. Defaults to `localhost`. #[default = "localhost"] pub host: Cow<'static, str>, @@ -69,6 +71,23 @@ pub struct Redis { pub connection_timeout: Duration, } +/// Setting of [coturn] server telnet interface. +/// +/// [coturn]: https://github.com/coturn/coturn +#[derive(Clone, Debug, Deserialize, Serialize, SmartDefault)] +#[serde(default)] +pub struct CoturnCli { + /// Coturn server IP address. Defaults to `127.0.0.1`. + #[default(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)))] + pub ip: IpAddr, + /// Coturn server port. Defaults to `5766`. + #[default = 5766] + pub port: u16, + /// Password for authorize on Coturn server telnet interface. + #[default(String::from("turn"))] + pub pass: String, +} + #[cfg(test)] mod spec { use std::{net::Ipv4Addr, time::Duration}; diff --git a/src/lib.rs b/src/lib.rs index e30354869..be1bc08b0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,8 @@ // TODO: Remove `clippy::must_use_candidate` once the issue below is resolved: // https://github.com/rust-lang/rust-clippy/issues/4779 #![allow(clippy::module_name_repetitions, clippy::must_use_candidate)] +// TODO: REVERT ME BEFORE MERGE!!! +#![allow(clippy::missing_errors_doc)] #[macro_use] pub mod utils; diff --git a/src/media/ice_user.rs b/src/media/ice_user.rs index 6832c147a..94c7680dd 100644 --- a/src/media/ice_user.rs +++ b/src/media/ice_user.rs @@ -2,17 +2,22 @@ //! //! [coturn]: https://github.com/coturn/coturn +use derive_more::{AsRef, Display, From, Into}; use medea_client_api_proto::IceServer; use crate::api::control::RoomId; +#[derive(AsRef, Clone, Debug, Display, From, Into)] +#[as_ref(forward)] +pub struct IceUsername(String); + /// Credentials on Turn server. #[derive(Clone, Debug)] pub struct IceUser { /// Address of Turn server. address: String, /// Username for authorization. - user: String, + username: IceUsername, /// Password for authorization. pass: String, /// Non static users are meant to be saved and delete from some remote @@ -31,17 +36,17 @@ impl IceUser { ) -> Self { Self { address, - user: format!("{}_{}", room_id, name), + username: IceUsername::from(format!("{}_{}", room_id, name)), pass, is_static: false, } } /// Build new static [`IceUser`]. - pub fn new(address: String, user: String, pass: String) -> Self { + pub fn new(address: String, username: String, pass: String) -> Self { Self { address, - user, + username: IceUsername(username), pass, is_static: true, } @@ -61,7 +66,7 @@ impl IceUser { ]; let turn = IceServer { urls: turn_urls, - username: Some(self.user.clone()), + username: Some(self.username.0.clone()), credential: Some(self.pass.clone()), }; vec![stun, turn] @@ -71,8 +76,8 @@ impl IceUser { &self.address } - pub fn user(&self) -> &str { - &self.user + pub fn user(&self) -> &IceUsername { + &self.username } pub fn pass(&self) -> &str { diff --git a/src/media/mod.rs b/src/media/mod.rs index fb5ced46a..a362ee1f5 100644 --- a/src/media/mod.rs +++ b/src/media/mod.rs @@ -6,7 +6,7 @@ pub mod track; #[doc(inline)] pub use self::{ - ice_user::IceUser, + ice_user::{IceUser, IceUsername}, peer::{ New, Peer, PeerError, PeerStateMachine, WaitLocalHaveRemote, WaitLocalSdp, WaitRemoteSdp, diff --git a/src/signalling/participants.rs b/src/signalling/participants.rs index 6236a5959..0ca693e8c 100644 --- a/src/signalling/participants.rs +++ b/src/signalling/participants.rs @@ -243,22 +243,29 @@ impl ParticipantService { .map(move |_| Ok(member)), )) } else { + let turn_service = self.turn_service.clone(); + let cloned_member_id = member_id.clone(); + let room_id = self.room_id.clone(); Box::new( - wrap_future(self.turn_service.create( - member_id.clone(), - self.room_id.clone(), - UnreachablePolicy::ReturnErr, - )) - .map( - |result, room: &mut Room, _| match result { + wrap_future(async move { + turn_service + .create( + cloned_member_id, + room_id, + UnreachablePolicy::ReturnErr, + ) + .await + }) + .map(move |result, room: &mut Room, _| { + match result { Ok(ice_user) => { room.members.insert_connection(member_id, conn); member.replace_ice_user(ice_user); Ok(member) } Err(e) => Err(ParticipantServiceErr::from(e)), - }, - ), + } + }), ) } } @@ -328,8 +335,10 @@ impl ParticipantService { match self.get_member_by_id(&member_id) { None => future::ok(()).boxed_local(), Some(member) => { - if let Some(ice_user) = member.take_ice_user() { - self.turn_service.delete(vec![ice_user]) + if let Some(turn_user) = member.take_ice_user() { + let turn_service = self.turn_service.clone(); + async move { turn_service.delete(&[turn_user]).await } + .boxed_local() } else { future::ok(()).boxed_local() } @@ -363,16 +372,18 @@ impl ParticipantService { )); // deleting all IceUsers - let ice_users = self + let ice_users: Vec<_> = self .members .values() .filter_map(Member::take_ice_user) .collect(); - let delete_ice_users = self - .turn_service - .delete(ice_users) - .map_err(|err| error!("Error removing IceUsers {:?}", err)); + let turn_service = self.turn_service.clone(); + let delete_ice_users = async move { + if let Err(e) = turn_service.delete(ice_users.as_slice()).await { + error!("Error removing IceUser {:?}", e) + }; + }; future::join(close_rpc_connections, delete_ice_users) .map(|_| ()) @@ -402,12 +413,12 @@ impl ParticipantService { if let Some(member) = self.members.remove(member_id) { if let Some(ice_user) = member.take_ice_user() { - wrap_future::<_, Room>( - self.turn_service - .delete(vec![ice_user]) - .map_err(|e| error!("Error removing IceUser {:?}", e)) - .map(|_| ()), - ) + let turn_service = self.turn_service.clone(); + wrap_future::<_, Room>(async move { + if let Err(e) = turn_service.delete(&[ice_user]).await { + error!("Error removing IceUser {:?}", e) + } + }) .spawn(ctx); } } diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 13c544d89..c26ff8125 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -248,7 +248,7 @@ impl Room { sdp_offer: None, tracks: sender.tracks(), ice_servers, - force_relay: sender.is_force_relayed(), + force_relay: true, }; self.peers.add_peer(sender); Ok(Box::new( @@ -812,7 +812,7 @@ impl CommandHandler for Room { sdp_offer: Some(sdp_offer), tracks: to_peer.tracks(), ice_servers, - force_relay: to_peer.is_force_relayed(), + force_relay: true, }; self.peers.add_peer(from_peer); diff --git a/src/turn/cli.rs b/src/turn/cli.rs new file mode 100644 index 000000000..9e3070964 --- /dev/null +++ b/src/turn/cli.rs @@ -0,0 +1,73 @@ +use std::{fmt, ops::DerefMut, time::Duration}; + +use coturn_telnet::{CoturnTelnetError, Manager, Pool, PoolError}; +use deadpool::managed::{PoolConfig, Timeouts}; +use derive_more::{Display, From}; +use failure::Fail; + +use crate::media::IceUser; + +#[derive(Display, Debug, Fail, From)] +pub enum CoturnCliError { + #[display(fmt = "Couldn't get connection from pool: {}", _0)] + PoolError(PoolError), + #[display(fmt = "Coturn telnet connection returned error: {}", _0)] + CliError(CoturnTelnetError), +} + +/// Abstraction over remote [Coturn] server telnet interface. +/// +/// This struct can be cloned and transferred across thread boundaries. +/// +/// [Coturn]: https://github.com/coturn/coturn +#[derive(Clone)] +pub struct CoturnTelnetClient { + pool: Pool, +} + +impl CoturnTelnetClient { + /// Creates new [`CoturnTelnetClient`]. + pub fn new( + addr: (String, u16), + pass: String, + ) -> Result { + let manager = Manager::new(addr, pass); + // TODO: to conf + let config = PoolConfig { + max_size: 16, + timeouts: Timeouts { + wait: Some(Duration::from_secs(5)), + create: Some(Duration::from_secs(5)), + recycle: Some(Duration::from_secs(5)), + }, + }; + Ok(Self { + pool: Pool::from_config(manager, config), + }) + } + + /// Forcefully closes provided [`IceUser`]s sessions on Coturn server. + pub async fn delete_sessions( + &self, + users: &[&IceUser], + ) -> Result<(), CoturnCliError> { + let mut connection = self.pool.get().await?; + for user in users { + let sessions = connection + .deref_mut() + .print_sessions(user.user().clone().into()) + .await?; + connection.deref_mut().delete_sessions(sessions).await?; + } + + Ok(()) + } +} + +impl fmt::Debug for CoturnTelnetClient { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("CoturnTelnetClient") + .field("pool", &self.pool.status()) + .finish() + } +} diff --git a/src/turn/mod.rs b/src/turn/mod.rs index 2200d2a6e..bbf887586 100644 --- a/src/turn/mod.rs +++ b/src/turn/mod.rs @@ -2,6 +2,7 @@ //! //! [TURN]: https://webrtcglossary.com/turn +pub mod cli; pub mod repo; pub mod service; diff --git a/src/turn/repo.rs b/src/turn/repo.rs index 68c7d8b8e..ba3dd3ebb 100644 --- a/src/turn/repo.rs +++ b/src/turn/repo.rs @@ -1,7 +1,7 @@ //! Abstraction over remote Redis database used to store Turn server //! credentials. -use std::{fmt, future::Future, time::Duration}; +use std::{fmt, time::Duration}; use crypto::{digest::Digest, md5::Md5}; use deadpool::managed::{PoolConfig, Timeouts}; @@ -21,8 +21,11 @@ pub enum TurnDatabaseErr { RedisError(RedisError), } -// Abstraction over remote Redis database used to store Turn server -// credentials. +/// Abstraction over remote Redis database used to store Turn server +/// credentials. +/// +/// This struct can be cloned and transferred across thread boundaries. +#[derive(Clone)] pub struct TurnDatabase { pool: Pool, } @@ -48,10 +51,7 @@ impl TurnDatabase { } /// Inserts provided [`IceUser`] into remote Redis database. - pub fn insert( - &mut self, - user: &IceUser, - ) -> impl Future> { + pub async fn insert(&self, user: &IceUser) -> Result<(), TurnDatabaseErr> { debug!("Store ICE user: {:?}", user); let key = format!("turn/realm/medea/user/{}/key", user.user()); @@ -61,34 +61,34 @@ impl TurnDatabase { hasher.input_str(&value); let result = hasher.result_str(); - let pool = self.pool.clone(); - async move { - let mut conn = pool.get().await?; - Ok(cmd("SET") - .arg(key) - .arg(result) - .query_async(&mut conn) - .await?) - } + let mut conn = self.pool.get().await?; + Ok(cmd("SET") + .arg(key) + .arg(result) + .query_async(&mut conn) + .await?) } /// Deletes batch of provided [`IceUser`]s. - pub fn remove( - &mut self, - users: &[IceUser], - ) -> impl Future> { + /// + /// No-op if empty batch is provided. + pub async fn remove( + &self, + users: &[&IceUser], + ) -> Result<(), TurnDatabaseErr> { debug!("Remove ICE users: {:?}", users); - let delete_keys: Vec<_> = users + if users.is_empty() { + return Ok(()); + } + + let keys: Vec<_> = users .iter() .map(|u| format!("turn/realm/medea/user/{}/key", u.user())) .collect(); - let pool = self.pool.clone(); - async move { - let mut conn = pool.get().await?; - Ok(cmd("DEL").arg(delete_keys).query_async(&mut conn).await?) - } + let mut conn = self.pool.get().await?; + Ok(cmd("DEL").arg(keys).query_async(&mut conn).await?) } } diff --git a/src/turn/service.rs b/src/turn/service.rs index 0c607bb96..38cb3d4f8 100644 --- a/src/turn/service.rs +++ b/src/turn/service.rs @@ -5,15 +5,9 @@ use std::{fmt, sync::Arc}; -use actix::{ - fut, Actor, ActorFuture, Addr, Context, Handler, MailboxError, Message, - ResponseFuture, WrapFuture as _, -}; +use async_trait::async_trait; use derive_more::{Display, From}; use failure::Fail; -use futures::future::{ - self, FutureExt as _, LocalBoxFuture, TryFutureExt as _, -}; use rand::{distributions::Alphanumeric, Rng}; use redis::ConnectionInfo; @@ -21,87 +15,22 @@ use crate::{ api::control::{MemberId, RoomId}, conf, media::IceUser, - turn::repo::{TurnDatabase, TurnDatabaseErr}, + turn::{ + cli::{CoturnCliError, CoturnTelnetClient}, + repo::{TurnDatabase, TurnDatabaseErr}, + }, }; static TURN_PASS_LEN: usize = 16; -/// Manages Turn server credentials. -pub trait TurnAuthService: fmt::Debug + Send + Sync { - /// Generates and registers Turn credentials. - fn create( - &self, - member_id: MemberId, - room_id: RoomId, - policy: UnreachablePolicy, - ) -> LocalBoxFuture<'static, Result>; - - /// Deletes batch of [`IceUser`]s. - fn delete( - &self, - users: Vec, - ) -> LocalBoxFuture<'static, Result<(), TurnServiceErr>>; -} - -impl TurnAuthService for Addr { - /// Sends [`CreateIceUser`] to [`Service`]. - fn create( - &self, - member_id: MemberId, - room_id: RoomId, - policy: UnreachablePolicy, - ) -> LocalBoxFuture<'static, Result> { - let creating = self.send(CreateIceUser { - member_id, - room_id, - policy, - }); - async { - match creating.await { - Ok(Ok(ice)) => Ok(ice), - Ok(Err(err)) => Err(err), - Err(err) => Err(err.into()), - } - } - .boxed_local() - } - - /// Sends `DeleteRoom` to [`Service`]. - fn delete( - &self, - users: Vec, - ) -> LocalBoxFuture<'static, Result<(), TurnServiceErr>> { - // leave only non static users - let users: Vec = - users.into_iter().filter(|u| !u.is_static()).collect(); - - if users.is_empty() { - future::ok(()).boxed_local() - } else { - let deleting = self.send(DeleteIceUsers(users)); - async { - match deleting.await { - Ok(Err(err)) => Err(err), - Err(err) => Err(err.into()), - _ => Ok(()), - } - } - .boxed_local() - } - } -} - -/// Ergonomic type alias for using [`ActorFuture`] for [`AuthService`]. -type ActFuture = Box>; - /// Error which can happen in [`TurnAuthService`]. #[derive(Display, Debug, Fail, From)] pub enum TurnServiceErr { #[display(fmt = "Error accessing TurnAuthRepo: {}", _0)] TurnAuthRepoErr(TurnDatabaseErr), - #[display(fmt = "Mailbox error when accessing TurnAuthRepo: {}", _0)] - MailboxErr(MailboxError), + #[display(fmt = "Error accessing TurnAuthRepo: {}", _0)] + CoturnCLiErr(CoturnCliError), #[display(fmt = "Timeout exceeded while trying to insert/delete IceUser")] #[from(ignore)] @@ -120,12 +49,29 @@ pub enum UnreachablePolicy { ReturnStatic, } +/// Manages Turn server credentials. +#[async_trait] +pub trait TurnAuthService: fmt::Debug + Send + Sync { + /// Generates and registers Turn credentials. + async fn create( + &self, + member_id: MemberId, + room_id: RoomId, + policy: UnreachablePolicy, + ) -> Result; + + /// Deletes batch of [`IceUser`]s. + async fn delete(&self, users: &[IceUser]) -> Result<(), TurnServiceErr>; +} + /// [`TurnAuthService`] implementation backed by Redis database. #[derive(Debug)] struct Service { /// Turn credentials repository. turn_db: TurnDatabase, + coturn_cli: CoturnTelnetClient, + /// TurnAuthRepo password. db_pass: String, @@ -137,9 +83,66 @@ struct Service { /// Turn server static user password. turn_password: String, +} + +impl Service { + /// Generates random alphanumeric string of specified length. + fn generate_pass(n: usize) -> String { + rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(n) + .collect() + } - /// Lazy static [`ICEUser`]. - static_user: Option, + /// Returns [`IceUser`] with static credentials. + fn static_user(&self) -> IceUser { + IceUser::new( + self.turn_address.clone(), + self.turn_username.clone(), + self.turn_password.clone(), + ) + } +} + +#[async_trait] +impl TurnAuthService for Service { + /// Generates [`IceUser`] with saved Turn address, provided [`MemberId`] and + /// random password. Inserts created [`IceUser`] into [`TurnDatabase`]. + async fn create( + &self, + member_id: MemberId, + room_id: RoomId, + policy: UnreachablePolicy, + ) -> Result { + let ice_user = IceUser::build( + self.turn_address.clone(), + &room_id, + &member_id.0, + Self::generate_pass(TURN_PASS_LEN), + ); + + match self.turn_db.insert(&ice_user).await { + Ok(_) => Ok(ice_user), + Err(err) => match policy { + UnreachablePolicy::ReturnErr => Err(err.into()), + UnreachablePolicy::ReturnStatic => Ok(self.static_user()), + }, + } + } + + /// Deletes provided [`IceUser`]s from [`TurnDatabase`] and closes their + /// sessions on Coturn. + async fn delete(&self, users: &[IceUser]) -> Result<(), TurnServiceErr> { + if users.is_empty() { + return Ok(()); + } + + // leave only non static users + let users = users.iter().filter(|u| !u.is_static()).collect::>(); + self.turn_db.remove(users.as_slice()).await?; + self.coturn_cli.delete_sessions(users.as_slice()).await?; + Ok(()) + } } /// Create new instance [`TurnAuthService`]. @@ -162,101 +165,21 @@ pub fn new_turn_auth_service<'a>( }, )?; + let coturn_cli = CoturnTelnetClient::new( + (cf.cli.ip.to_string(), cf.cli.port), + cf.cli.pass.clone(), + )?; + let turn_service = Service { turn_db, + coturn_cli, db_pass: cf.db.redis.pass.clone(), turn_address: cf.addr(), turn_username: cf.user.clone(), turn_password: cf.pass.clone(), - static_user: None, }; - Ok(Arc::new(turn_service.start())) -} - -impl Service { - /// Generates random alphanumeric string of specified length. - fn generate_pass(n: usize) -> String { - rand::thread_rng() - .sample_iter(&Alphanumeric) - .take(n) - .collect() - } - - /// Returns [`ICEUser`] with static credentials. - fn static_user(&mut self) -> IceUser { - if self.static_user.is_none() { - self.static_user.replace(IceUser::new( - self.turn_address.clone(), - self.turn_username.clone(), - self.turn_password.clone(), - )); - }; - - self.static_user.clone().unwrap() - } -} - -impl Actor for Service { - type Context = Context; -} - -/// Creates credentials on Turn server for specified member. -#[derive(Debug, Message)] -#[rtype(result = "Result")] -struct CreateIceUser { - pub member_id: MemberId, - pub room_id: RoomId, - pub policy: UnreachablePolicy, -} - -impl Handler for Service { - type Result = ActFuture>; - - /// Generates [`IceUser`] with saved Turn address, provided [`MemberId`] and - /// random password. Inserts created [`IceUser`] into [`TurnDatabase`]. - fn handle( - &mut self, - msg: CreateIceUser, - _ctx: &mut Self::Context, - ) -> Self::Result { - let ice_user = IceUser::build( - self.turn_address.clone(), - &msg.room_id, - &msg.member_id.to_string(), - Self::generate_pass(TURN_PASS_LEN), - ); - - Box::new(self.turn_db.insert(&ice_user).into_actor(self).then( - move |result, this, _| match result { - Ok(_) => fut::ok(ice_user), - Err(err) => match msg.policy { - UnreachablePolicy::ReturnErr => fut::err(err.into()), - UnreachablePolicy::ReturnStatic => { - fut::ok(this.static_user()) - } - }, - }, - )) - } -} - -/// Deletes all users from given room in redis. -#[derive(Debug, Message)] -#[rtype(result = "Result<(), TurnServiceErr>")] -struct DeleteIceUsers(Vec); - -impl Handler for Service { - type Result = ResponseFuture>; - - /// Deletes all users with provided [`RoomId`] - fn handle( - &mut self, - msg: DeleteIceUsers, - _ctx: &mut Self::Context, - ) -> Self::Result { - self.turn_db.remove(&msg.0).err_into().boxed_local() - } + Ok(Arc::new(turn_service)) } #[cfg(test)] @@ -267,35 +190,30 @@ pub mod test { use super::*; - #[derive(Debug)] - struct TurnAuthServiceMock {} + #[derive(Clone, Copy, Debug)] + struct TurnAuthServiceMock; + #[async_trait] impl TurnAuthService for TurnAuthServiceMock { - fn create( + async fn create( &self, _: MemberId, _: RoomId, _: UnreachablePolicy, - ) -> LocalBoxFuture<'static, Result> { - async { - Ok(IceUser::new( - "5.5.5.5:1234".parse().unwrap(), - "username".into(), - "password".into(), - )) - } - .boxed_local() + ) -> Result { + Ok(IceUser::new( + "5.5.5.5:1234".parse().unwrap(), + "username".into(), + "password".into(), + )) } - fn delete( - &self, - _: Vec, - ) -> LocalBoxFuture<'static, Result<(), TurnServiceErr>> { - future::ok(()).boxed_local() + async fn delete(&self, _: &[IceUser]) -> Result<(), TurnServiceErr> { + Ok(()) } } pub fn new_turn_auth_service_mock() -> Arc { - Arc::new(TurnAuthServiceMock {}) + Arc::new(TurnAuthServiceMock) } } From 5332d558a48bebc0843f9228d631b46b47d33666 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 09:51:26 +0200 Subject: [PATCH 030/224] refactor --- Cargo.lock | 256 ++++++++++++++----------- crates/coturn-telnet/src/connection.rs | 2 +- crates/coturn-telnet/src/pool.rs | 22 +-- jason/src/lib.rs | 2 - src/lib.rs | 2 - src/turn/cli.rs | 9 +- src/turn/service.rs | 2 +- 7 files changed, 163 insertions(+), 132 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef64d72cd..f951d9c4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -40,8 +40,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -58,7 +58,7 @@ dependencies = [ "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "trust-dns-proto 0.18.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -73,7 +73,7 @@ dependencies = [ "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -98,9 +98,9 @@ dependencies = [ "encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -115,7 +115,7 @@ dependencies = [ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -151,7 +151,7 @@ dependencies = [ "actix-macros 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "actix-threadpool 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -164,7 +164,7 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -178,7 +178,7 @@ name = "actix-service" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -191,7 +191,7 @@ dependencies = [ "actix-rt 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "actix-server 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "actix-service 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -202,7 +202,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -221,7 +221,7 @@ dependencies = [ "actix-utils 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -236,7 +236,7 @@ dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -263,7 +263,7 @@ dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -271,7 +271,7 @@ dependencies = [ "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -287,7 +287,7 @@ dependencies = [ "actix-http 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -371,7 +371,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "async-stream-impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -426,19 +426,19 @@ dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "backtrace" -version = "0.3.43" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", @@ -461,7 +461,7 @@ name = "base64" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -504,12 +504,12 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.1.2" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.3.2" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -581,7 +581,7 @@ version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -597,7 +597,7 @@ dependencies = [ "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "serde-hjson 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -621,6 +621,22 @@ name = "copyless" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "coturn-telnet" +version = "0.1.0-dev" +dependencies = [ + "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-test 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crc32fast" version = "1.2.0" @@ -766,7 +782,7 @@ dependencies = [ "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "config 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "redis 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", @@ -897,7 +913,7 @@ name = "failure" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -972,50 +988,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-channel 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-channel" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-core" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-executor" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "futures-io" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-macro" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1026,26 +1042,26 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-task" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures-util" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-io 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-macro 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-task 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-macro 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1058,7 +1074,7 @@ name = "fxhash" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1083,9 +1099,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1166,9 +1182,9 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-channel 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "h2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1352,13 +1368,14 @@ dependencies = [ "awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "config 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "coturn-telnet 0.1.0-dev", "deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "deadpool-redis 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "derive_builder 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "humantime-serde 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "medea-client-api-proto 0.2.0-dev", @@ -1369,7 +1386,7 @@ dependencies = [ "redis 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "serial_test_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1394,7 +1411,7 @@ dependencies = [ "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "medea-macro 0.2.0-dev", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1437,14 +1454,14 @@ dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "downcast 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "fragile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "medea-client-api-proto 0.2.0-dev", "medea-macro 0.2.0-dev", "mockall 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "predicates-tree 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "tracerr 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-futures 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1987,8 +2004,8 @@ dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-executor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2157,7 +2174,7 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2271,7 +2288,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2472,7 +2489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2482,17 +2499,38 @@ dependencies = [ "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tokio-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-test" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tokio-util" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-sink 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2515,8 +2553,8 @@ dependencies = [ "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "http-body 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2551,7 +2589,7 @@ name = "tower" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "tower-buffer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-discover 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2568,8 +2606,8 @@ name = "tower-balance" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2589,7 +2627,7 @@ name = "tower-buffer" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2602,7 +2640,7 @@ name = "tower-discover" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2617,7 +2655,7 @@ name = "tower-limit" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2629,7 +2667,7 @@ name = "tower-load" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2642,7 +2680,7 @@ name = "tower-load-shed" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2662,8 +2700,8 @@ name = "tower-ready-cache" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2675,7 +2713,7 @@ name = "tower-retry" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tower-layer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2703,8 +2741,8 @@ name = "tower-util" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "pin-project 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2767,7 +2805,7 @@ dependencies = [ "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", "enum-as-inner 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2785,7 +2823,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2891,7 +2929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2900,7 +2938,7 @@ name = "wasm-bindgen-backend" version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3125,7 +3163,7 @@ dependencies = [ "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7601d4d1d7ef2335d6597a41b5fe069f6ab799b85f53565ab390e7b7065aac5" -"checksum backtrace 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)" = "7f80256bc78f67e7df7e36d77366f636ed976895d91fe2ab9efa3973e8fe8c4f" +"checksum backtrace 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e4036b9bf40f3cf16aba72a3d65e8a520fc4bafcdc7079aea8f848c58c5b5536" "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" @@ -3133,8 +3171,8 @@ dependencies = [ "checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" "checksum brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" "checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -"checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" -"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +"checksum bumpalo 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f359dc14ff8911330a51ef78022d376f25ed00248912803b58f00cb1c27f742" +"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" "checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1" "checksum bytestring 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fc267467f58ef6cc8874064c62a0423eb0d099362c8a23edd1c6d044f46eead4" "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" @@ -3188,15 +3226,15 @@ dependencies = [ "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" -"checksum futures 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ad6636318d07abeb4656157ef1936c64485f066c7f9ce5d7c5b879fcb6dd5ccb" -"checksum futures-channel 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7264eb65b194d2fa6ec31b898ead7c332854bfa42521659226e72a585fca5b85" -"checksum futures-core 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b597b16aa1a19ce2dfde5128a7c656d75346b35601a640be2d9efd4e9c83609d" -"checksum futures-executor 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "46a5e593d77bee52393c7f3b16b8b413214096d3f7dc4f5f4c57dee01ad2bdaf" -"checksum futures-io 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3d429f824b5e5dbd45fc8e54e1005a37e1f8c6d570cd64d0b59b24d3a80b8b8e" -"checksum futures-macro 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d75b72904b78044e0091355fc49d29f48bff07a68a719a41cf059711e071b4" -"checksum futures-sink 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "04299e123547ea7c56f3e1b376703142f5fc0b6700433eed549e9d0b8a75a66c" -"checksum futures-task 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "86f9ceab4bce46555ee608b1ec7c414d6b2e76e196ef46fa5a8d4815a8571398" -"checksum futures-util 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7d2f1296f7644d2cd908ebb2fa74645608e39f117c72bac251d40418c6d74c4f" +"checksum futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780" +"checksum futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8" +"checksum futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a" +"checksum futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba" +"checksum futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6" +"checksum futures-macro 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" +"checksum futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6" +"checksum futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27" +"checksum futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5" "checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" @@ -3312,7 +3350,7 @@ dependencies = [ "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" "checksum serde-hjson 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" "checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" -"checksum serde_json 1.0.46 (registry+https://github.com/rust-lang/crates.io-index)" = "21b01d7f0288608a01dca632cf1df859df6fd6ffa885300fc275ce2ba6221953" +"checksum serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "15913895b61e0be854afd32fd4163fcd2a3df34142cf2cb961b310ce694cbf90" "checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" "checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" @@ -3348,6 +3386,8 @@ dependencies = [ "checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" +"checksum tokio-macros 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" +"checksum tokio-test 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "09cf9705471976fa5fc6817d3fbc9c4ff9696a6647af0e5c1870c81ca7445b05" "checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" "checksum tonic 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08283643b1d483eb7f3fc77069e63b5cba3e4db93514b3d45470e67f123e4e48" diff --git a/crates/coturn-telnet/src/connection.rs b/crates/coturn-telnet/src/connection.rs index 9ad42dc97..fd2fa2a19 100644 --- a/crates/coturn-telnet/src/connection.rs +++ b/crates/coturn-telnet/src/connection.rs @@ -45,7 +45,7 @@ impl From for CoturnTelnetError { /// Asynchronous connection to remote [Coturn] server telnet interface. You can /// use this directly, but it is recommended to use this with connection pool -/// from `crate::pool`, which takes care of connection life cycle. +/// from [`crate::pool::Pool`], which takes care of connection life cycle. /// /// [Coturn]: https://github.com/coturn/coturn. pub struct CoturnTelnetConnection(Framed); diff --git a/crates/coturn-telnet/src/pool.rs b/crates/coturn-telnet/src/pool.rs index 5a7795d9b..8b7feeb09 100644 --- a/crates/coturn-telnet/src/pool.rs +++ b/crates/coturn-telnet/src/pool.rs @@ -21,26 +21,26 @@ use async_trait::async_trait; use bytes::Bytes; +use deadpool::managed; use crate::connection::{CoturnTelnetConnection, CoturnTelnetError}; -/// A type alias for using [`deadpool::managed::Pool`] with +/// A type alias for using `deadpool::managed::Pool` with /// [`CoturnTelnetConnection`]. -pub type Pool = - deadpool::managed::Pool; +pub type Pool = managed::Pool; -/// A type alias for using [`deadpool::managed::PoolError`] with +/// A type alias for using `deadpool::managed::PoolError` with /// [`CoturnTelnetConnection`]. -pub type PoolError = deadpool::managed::PoolError; +pub type PoolError = managed::PoolError; -/// A type alias for using [`deadpool::managed::Object`] with +/// A type alias for using `deadpool::managed::Object` with /// [`CoturnTelnetConnection`]. pub type Connection = - deadpool::managed::Object; + managed::Object; -type RecycleResult = deadpool::managed::RecycleResult; +type RecycleResult = managed::RecycleResult; -/// The manager for creating and recycling Coturn telnet connections +/// The manager for creating and recycling Coturn telnet connections. pub struct Manager { addr: (String, u16), pass: Bytes, @@ -56,9 +56,7 @@ impl Manager { } #[async_trait] -impl deadpool::managed::Manager - for Manager -{ +impl managed::Manager for Manager { async fn create( &self, ) -> Result { diff --git a/jason/src/lib.rs b/jason/src/lib.rs index f83a24a1b..6dce1acde 100644 --- a/jason/src/lib.rs +++ b/jason/src/lib.rs @@ -7,8 +7,6 @@ #![allow(clippy::module_name_repetitions, clippy::must_use_candidate)] #![cfg_attr(not(feature = "mockable"), warn(missing_docs))] #![cfg_attr(feature = "mockable", allow(missing_docs))] -// TODO: REVERT ME BEFORE MERGE!!! -#![allow(clippy::missing_errors_doc)] #[macro_use] pub mod utils; diff --git a/src/lib.rs b/src/lib.rs index 27c169dc9..8919683d1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,8 +3,6 @@ // TODO: Remove `clippy::must_use_candidate` once the issue below is resolved: // https://github.com/rust-lang/rust-clippy/issues/4779 #![allow(clippy::module_name_repetitions, clippy::must_use_candidate)] -// TODO: REVERT ME BEFORE MERGE!!! -#![allow(clippy::missing_errors_doc)] #[macro_use] pub mod utils; diff --git a/src/turn/cli.rs b/src/turn/cli.rs index 9e3070964..ae8cfd851 100644 --- a/src/turn/cli.rs +++ b/src/turn/cli.rs @@ -27,10 +27,7 @@ pub struct CoturnTelnetClient { impl CoturnTelnetClient { /// Creates new [`CoturnTelnetClient`]. - pub fn new( - addr: (String, u16), - pass: String, - ) -> Result { + pub fn new(addr: (String, u16), pass: String) -> Self { let manager = Manager::new(addr, pass); // TODO: to conf let config = PoolConfig { @@ -41,9 +38,9 @@ impl CoturnTelnetClient { recycle: Some(Duration::from_secs(5)), }, }; - Ok(Self { + Self { pool: Pool::from_config(manager, config), - }) + } } /// Forcefully closes provided [`IceUser`]s sessions on Coturn server. diff --git a/src/turn/service.rs b/src/turn/service.rs index 6bd6148d2..42a62c75d 100644 --- a/src/turn/service.rs +++ b/src/turn/service.rs @@ -173,7 +173,7 @@ pub fn new_turn_auth_service<'a>( let coturn_cli = CoturnTelnetClient::new( (cf.cli.ip.to_string(), cf.cli.port), cf.cli.pass.clone(), - )?; + ); let turn_service = Service { turn_db, From 56791475d1094a84c223bdabb60286e7b612aec1 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 10:05:16 +0200 Subject: [PATCH 031/224] coturn telnet docs --- crates/coturn-telnet/src/codec.rs | 2 ++ crates/coturn-telnet/src/connection.rs | 11 ++++++----- crates/coturn-telnet/src/lib.rs | 12 +++++++++--- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/crates/coturn-telnet/src/codec.rs b/crates/coturn-telnet/src/codec.rs index 2420d585f..c23549381 100644 --- a/crates/coturn-telnet/src/codec.rs +++ b/crates/coturn-telnet/src/codec.rs @@ -145,6 +145,8 @@ impl Into for CoturnCliRequest { } } +/// Errors that can happen while decoding bytes received to +/// [`CoturnCliResponse`]. #[derive(Debug)] pub enum CoturnCliCodecError { IoError(io::Error), diff --git a/crates/coturn-telnet/src/connection.rs b/crates/coturn-telnet/src/connection.rs index fd2fa2a19..5754392db 100644 --- a/crates/coturn-telnet/src/connection.rs +++ b/crates/coturn-telnet/src/connection.rs @@ -12,14 +12,15 @@ use crate::codec::{ CoturnResponseParseError, }; +/// Any errors that can be thrown from [`CoturnTelnetConnection`]. #[derive(Debug, derive_more::Display, derive_more::From)] pub enum CoturnTelnetError { /// Underlying transport encountered [`io::Error`]. You should try - /// recreating [`CoturnTelnetClient`]. + /// recreating [`CoturnTelnetConnection`]. #[display(fmt = "Underlying transport encountered IoError: {}", _0)] IoError(io::Error), /// Underlying stream exhausted. You should try recreating - /// [`CoturnTelnetClient`]. + /// [`CoturnTelnetConnection`]. #[display(fmt = "Disconnected from Coturn telnet server")] Disconnected, /// Unable to parse response from Coturn telnet server. This is @@ -45,7 +46,7 @@ impl From for CoturnTelnetError { /// Asynchronous connection to remote [Coturn] server telnet interface. You can /// use this directly, but it is recommended to use this with connection pool -/// from [`crate::pool::Pool`], which takes care of connection life cycle. +/// from [`crate::pool::Pool`], which takes care of connection lifecycle. /// /// [Coturn]: https://github.com/coturn/coturn. pub struct CoturnTelnetConnection(Framed); @@ -66,7 +67,7 @@ impl CoturnTelnetConnection { /// Returns session ids associated with provided username. /// - /// 1. Sends [`CoturnTelnetClientError::PrintSessions`] with provided + /// 1. Sends [`CoturnCliRequest::PrintSessions`] with provided /// username. /// 2. Awaits for [`CoturnCliResponse::Sessions`]. pub async fn print_sessions( @@ -131,7 +132,7 @@ impl CoturnTelnetConnection { Ok(()) } - /// Authenticates [`CoturnTelnetClient`]. + /// Authenticates [`CoturnTelnetConnection`]. /// /// 1. Awaits for [`CoturnCliResponse::EnterPassword`]. /// 2. Sends [`CoturnCliRequest::Auth`]. diff --git a/crates/coturn-telnet/src/lib.rs b/crates/coturn-telnet/src/lib.rs index 321641c49..b4ca61b19 100644 --- a/crates/coturn-telnet/src/lib.rs +++ b/crates/coturn-telnet/src/lib.rs @@ -1,8 +1,14 @@ +//! Implements client to access [Coturn] telnet cli. You can use +//! [`CoturnTelnetConnection`] directly, but it is recommended to use connection +//! pool based on [deadpool] that will take care of connection lifecycle. +//! +//! [Coturn]: https://github.com/coturn/coturn +//! [deadpool]: https://crates.io/crates/deadpool #![allow(clippy::module_name_repetitions)] -mod codec; -mod connection; -mod pool; +pub mod codec; +pub mod connection; +pub mod pool; pub use connection::{CoturnTelnetConnection, CoturnTelnetError}; pub use pool::{Connection, Manager, Pool, PoolError}; From 2512b0b83f6197f218a451409b159f09c70631ee Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 10:22:18 +0200 Subject: [PATCH 032/224] doctest --- crates/coturn-telnet/src/pool.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/crates/coturn-telnet/src/pool.rs b/crates/coturn-telnet/src/pool.rs index 8b7feeb09..75d59da27 100644 --- a/crates/coturn-telnet/src/pool.rs +++ b/crates/coturn-telnet/src/pool.rs @@ -6,17 +6,21 @@ //! # Example //! //! ```rust +//! use std::ops::DerefMut; //! use coturn_telnet::{Manager, Pool}; //! -//! let mgr = Manager::new((String::from("localhost", 5766)), "turn") -//! .unwrap(); -//! let pool = Pool::new(mgr, 16); -//! let mut conn = pool.get().await.unwrap(); +//! let mut rt = tokio::runtime::Runtime::new().unwrap(); +//! rt.block_on(async { +//! let mgr = Manager::new((String::from("localhost"), 5766), "turn"); +//! let pool = Pool::new(mgr, 16); //! -//! conn.deref_mut() -//! .print_sessions(String::from("username")) -//! .await -//! .unwrap(); +//! let mut conn = pool.get().await.unwrap(); +//! +//! conn.deref_mut() +//! .print_sessions(String::from("username")) +//! .await +//! .unwrap(); +//! }); //! ``` use async_trait::async_trait; From 54e39d3b7358867ba8ea9e0e50a821096331ffd2 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 11 Feb 2020 12:37:05 +0300 Subject: [PATCH 033/224] Add some docs --- src/turn/coturn_stats.rs | 118 ++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 65 deletions(-) diff --git a/src/turn/coturn_stats.rs b/src/turn/coturn_stats.rs index 295e7b696..9c5cfc769 100644 --- a/src/turn/coturn_stats.rs +++ b/src/turn/coturn_stats.rs @@ -47,7 +47,7 @@ impl CoturnAllocationEvent { body: String, ) -> Result { match event_type { - "total_traffic" => { + "total_traffic" | "traffic" => { let mut items: HashMap<&str, u64> = body .split(", ") .map(|i| { @@ -97,69 +97,21 @@ impl CoturnAllocationEvent { ) })?; - Ok(CoturnAllocationEvent::TotalTraffic { - received_bytes, - received_packets, - sent_bytes, - sent_packets, - }) - } - "traffic" => { - let mut items: HashMap<&str, u64> = body - .split(", ") - .map(|i| { - let mut splitted_item = i.split('='); - let key = splitted_item.next().ok_or_else(|| { - CoturnEventParseError::FailedToParseTrafficMap( - body.clone(), - ) - })?; - let value: u64 = splitted_item - .next() - .ok_or_else(|| { - CoturnEventParseError::FailedToParseTrafficMap( - body.clone(), - ) - })? - .parse() - .map_err(|_| { - CoturnEventParseError::FailedToParseTrafficMap( - body.clone(), - ) - })?; - - Ok((key, value)) + if event_type == "total_traffic" { + Ok(CoturnAllocationEvent::TotalTraffic { + received_bytes, + received_packets, + sent_bytes, + sent_packets, }) - .collect::>()?; - - let received_packets = - items.remove("rcvp").ok_or_else(|| { - CoturnEventParseError::FieldNotFoundInTrafficUpdate( - "rcvp".to_string(), - ) - })?; - let received_bytes = items.remove("rcvb").ok_or_else(|| { - CoturnEventParseError::FieldNotFoundInTrafficUpdate( - "rcvb".to_string(), - ) - })?; - let sent_packets = items.remove("sentp").ok_or_else(|| { - CoturnEventParseError::FieldNotFoundInTrafficUpdate( - "sentp".to_string(), - ) - })?; - let sent_bytes = items.remove("sentb").ok_or_else(|| { - CoturnEventParseError::FieldNotFoundInTrafficUpdate( - "sentb".to_string(), - ) - })?; - - Ok(CoturnAllocationEvent::Traffic { - received_bytes, - received_packets, - sent_bytes, - sent_packets, - }) + } else { + Ok(CoturnAllocationEvent::Traffic { + received_bytes, + received_packets, + sent_bytes, + sent_packets, + }) + } } "status" => { let mut splitted = body.split(' '); @@ -200,7 +152,6 @@ impl CoturnAllocationEvent { } } _ => { - debug!("Body: {}", body); Err(CoturnEventParseError::UnsupportedEventType( event_type.to_string(), )) @@ -271,20 +222,57 @@ impl CoturnEvent { } } -#[derive(Debug)] +#[derive(Debug, Display)] pub enum CoturnEventParseError { + /// Unsupported allocation status. + #[display(fmt = "Unsupported allocation status: {}", _0)] UnsupportedStatus(String), + + /// Unsupported allocation event type. + #[display(fmt = "Unsupported allocation event type: {}", _0)] UnsupportedEventType(String), + + /// Some traffic stats event's field not found. + #[display(fmt = "Field {} not found in traffic event", _0)] FieldNotFoundInTrafficUpdate(String), + + /// Failed to parse traffic event stat metadata. + #[display(fmt = "Failed to parse traffic stat '{}' from traffic event.", _0)] FailedToParseTrafficMap(String), + + /// Status is empty. + #[display(fmt = "Status is empty.")] EmptyStatus, + + /// Status doesn't have metadata. + #[display(fmt = "Status doesn't have metadata.")] NoMetadataInStatus, + + /// Allocation lifetime parsing failed. + #[display(fmt = "Allocation lifetime parsing failed.")] FailedLifetimeParsing, + + /// Redis channel info is empty. + #[display(fmt = "Redis channel info is empty.")] NoChannelInfo, + + /// No user metadata. + #[display(fmt = "No user metadata.")] NoUserInfo, + + /// No MemberId metadata. + #[display(fmt = "No MemberId metadata.")] NoMemberId, + + /// No PeerId metadata. + #[display(fmt = "No PeerId metadata.")] NoPeerId, + + /// No allocation ID metadata. + #[display(fmt = "No allocation ID metadata.")] NoAllocationId, + + #[display(fmt = "No event type.")] NoEventType, } From be00905664bd623a598e552e7d830ae06d6bbc27 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 11:41:47 +0200 Subject: [PATCH 034/224] add timeouts to config --- config.toml | 19 ++++++++- crates/coturn-telnet/Cargo.toml | 2 +- crates/coturn-telnet/README.md | 2 +- src/conf/turn.rs | 69 +++++++++++++++++++++++++++++---- 4 files changed, 82 insertions(+), 10 deletions(-) diff --git a/config.toml b/config.toml index d4175eee1..cfefc8712 100644 --- a/config.toml +++ b/config.toml @@ -128,7 +128,7 @@ [turn.cli] # Coturn server host. # -# Env var: MEDEA_TURN__CLI__HOST +# Env var: MEDEA_TURN__CLI__IP # Default: # host = "127.0.0.1" @@ -144,7 +144,24 @@ # Default: # pass = "turn" +[turn.cli.timeouts] +# Timeout when waiting for an available connection. +# +# Env var: MEDEA_TURN__CLI__TIMEOUTS__WAIT +# Default: +# wait = "5s" +# Timeout when creating a new connection. +# +# Env var: MEDEA_TURN__CLI__TIMEOUTS__CREATE +# Default: +# create = "5s" + +# Timeout when recycling connection. +# +# Env var: MEDEA_TURN__CLI__TIMEOUTS__RECYCLE +# Default: +# recycle = "5s" [log] # Maximum allowed level of application log entries. diff --git a/crates/coturn-telnet/Cargo.toml b/crates/coturn-telnet/Cargo.toml index 03f768a3b..d545405d8 100644 --- a/crates/coturn-telnet/Cargo.toml +++ b/crates/coturn-telnet/Cargo.toml @@ -2,7 +2,7 @@ name = "coturn-telnet" version = "0.1.0-dev" edition = "2018" -description = "Coturn TURN server telnet cli client" +description = "Coturn TURN server telnet client" authors = ["Instrumentisto Team "] license = "MIT/Apache-2.0" documentation = "https://docs.rs/coturn-telnet" diff --git a/crates/coturn-telnet/README.md b/crates/coturn-telnet/README.md index 3411b4d2b..63dbe12a2 100644 --- a/crates/coturn-telnet/README.md +++ b/crates/coturn-telnet/README.md @@ -7,7 +7,7 @@ coturn-telnet [API Docs](https://docs.rs/coturn-telnet) | [Changelog](https://github.com/instrumentisto/medea/blob/master/crates/coturn-telnet/CHANGELOG.md) -[Coturn] telnet cli client implementation. +[Coturn] telnet admin interface client implementation. diff --git a/src/conf/turn.rs b/src/conf/turn.rs index 72e4d6089..c7ce09e8f 100644 --- a/src/conf/turn.rs +++ b/src/conf/turn.rs @@ -6,6 +6,7 @@ use std::{ time::Duration, }; +use deadpool::managed::Timeouts as PoolTimeouts; use serde::{Deserialize, Serialize}; use smart_default::SmartDefault; @@ -15,7 +16,7 @@ use smart_default::SmartDefault; pub struct Turn { /// Database settings pub db: Db, - /// Coturn cli connection settings. + /// Coturn telnet connection settings. pub cli: CoturnCli, /// Host of STUN/TURN server. Defaults to `localhost`. #[default = "localhost"] @@ -86,6 +87,35 @@ pub struct CoturnCli { /// Password for authorize on Coturn server telnet interface. #[default(String::from("turn"))] pub pass: String, + /// Coturn connection timeouts. + pub timeouts: Timeouts, +} + +/// [Deadpool] connection pool timeouts. +/// +/// [Deadpool]: https://crates.io/crates/deadpool +#[derive(Clone, Debug, Deserialize, Serialize, SmartDefault)] +#[serde(default)] +pub struct Timeouts { + #[default(Some(Duration::from_secs(5)))] + #[serde(with = "humantime_serde")] + pub wait: Option, + #[default(Some(Duration::from_secs(5)))] + #[serde(with = "humantime_serde")] + pub create: Option, + #[default(Some(Duration::from_secs(5)))] + #[serde(with = "humantime_serde")] + pub recycle: Option, +} + +impl Into for &Timeouts { + fn into(self) -> PoolTimeouts { + PoolTimeouts { + wait: self.wait, + create: self.create, + recycle: self.recycle + } + } } #[cfg(test)] @@ -157,14 +187,39 @@ mod spec { #[test] #[serial] - fn turn_conf() { + fn coturn_cli() { let default_conf = Conf::default(); - let env_conf = overrided_by_env_conf!( - "MEDEA_TURN__HOST" => "example.com", - "MEDEA_TURN__PORT" => "1234", + let env_conf:Conf = overrided_by_env_conf!( + "MEDEA_TURN__CLI__IP" => "4.4.4.4", + "MEDEA_TURN__CLI__PORT" => "1234", + "MEDEA_TURN__CLI__PASS" => "clipass", ); - assert_ne!(default_conf.turn.host, env_conf.turn.host); - assert_ne!(default_conf.turn.port, env_conf.turn.port); + assert_ne!(default_conf.turn.cli.ip, env_conf.turn.cli.ip); + assert_ne!(default_conf.turn.cli.port, env_conf.turn.cli.port); + assert_ne!(default_conf.turn.cli.pass, env_conf.turn.cli.pass); + + assert_eq!(env_conf.turn.cli.ip, Ipv4Addr::new(4, 4, 4, 4)); + assert_eq!(env_conf.turn.cli.port, 1234); + assert_eq!(env_conf.turn.cli.pass, "clipass"); + } + + #[test] + #[serial] + fn coturn_cli_timeouts() { + let default_conf = Conf::default(); + let env_conf:Conf = overrided_by_env_conf!( + "MEDEA_TURN__CLI__TIMEOUTS__WAIT" => "1s", + "MEDEA_TURN__CLI__TIMEOUTS__CREATE" => "2s", + "MEDEA_TURN__CLI__TIMEOUTS__RECYCLE" => "3s", + ); + + assert_ne!(default_conf.turn.cli.timeouts.wait, env_conf.turn.cli.timeouts.wait); + assert_ne!(default_conf.turn.cli.timeouts.create, env_conf.turn.cli.timeouts.create); + assert_ne!(default_conf.turn.cli.timeouts.recycle, env_conf.turn.cli.timeouts.recycle); + + assert_eq!(env_conf.turn.cli.timeouts.wait, Some(Duration::from_secs(1))); + assert_eq!(env_conf.turn.cli.timeouts.create, Some(Duration::from_secs(2))); + assert_eq!(env_conf.turn.cli.timeouts.recycle, Some(Duration::from_secs(3))); } } From 92ced951848050ab60c8fa984c26502a69a1f66b Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 12:14:44 +0200 Subject: [PATCH 035/224] add timeouts to config --- config.toml | 9 ++++-- src/conf/turn.rs | 78 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/config.toml b/config.toml index cfefc8712..13cce3ede 100644 --- a/config.toml +++ b/config.toml @@ -145,19 +145,22 @@ # pass = "turn" [turn.cli.timeouts] -# Timeout when waiting for an available connection. +# Timeout when waiting for an available connection. 0 means no timeout and is +# not recommended. # # Env var: MEDEA_TURN__CLI__TIMEOUTS__WAIT # Default: # wait = "5s" -# Timeout when creating a new connection. +# Timeout when creating a new connection. 0 means no timeout and is not +# recommended. # # Env var: MEDEA_TURN__CLI__TIMEOUTS__CREATE # Default: # create = "5s" -# Timeout when recycling connection. +# Timeout when recycling connection. 0 means no timeout and is not +# recommended. # # Env var: MEDEA_TURN__CLI__TIMEOUTS__RECYCLE # Default: diff --git a/src/conf/turn.rs b/src/conf/turn.rs index c7ce09e8f..438842c62 100644 --- a/src/conf/turn.rs +++ b/src/conf/turn.rs @@ -110,10 +110,31 @@ pub struct Timeouts { impl Into for &Timeouts { fn into(self) -> PoolTimeouts { + let wait = self.wait.and_then(|wait| { + if wait.as_nanos() == 0 { + None + } else { + Some(wait) + } + }); + let create = self.create.and_then(|create| { + if create.as_nanos() == 0 { + None + } else { + Some(create) + } + }); + let recycle = self.recycle.and_then(|recycle| { + if recycle.as_nanos() == 0 { + None + } else { + Some(recycle) + } + }); PoolTimeouts { - wait: self.wait, - create: self.create, - recycle: self.recycle + wait, + create, + recycle, } } } @@ -126,6 +147,8 @@ mod spec { use crate::{conf::Conf, overrided_by_env_conf}; + use super::*; + #[test] #[serial] fn redis_db_overrides_defaults() { @@ -189,7 +212,7 @@ mod spec { #[serial] fn coturn_cli() { let default_conf = Conf::default(); - let env_conf:Conf = overrided_by_env_conf!( + let env_conf: Conf = overrided_by_env_conf!( "MEDEA_TURN__CLI__IP" => "4.4.4.4", "MEDEA_TURN__CLI__PORT" => "1234", "MEDEA_TURN__CLI__PASS" => "clipass", @@ -208,18 +231,51 @@ mod spec { #[serial] fn coturn_cli_timeouts() { let default_conf = Conf::default(); - let env_conf:Conf = overrided_by_env_conf!( + let env_conf: Conf = overrided_by_env_conf!( "MEDEA_TURN__CLI__TIMEOUTS__WAIT" => "1s", "MEDEA_TURN__CLI__TIMEOUTS__CREATE" => "2s", "MEDEA_TURN__CLI__TIMEOUTS__RECYCLE" => "3s", ); - assert_ne!(default_conf.turn.cli.timeouts.wait, env_conf.turn.cli.timeouts.wait); - assert_ne!(default_conf.turn.cli.timeouts.create, env_conf.turn.cli.timeouts.create); - assert_ne!(default_conf.turn.cli.timeouts.recycle, env_conf.turn.cli.timeouts.recycle); + assert_ne!( + default_conf.turn.cli.timeouts.wait, + env_conf.turn.cli.timeouts.wait + ); + assert_ne!( + default_conf.turn.cli.timeouts.create, + env_conf.turn.cli.timeouts.create + ); + assert_ne!( + default_conf.turn.cli.timeouts.recycle, + env_conf.turn.cli.timeouts.recycle + ); + + assert_eq!( + env_conf.turn.cli.timeouts.wait, + Some(Duration::from_secs(1)) + ); + assert_eq!( + env_conf.turn.cli.timeouts.create, + Some(Duration::from_secs(2)) + ); + assert_eq!( + env_conf.turn.cli.timeouts.recycle, + Some(Duration::from_secs(3)) + ); + } + + #[test] + fn into_pool_timeouts() { + let timeouts = Timeouts { + wait: None, + create: Some(Duration::from_secs(0)), + recycle: Some(Duration::from_secs(2)), + }; + + let timeouts: PoolTimeouts = (&timeouts).into(); - assert_eq!(env_conf.turn.cli.timeouts.wait, Some(Duration::from_secs(1))); - assert_eq!(env_conf.turn.cli.timeouts.create, Some(Duration::from_secs(2))); - assert_eq!(env_conf.turn.cli.timeouts.recycle, Some(Duration::from_secs(3))); + assert!(timeouts.wait.is_none()); + assert!(timeouts.create.is_none()); + assert_eq!(timeouts.recycle, Some(Duration::from_secs(2))); } } From 9f9657e353e3ee185bca087f6566dceeb2c72cc3 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 11 Feb 2020 13:45:31 +0300 Subject: [PATCH 036/224] Refactor validation of specs --- src/api/control/endpoints/mod.rs | 7 +- .../control/endpoints/webrtc_play_endpoint.rs | 126 ++++++------------ src/api/control/error_codes.rs | 14 ++ src/api/control/member.rs | 37 +++-- src/api/control/mod.rs | 49 ++++++- src/api/control/pipeline.rs | 11 ++ src/api/control/room.rs | 41 +++++- src/signalling/elements/member.rs | 3 +- src/signalling/room.rs | 3 +- src/turn/coturn_stats.rs | 13 +- 10 files changed, 192 insertions(+), 112 deletions(-) diff --git a/src/api/control/endpoints/mod.rs b/src/api/control/endpoints/mod.rs index 53017449c..996d9e79d 100644 --- a/src/api/control/endpoints/mod.rs +++ b/src/api/control/endpoints/mod.rs @@ -13,6 +13,7 @@ use serde::Deserialize; use super::{member::MemberElement, TryFromProtobufError}; +use crate::api::control::endpoints::webrtc_play_endpoint::Validated; #[doc(inline)] pub use webrtc_play_endpoint::{WebRtcPlayEndpoint, WebRtcPlayId}; #[doc(inline)] @@ -50,11 +51,11 @@ pub enum EndpointSpec { WebRtcPublish(WebRtcPublishEndpoint), /// [`WebRtcPlayEndpoint`] element. - WebRtcPlay(WebRtcPlayEndpoint), + WebRtcPlay(WebRtcPlayEndpoint), } -impl Into for EndpointSpec { - fn into(self) -> MemberElement { +impl Into> for EndpointSpec { + fn into(self) -> MemberElement { match self { Self::WebRtcPublish(e) => { MemberElement::WebRtcPublishEndpoint { spec: e } diff --git a/src/api/control/endpoints/webrtc_play_endpoint.rs b/src/api/control/endpoints/webrtc_play_endpoint.rs index 8b28eb938..57f832e41 100644 --- a/src/api/control/endpoints/webrtc_play_endpoint.rs +++ b/src/api/control/endpoints/webrtc_play_endpoint.rs @@ -5,12 +5,14 @@ use std::convert::TryFrom; use derive_more::{Display, From, Into}; +use failure::Fail; use medea_control_api_proto::grpc::medea as proto; use serde::{de::Deserializer, Deserialize}; use crate::api::control::{ callback::url::CallbackUrl, refs::SrcUri, TryFromProtobufError, }; +use std::marker::PhantomData; /// ID of [`WebRtcPlayEndpoint`]. #[derive( @@ -18,9 +20,20 @@ use crate::api::control::{ )] pub struct WebRtcPlayId(String); +#[derive(Debug, Default, Clone)] +pub struct Unvalidated; + +#[derive(Debug, Clone)] +pub struct Validated; + +#[derive(Debug, Fail, Display)] +pub enum ValidationError { + ForceRelayShouldBeEnabled, +} + /// Media element which is able to play media data for client via WebRTC. -#[derive(Clone, Debug)] -pub struct WebRtcPlayEndpoint { +#[derive(Clone, Deserialize, Debug)] +pub struct WebRtcPlayEndpoint { /// Source URI in format `local://{room_id}/{member_id}/{endpoint_id}`. pub src: SrcUri, @@ -30,9 +43,33 @@ pub struct WebRtcPlayEndpoint { /// Option to relay all media through a TURN server forcibly. pub force_relay: bool, + + #[serde(skip)] + #[serde(bound = "T: From + Default")] + _validation_state: T, } -impl TryFrom<&proto::WebRtcPlayEndpoint> for WebRtcPlayEndpoint { +impl WebRtcPlayEndpoint { + pub fn validate( + self, + ) -> Result, ValidationError> { + if !self.force_relay + && (self.on_start.is_some() || self.on_stop.is_some()) + { + Err(ValidationError::ForceRelayShouldBeEnabled) + } else { + Ok(WebRtcPlayEndpoint { + src: self.src, + on_start: self.on_start, + on_stop: self.on_stop, + force_relay: self.force_relay, + _validation_state: Validated, + }) + } + } +} + +impl TryFrom<&proto::WebRtcPlayEndpoint> for WebRtcPlayEndpoint { type Error = TryFromProtobufError; fn try_from( @@ -47,91 +84,14 @@ impl TryFrom<&proto::WebRtcPlayEndpoint> for WebRtcPlayEndpoint { .map(CallbackUrl::try_from) .transpose()?; - if !value.force_relay && (on_start.is_some() || on_stop.is_some()) { - return Err( - TryFromProtobufError::CallbackNotSupportedInNotRelayMode, - ); - } - - Ok(Self { + let unvalidated = WebRtcPlayEndpoint { src: SrcUri::try_from(value.src.clone())?, force_relay: value.force_relay, on_stop, on_start, - }) - } -} - -impl<'de> Deserialize<'de> for WebRtcPlayEndpoint { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - use serde::de::Error as _; - - let ev = serde_json::Value::deserialize(deserializer)?; - let map = ev.as_object().ok_or_else(|| { - D::Error::custom(format!( - "unable to deserialize ClientMsg [{:?}]", - &ev - )) - })?; - - let src = map - .get("src") - .ok_or_else(|| D::Error::custom(format!("missing field `src`")))?; - let src = SrcUri::deserialize(src).map_err(|e| { - D::Error::custom(format!( - "error while deserialization of `src` field: {:?}", - e - )) - })?; - let force_relay = map - .get("force_relay") - .and_then(|force_relay| force_relay.as_bool()) - .unwrap_or_default(); - - let on_start = if let Some(on_start) = map.get("on_start") { - if !force_relay { - return Err(D::Error::custom(format!( - "`on_start` callback not supported while `force_relay` != \ - `true`" - ))); - } else { - Some(CallbackUrl::deserialize(on_start).map_err(|e| { - D::Error::custom(format!( - "error while deserialization of `on_start` field: {:?}", - e - )) - })?) - } - } else { - None + _validation_state: Unvalidated, }; - let on_stop = if let Some(on_stop) = map.get("on_stop") { - if !force_relay { - return Err(D::Error::custom(format!( - "`on_stop` callback not supported while `force_relay` != \ - `true`" - ))); - } else { - Some(CallbackUrl::deserialize(on_stop).map_err(|e| { - D::Error::custom(format!( - "error while deserialization of `on_stop` field: {:?}", - e - )) - })?) - } - } else { - None - }; - - Ok(Self { - src, - force_relay, - on_start, - on_stop, - }) + Ok(unvalidated.validate()?) } } diff --git a/src/api/control/error_codes.rs b/src/api/control/error_codes.rs index 00c1183b4..91d3a7611 100644 --- a/src/api/control/error_codes.rs +++ b/src/api/control/error_codes.rs @@ -12,6 +12,7 @@ use medea_control_api_proto::grpc::medea as proto; use crate::{ api::control::{ callback::url::CallbackUrlParseError, + endpoints::webrtc_play_endpoint::ValidationError, grpc::server::GrpcControlApiError, refs::{ fid::ParseFidError, local_uri::LocalUriParseError, @@ -350,6 +351,19 @@ impl From for ErrorResponse { CallbackNotSupportedInNotRelayMode => { Self::without_id(ErrorCode::CallbackNotSupportedInNotRelayMode) } + SpecValidationError(e) => e.into(), + } + } +} + +impl From for ErrorResponse { + fn from(err: ValidationError) -> Self { + use ValidationError::*; + + match err { + ForceRelayShouldBeEnabled => { + Self::without_id(ErrorCode::CallbackNotSupportedInNotRelayMode) + } } } } diff --git a/src/api/control/member.rs b/src/api/control/member.rs index ab57f70b7..a15ee0705 100644 --- a/src/api/control/member.rs +++ b/src/api/control/member.rs @@ -12,7 +12,9 @@ use serde::Deserialize; use crate::api::control::{ callback::url::CallbackUrl, endpoints::{ - webrtc_play_endpoint::WebRtcPlayEndpoint, + webrtc_play_endpoint::{ + Unvalidated, Validated, ValidationError, WebRtcPlayEndpoint, + }, webrtc_publish_endpoint::{WebRtcPublishEndpoint, WebRtcPublishId}, }, pipeline::Pipeline, @@ -32,7 +34,7 @@ pub struct Id(pub String); /// [`Member`]: crate::signalling::elements::member::Member #[derive(Clone, Deserialize, Debug)] #[serde(tag = "kind")] -pub enum MemberElement { +pub enum MemberElement { /// Represent [`WebRtcPublishEndpoint`]. /// Can transform into [`EndpointSpec`] enum by `EndpointSpec::try_from`. /// @@ -43,14 +45,30 @@ pub enum MemberElement { /// Can transform into [`EndpointSpec`] enum by `EndpointSpec::try_from`. /// /// [`EndpointSpec`]: crate::api::control::endpoints::EndpointSpec - WebRtcPlayEndpoint { spec: WebRtcPlayEndpoint }, + #[serde(bound = "T: From + Default")] + WebRtcPlayEndpoint { spec: WebRtcPlayEndpoint }, +} + +impl MemberElement { + pub fn validate(self) -> Result, ValidationError> { + match self { + MemberElement::WebRtcPublishEndpoint { spec } => { + Ok(MemberElement::WebRtcPublishEndpoint { spec }) + } + MemberElement::WebRtcPlayEndpoint { spec } => { + Ok(MemberElement::WebRtcPlayEndpoint { + spec: spec.validate()?, + }) + } + } + } } /// Newtype for [`RoomElement::Member`] variant. #[derive(Clone, Debug)] pub struct MemberSpec { /// Spec of this `Member`. - pipeline: Pipeline, + pipeline: Pipeline>, /// Credentials to authorize `Member` with. credentials: String, @@ -62,8 +80,8 @@ pub struct MemberSpec { on_leave: Option, } -impl Into for MemberSpec { - fn into(self) -> RoomElement { +impl Into> for MemberSpec { + fn into(self) -> RoomElement { RoomElement::Member { spec: self.pipeline, credentials: self.credentials, @@ -77,7 +95,8 @@ impl MemberSpec { /// Returns all [`WebRtcPlayEndpoint`]s of this [`MemberSpec`]. pub fn play_endpoints( &self, - ) -> impl Iterator { + ) -> impl Iterator)> + { self.pipeline.iter().filter_map(|(id, e)| match e { MemberElement::WebRtcPlayEndpoint { spec } => { Some((id.clone().into(), spec)) @@ -213,12 +232,12 @@ macro_rules! impl_try_from_proto_for_member { impl_try_from_proto_for_member!(proto::room::element::El); impl_try_from_proto_for_member!(proto::create_request::El); -impl TryFrom<&RoomElement> for MemberSpec { +impl TryFrom<&RoomElement> for MemberSpec { type Error = TryFromElementError; // TODO: delete this allow when some new RoomElement will be added. #[allow(unreachable_patterns)] - fn try_from(from: &RoomElement) -> Result { + fn try_from(from: &RoomElement) -> Result { match from { RoomElement::Member { spec, diff --git a/src/api/control/mod.rs b/src/api/control/mod.rs index 34315cf87..fd38cfc18 100644 --- a/src/api/control/mod.rs +++ b/src/api/control/mod.rs @@ -38,6 +38,10 @@ pub use self::{ member::{Id as MemberId, MemberSpec}, room::{Id as RoomId, RoomElement, RoomSpec}, }; +use crate::api::control::endpoints::webrtc_play_endpoint::{ + Unvalidated, Validated, ValidationError, +}; +use std::collections::HashMap; /// Errors which may occur while deserializing protobuf spec. #[derive(Debug, Fail, Display)] @@ -75,6 +79,8 @@ pub enum TryFromProtobufError { CallbackUrlParseErr(CallbackUrlParseError), CallbackNotSupportedInNotRelayMode, + + SpecValidationError(ValidationError), } impl From for TryFromProtobufError { @@ -89,20 +95,47 @@ impl From for TryFromProtobufError { } } +impl From for TryFromProtobufError { + fn from(from: ValidationError) -> Self { + Self::SpecValidationError(from) + } +} + /// Root elements of [Control API] spec. /// /// [Control API]: https://tinyurl.com/yxsqplq7 #[derive(Clone, Deserialize, Debug)] #[serde(tag = "kind")] -pub enum RootElement { +pub enum RootElement { /// Represents [`RoomSpec`]. /// Can transform into [`RoomSpec`] by `RoomSpec::try_from`. Room { id: RoomId, - spec: Pipeline, + #[serde(bound = "T: From + Default")] + spec: Pipeline>, }, } +impl RootElement { + pub fn validate(self) -> Result, ValidationError> { + match self { + RootElement::Room { id, spec } => { + let validated_spec = spec + .into_iter() + .map(|(key, value)| { + value.validate().map(move |res| (key, res)) + }) + .collect::, _>>()?; + + Ok(RootElement::Room { + id, + spec: Pipeline::new(validated_spec), + }) + } + } + } +} + /// Errors that can occur when we try transform some spec from `Element`. /// This error used in all [`TryFrom`] of Control API. /// @@ -156,6 +189,8 @@ pub enum LoadStaticControlSpecsError { /// [Control API]: https://tinyurl.com/yxsqplq7 #[display(fmt = "Error while deserialization static spec. {:?}", _0)] YamlDeserializationError(serde_yaml::Error), + + SpecValidationError(ValidationError), } impl From for LoadStaticControlSpecsError { @@ -176,6 +211,12 @@ impl From for LoadStaticControlSpecsError { } } +impl From for LoadStaticControlSpecsError { + fn from(err: ValidationError) -> Self { + Self::SpecValidationError(err) + } +} + /// Loads [`RoomSpec`] from file with YAML format. /// /// # Errors @@ -194,8 +235,8 @@ pub fn load_from_yaml_file>( let mut file = File::open(path)?; let mut buf = String::new(); file.read_to_string(&mut buf)?; - let parsed: RootElement = serde_yaml::from_str(&buf)?; - let room = RoomSpec::try_from(&parsed)?; + let unvalidated: RootElement = serde_yaml::from_str(&buf)?; + let room = RoomSpec::try_from(&unvalidated.validate()?)?; Ok(room) } diff --git a/src/api/control/pipeline.rs b/src/api/control/pipeline.rs index d94d1ad52..1d760328d 100644 --- a/src/api/control/pipeline.rs +++ b/src/api/control/pipeline.rs @@ -9,6 +9,7 @@ use std::{ }; use serde::Deserialize; +use std::collections::hash_map::IntoIter; /// Entity that represents some pipeline of spec. #[derive(Clone, Deserialize, Debug)] @@ -44,3 +45,13 @@ impl<'a, K: Eq + Hash, V> IntoIterator for &'a Pipeline { self.pipeline.iter() } } + +impl IntoIterator for Pipeline { + type IntoIter = IntoIter; + type Item = (K, V); + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.pipeline.into_iter() + } +} diff --git a/src/api/control/room.rs b/src/api/control/room.rs index 3e2647e70..792547201 100644 --- a/src/api/control/room.rs +++ b/src/api/control/room.rs @@ -17,6 +17,9 @@ use super::{ pipeline::Pipeline, MemberId, RootElement, TryFromElementError, }; +use crate::api::control::endpoints::webrtc_play_endpoint::{ + Unvalidated, Validated, ValidationError, +}; /// ID of [`Room`]. /// @@ -29,17 +32,45 @@ pub struct Id(pub String); /// [`Room`]: crate::signalling::room::Room #[derive(Clone, Deserialize, Debug)] #[serde(tag = "kind")] -pub enum RoomElement { +pub enum RoomElement { /// Represent [`MemberSpec`]. /// Can transform into [`MemberSpec`] by `MemberSpec::try_from`. Member { - spec: Pipeline, + #[serde(bound = "T: From + Default")] + spec: Pipeline>, credentials: String, on_leave: Option, on_join: Option, }, } +impl RoomElement { + pub fn validate(self) -> Result, ValidationError> { + match self { + RoomElement::Member { + spec, + credentials, + on_leave, + on_join, + } => { + let validated_spec = spec + .into_iter() + .map(|(key, value)| { + value.validate().map(move |res| (key, res)) + }) + .collect::, _>>()?; + + Ok(RoomElement::Member { + credentials, + on_leave, + on_join, + spec: Pipeline::new(validated_spec), + }) + } + } + } +} + /// [Control API]'s `Room` element specification. /// /// Newtype for [`RootElement::Room`]. @@ -48,7 +79,7 @@ pub enum RoomElement { #[derive(Clone, Debug)] pub struct RoomSpec { pub id: Id, - pub pipeline: Pipeline, + pub pipeline: Pipeline>, } impl TryFrom for RoomSpec { @@ -114,12 +145,12 @@ impl RoomSpec { } } -impl TryFrom<&RootElement> for RoomSpec { +impl TryFrom<&RootElement> for RoomSpec { type Error = TryFromElementError; // TODO: delete this allow when some new RootElement will be added. #[allow(unreachable_patterns)] - fn try_from(from: &RootElement) -> Result { + fn try_from(from: &RootElement) -> Result { match from { RootElement::Room { id, spec } => Ok(Self { id: id.clone(), diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index 3078a0b73..5cadfd2d1 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -30,6 +30,7 @@ use super::endpoints::{ webrtc::{WebRtcPlayEndpoint, WebRtcPublishEndpoint}, Endpoint, }; +use crate::api::control::endpoints::webrtc_play_endpoint::Validated; /// Errors which may occur while loading [`Member`]s from [`RoomSpec`]. #[derive(Debug, Display, Fail)] @@ -353,7 +354,7 @@ impl Member { pub fn create_sink( member: &Rc, id: WebRtcPlayId, - spec: WebRtcPlayEndpointSpec, + spec: WebRtcPlayEndpointSpec, ) { let src = member.get_src_by_id(&spec.src.endpoint_id).unwrap(); diff --git a/src/signalling/room.rs b/src/signalling/room.rs index ab9422496..7969d1e30 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -29,6 +29,7 @@ use crate::{ OnJoinEvent, OnLeaveEvent, OnLeaveReason, }, endpoints::{ + webrtc_play_endpoint::Validated, WebRtcPlayEndpoint as WebRtcPlayEndpointSpec, WebRtcPublishEndpoint as WebRtcPublishEndpointSpec, }, @@ -610,7 +611,7 @@ impl Room { &mut self, member_id: &MemberId, endpoint_id: WebRtcPlayId, - spec: WebRtcPlayEndpointSpec, + spec: WebRtcPlayEndpointSpec, ctx: &mut Context, ) -> Result<(), RoomError> { let member = self.members.get_member(&member_id)?; diff --git a/src/turn/coturn_stats.rs b/src/turn/coturn_stats.rs index 9c5cfc769..526fc3d9d 100644 --- a/src/turn/coturn_stats.rs +++ b/src/turn/coturn_stats.rs @@ -151,11 +151,9 @@ impl CoturnAllocationEvent { )), } } - _ => { - Err(CoturnEventParseError::UnsupportedEventType( - event_type.to_string(), - )) - } + _ => Err(CoturnEventParseError::UnsupportedEventType( + event_type.to_string(), + )), } } } @@ -237,7 +235,10 @@ pub enum CoturnEventParseError { FieldNotFoundInTrafficUpdate(String), /// Failed to parse traffic event stat metadata. - #[display(fmt = "Failed to parse traffic stat '{}' from traffic event.", _0)] + #[display( + fmt = "Failed to parse traffic stat '{}' from traffic event.", + _0 + )] FailedToParseTrafficMap(String), /// Status is empty. From 938d9227e43c6f4df46892448bf6f3f7f3ea8f91 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 12:50:04 +0200 Subject: [PATCH 037/224] add timeouts to config --- src/conf/turn.rs | 36 ++++++++++++++++++++++++------------ src/turn/cli.rs | 32 +++++++++++--------------------- src/turn/service.rs | 1 + 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/conf/turn.rs b/src/conf/turn.rs index 438842c62..d6abc8580 100644 --- a/src/conf/turn.rs +++ b/src/conf/turn.rs @@ -6,7 +6,9 @@ use std::{ time::Duration, }; -use deadpool::managed::Timeouts as PoolTimeouts; +use deadpool::managed::{ + PoolConfig as DeadpoolPoolConfig, Timeouts as DeadpoolTimeouts, +}; use serde::{Deserialize, Serialize}; use smart_default::SmartDefault; @@ -87,29 +89,35 @@ pub struct CoturnCli { /// Password for authorize on Coturn server telnet interface. #[default(String::from("turn"))] pub pass: String, - /// Coturn connection timeouts. - pub timeouts: Timeouts, + /// Connection pool config. + pub pool: PoolConfig, } -/// [Deadpool] connection pool timeouts. +/// [Deadpool] connection pool config. /// /// [Deadpool]: https://crates.io/crates/deadpool -#[derive(Clone, Debug, Deserialize, Serialize, SmartDefault)] +#[derive(Copy, Clone, Debug, Deserialize, Serialize, SmartDefault)] #[serde(default)] -pub struct Timeouts { +pub struct PoolConfig { + /// Maximum size of the pool + #[default = 16] + pub max_size: usize, + /// Timeout when waiting for available connection to become available. #[default(Some(Duration::from_secs(5)))] #[serde(with = "humantime_serde")] pub wait: Option, + /// Timeout when creating a new connection. #[default(Some(Duration::from_secs(5)))] #[serde(with = "humantime_serde")] pub create: Option, + /// Timeout when recycling connection. #[default(Some(Duration::from_secs(5)))] #[serde(with = "humantime_serde")] pub recycle: Option, } -impl Into for &Timeouts { - fn into(self) -> PoolTimeouts { +impl Into for PoolConfig { + fn into(self) -> DeadpoolPoolConfig { let wait = self.wait.and_then(|wait| { if wait.as_nanos() == 0 { None @@ -131,10 +139,14 @@ impl Into for &Timeouts { Some(recycle) } }); - PoolTimeouts { - wait, - create, - recycle, + + DeadpoolPoolConfig { + max_size: self.max_size, + timeouts: DeadpoolTimeouts { + wait, + create, + recycle, + }, } } } diff --git a/src/turn/cli.rs b/src/turn/cli.rs index ae8cfd851..2a3c47197 100644 --- a/src/turn/cli.rs +++ b/src/turn/cli.rs @@ -1,7 +1,7 @@ -use std::{fmt, ops::DerefMut, time::Duration}; +use std::{fmt, ops::DerefMut}; use coturn_telnet::{CoturnTelnetError, Manager, Pool, PoolError}; -use deadpool::managed::{PoolConfig, Timeouts}; +use deadpool::managed::PoolConfig; use derive_more::{Display, From}; use failure::Fail; @@ -21,26 +21,16 @@ pub enum CoturnCliError { /// /// [Coturn]: https://github.com/coturn/coturn #[derive(Clone)] -pub struct CoturnTelnetClient { - pool: Pool, -} +pub struct CoturnTelnetClient(Pool); impl CoturnTelnetClient { /// Creates new [`CoturnTelnetClient`]. - pub fn new(addr: (String, u16), pass: String) -> Self { - let manager = Manager::new(addr, pass); - // TODO: to conf - let config = PoolConfig { - max_size: 16, - timeouts: Timeouts { - wait: Some(Duration::from_secs(5)), - create: Some(Duration::from_secs(5)), - recycle: Some(Duration::from_secs(5)), - }, - }; - Self { - pool: Pool::from_config(manager, config), - } + pub fn new( + addr: (String, u16), + pass: String, + pool_config: PoolConfig, + ) -> Self { + Self(Pool::from_config(Manager::new(addr, pass), pool_config)) } /// Forcefully closes provided [`IceUser`]s sessions on Coturn server. @@ -48,7 +38,7 @@ impl CoturnTelnetClient { &self, users: &[&IceUser], ) -> Result<(), CoturnCliError> { - let mut connection = self.pool.get().await?; + let mut connection = self.0.get().await?; for user in users { let sessions = connection .deref_mut() @@ -64,7 +54,7 @@ impl CoturnTelnetClient { impl fmt::Debug for CoturnTelnetClient { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("CoturnTelnetClient") - .field("pool", &self.pool.status()) + .field("pool", &self.0.status()) .finish() } } diff --git a/src/turn/service.rs b/src/turn/service.rs index 42a62c75d..91d0284f0 100644 --- a/src/turn/service.rs +++ b/src/turn/service.rs @@ -173,6 +173,7 @@ pub fn new_turn_auth_service<'a>( let coturn_cli = CoturnTelnetClient::new( (cf.cli.ip.to_string(), cf.cli.port), cf.cli.pass.clone(), + cf.cli.pool.into(), ); let turn_service = Service { From 033b97a93649b8ce295bf1f2575b86a10f67af47 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 13:34:30 +0200 Subject: [PATCH 038/224] add timeouts to config --- config.toml | 14 +++++++++---- src/conf/turn.rs | 53 +++++++++++++++++++++++++----------------------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/config.toml b/config.toml index 13cce3ede..0b7325cc0 100644 --- a/config.toml +++ b/config.toml @@ -144,25 +144,31 @@ # Default: # pass = "turn" -[turn.cli.timeouts] +[turn.cli.pool] +# Maximum connection pool size. +# +# Env var: MEDEA_TURN__CLI__POOL__MAX_SIZE +# Default: +# max_size = 16 + # Timeout when waiting for an available connection. 0 means no timeout and is # not recommended. # -# Env var: MEDEA_TURN__CLI__TIMEOUTS__WAIT +# Env var: MEDEA_TURN__CLI__POOL__WAIT # Default: # wait = "5s" # Timeout when creating a new connection. 0 means no timeout and is not # recommended. # -# Env var: MEDEA_TURN__CLI__TIMEOUTS__CREATE +# Env var: MEDEA_TURN__CLI__POOL__CREATE # Default: # create = "5s" # Timeout when recycling connection. 0 means no timeout and is not # recommended. # -# Env var: MEDEA_TURN__CLI__TIMEOUTS__RECYCLE +# Env var: MEDEA_TURN__CLI__POLL__RECYCLE # Default: # recycle = "5s" diff --git a/src/conf/turn.rs b/src/conf/turn.rs index d6abc8580..12a5f21d4 100644 --- a/src/conf/turn.rs +++ b/src/conf/turn.rs @@ -68,6 +68,7 @@ pub struct Redis { /// The database number to use. This is usually 0. #[default = 0] pub db_number: i64, + //TODO: replace with PoolConfig /// The duration to wait to start a connection before returning err. #[default(Duration::from_secs(5))] #[serde(with = "humantime_serde")] @@ -241,53 +242,55 @@ mod spec { #[test] #[serial] - fn coturn_cli_timeouts() { + fn coturn_cli_pool() { let default_conf = Conf::default(); let env_conf: Conf = overrided_by_env_conf!( - "MEDEA_TURN__CLI__TIMEOUTS__WAIT" => "1s", - "MEDEA_TURN__CLI__TIMEOUTS__CREATE" => "2s", - "MEDEA_TURN__CLI__TIMEOUTS__RECYCLE" => "3s", + "MEDEA_TURN__CLI__POOL__MAX_SIZE" => "10", + "MEDEA_TURN__CLI__POOL__WAIT" => "1s", + "MEDEA_TURN__CLI__POOL__CREATE" => "2s", + "MEDEA_TURN__CLI__POLL__RECYCLE" => "3s", ); assert_ne!( - default_conf.turn.cli.timeouts.wait, - env_conf.turn.cli.timeouts.wait + default_conf.turn.cli.pool.max_size, + env_conf.turn.cli.pool.max_size ); assert_ne!( - default_conf.turn.cli.timeouts.create, - env_conf.turn.cli.timeouts.create + default_conf.turn.cli.pool.wait, + env_conf.turn.cli.pool.wait ); assert_ne!( - default_conf.turn.cli.timeouts.recycle, - env_conf.turn.cli.timeouts.recycle + default_conf.turn.cli.pool.create, + env_conf.turn.cli.pool.create ); - - assert_eq!( - env_conf.turn.cli.timeouts.wait, - Some(Duration::from_secs(1)) - ); - assert_eq!( - env_conf.turn.cli.timeouts.create, - Some(Duration::from_secs(2)) + assert_ne!( + default_conf.turn.cli.pool.recycle, + env_conf.turn.cli.pool.recycle ); + + assert_eq!(env_conf.turn.cli.pool.max_size, 10); + assert_eq!(env_conf.turn.cli.pool.wait, Some(Duration::from_secs(1))); + assert_eq!(env_conf.turn.cli.pool.create, Some(Duration::from_secs(2))); assert_eq!( - env_conf.turn.cli.timeouts.recycle, + env_conf.turn.cli.pool.recycle, Some(Duration::from_secs(3)) ); } #[test] - fn into_pool_timeouts() { - let timeouts = Timeouts { + fn into_pool_config() { + let pool_config = PoolConfig { + max_size: 6, wait: None, create: Some(Duration::from_secs(0)), recycle: Some(Duration::from_secs(2)), }; - let timeouts: PoolTimeouts = (&timeouts).into(); + let pool_config: DeadpoolPoolConfig = pool_config.into(); - assert!(timeouts.wait.is_none()); - assert!(timeouts.create.is_none()); - assert_eq!(timeouts.recycle, Some(Duration::from_secs(2))); + assert_eq!(pool_config.max_size, 6); + assert!(pool_config.timeouts.wait.is_none()); + assert!(pool_config.timeouts.create.is_none()); + assert_eq!(pool_config.timeouts.recycle, Some(Duration::from_secs(2))); } } From 08afedeffe9a2d172c08c5a2fb0f94d969757250 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 11 Feb 2020 14:03:08 +0300 Subject: [PATCH 039/224] Add on_start on_stop to WebRtcPublishEndpoint --- src/api/control/endpoints/mod.rs | 6 +- .../endpoints/webrtc_publish_endpoint.rs | 67 +++++++++++++++++-- src/api/control/grpc/server.rs | 2 +- src/api/control/member.rs | 12 ++-- src/signalling/room.rs | 2 +- src/turn/coturn_stats.rs | 7 +- 6 files changed, 80 insertions(+), 16 deletions(-) diff --git a/src/api/control/endpoints/mod.rs b/src/api/control/endpoints/mod.rs index 996d9e79d..a3e955c9b 100644 --- a/src/api/control/endpoints/mod.rs +++ b/src/api/control/endpoints/mod.rs @@ -48,7 +48,7 @@ impl_from_into!(WebRtcPlayId); #[derive(Debug, From)] pub enum EndpointSpec { /// [`WebRtcPublishEndpoint`] element. - WebRtcPublish(WebRtcPublishEndpoint), + WebRtcPublish(WebRtcPublishEndpoint), /// [`WebRtcPlayEndpoint`] element. WebRtcPlay(WebRtcPlayEndpoint), @@ -81,7 +81,7 @@ impl TryFrom<(Id, proto::member::element::El)> for EndpointSpec { Ok(Self::WebRtcPlay(play)) } WebrtcPub(elem) => { - let publish = WebRtcPublishEndpoint::from(&elem); + let publish = WebRtcPublishEndpoint::try_from(&elem)?; Ok(Self::WebRtcPublish(publish)) } } @@ -101,7 +101,7 @@ impl TryFrom<(Id, proto::create_request::El)> for EndpointSpec { Ok(Self::WebRtcPlay(play)) } WebrtcPub(elem) => { - let publish = WebRtcPublishEndpoint::from(&elem); + let publish = WebRtcPublishEndpoint::try_from(&elem)?; Ok(Self::WebRtcPublish(publish)) } Member(_) | Room(_) => { diff --git a/src/api/control/endpoints/webrtc_publish_endpoint.rs b/src/api/control/endpoints/webrtc_publish_endpoint.rs index 1c0619805..64b75a98c 100644 --- a/src/api/control/endpoints/webrtc_publish_endpoint.rs +++ b/src/api/control/endpoints/webrtc_publish_endpoint.rs @@ -5,7 +5,16 @@ use derive_more::{Display, From, Into}; use serde::Deserialize; +use crate::api::control::{ + callback::url::CallbackUrl, + endpoints::webrtc_play_endpoint::{ + Unvalidated, Validated, ValidationError, + }, + member::MemberElement::WebRtcPlayEndpoint, + TryFromProtobufError, +}; use medea_control_api_proto::grpc::medea as proto; +use std::convert::TryFrom; /// ID of [`WebRtcPublishEndpoint`]. #[derive( @@ -53,23 +62,71 @@ impl Into for P2pMode { /// Media element which is able to publish media data for another client via /// WebRTC. #[derive(Clone, Deserialize, Debug)] -pub struct WebRtcPublishEndpoint { +pub struct WebRtcPublishEndpoint { /// Peer-to-peer mode of this [`WebRtcPublishEndpoint`]. pub p2p: P2pMode, /// Option to relay all media through a TURN server forcibly. #[serde(default)] pub force_relay: bool, + + pub on_start: Option, + + pub on_stop: Option, + + #[serde(skip)] + #[serde(bound = "T: From + Default")] + _validation_state: T, } -impl From<&proto::WebRtcPublishEndpoint> for WebRtcPublishEndpoint { - fn from(value: &proto::WebRtcPublishEndpoint) -> Self { - Self { +impl WebRtcPublishEndpoint { + pub fn validate( + self, + ) -> Result, ValidationError> { + if !self.force_relay + && (self.on_start.is_some() || self.on_stop.is_some()) + { + Err(ValidationError::ForceRelayShouldBeEnabled) + } else { + Ok(WebRtcPublishEndpoint { + on_start: self.on_start, + on_stop: self.on_stop, + force_relay: self.force_relay, + p2p: self.p2p, + _validation_state: Validated, + }) + } + } +} + +impl TryFrom<&proto::WebRtcPublishEndpoint> + for WebRtcPublishEndpoint +{ + type Error = TryFromProtobufError; + + fn try_from( + value: &proto::WebRtcPublishEndpoint, + ) -> Result { + let on_start = Some(value.on_start.clone()) + .filter(|s| !s.is_empty()) + .map(CallbackUrl::try_from) + .transpose()?; + let on_stop = Some(value.on_stop.clone()) + .filter(|s| !s.is_empty()) + .map(CallbackUrl::try_from) + .transpose()?; + + let unvalidated = WebRtcPublishEndpoint { p2p: P2pMode::from( proto::web_rtc_publish_endpoint::P2p::from_i32(value.p2p) .unwrap_or_default(), ), force_relay: value.force_relay, - } + on_start, + on_stop, + _validation_state: Unvalidated, + }; + + Ok(unvalidated.validate()?) } } diff --git a/src/api/control/grpc/server.rs b/src/api/control/grpc/server.rs index 07ab32262..f6272aaf9 100644 --- a/src/api/control/grpc/server.rs +++ b/src/api/control/grpc/server.rs @@ -189,7 +189,7 @@ impl ControlApiService { play.id.into(), ), proto::create_request::El::WebrtcPub(publish) => ( - Ok(WebRtcPublishEndpoint::from(&publish)) + WebRtcPublishEndpoint::try_from(&publish) .map(EndpointSpec::from), publish.id.into(), ), diff --git a/src/api/control/member.rs b/src/api/control/member.rs index a15ee0705..ac97df730 100644 --- a/src/api/control/member.rs +++ b/src/api/control/member.rs @@ -39,7 +39,8 @@ pub enum MemberElement { /// Can transform into [`EndpointSpec`] enum by `EndpointSpec::try_from`. /// /// [`EndpointSpec`]: crate::api::control::endpoints::EndpointSpec - WebRtcPublishEndpoint { spec: WebRtcPublishEndpoint }, + #[serde(bound = "T: From + Default")] + WebRtcPublishEndpoint { spec: WebRtcPublishEndpoint }, /// Represent [`WebRtcPlayEndpoint`]. /// Can transform into [`EndpointSpec`] enum by `EndpointSpec::try_from`. @@ -53,7 +54,9 @@ impl MemberElement { pub fn validate(self) -> Result, ValidationError> { match self { MemberElement::WebRtcPublishEndpoint { spec } => { - Ok(MemberElement::WebRtcPublishEndpoint { spec }) + Ok(MemberElement::WebRtcPublishEndpoint { + spec: spec.validate()?, + }) } MemberElement::WebRtcPlayEndpoint { spec } => { Ok(MemberElement::WebRtcPlayEndpoint { @@ -109,7 +112,7 @@ impl MemberSpec { pub fn get_publish_endpoint_by_id( &self, id: WebRtcPublishId, - ) -> Option<&WebRtcPublishEndpoint> { + ) -> Option<&WebRtcPublishEndpoint> { let e = self.pipeline.get(&id.into())?; if let MemberElement::WebRtcPublishEndpoint { spec } = e { Some(spec) @@ -121,7 +124,8 @@ impl MemberSpec { /// Returns all [`WebRtcPublishEndpoint`]s of this [`MemberSpec`]. pub fn publish_endpoints( &self, - ) -> impl Iterator { + ) -> impl Iterator)> + { self.pipeline.iter().filter_map(|(id, e)| match e { MemberElement::WebRtcPublishEndpoint { spec } => { Some((id.clone().into(), spec)) diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 7969d1e30..a9838d733 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -558,7 +558,7 @@ impl Room { &mut self, member_id: &MemberId, publish_id: WebRtcPublishId, - spec: &WebRtcPublishEndpointSpec, + spec: &WebRtcPublishEndpointSpec, ) -> Result<(), RoomError> { let member = self.members.get_member(&member_id)?; diff --git a/src/turn/coturn_stats.rs b/src/turn/coturn_stats.rs index 526fc3d9d..91e6c8fc8 100644 --- a/src/turn/coturn_stats.rs +++ b/src/turn/coturn_stats.rs @@ -46,8 +46,11 @@ impl CoturnAllocationEvent { event_type: &str, body: String, ) -> Result { + const TOTAL_TRAFFIC: &str = "total_traffic"; + const TRAFFIC: &str = "traffic"; + match event_type { - "total_traffic" | "traffic" => { + TOTAL_TRAFFIC | TRAFFIC => { let mut items: HashMap<&str, u64> = body .split(", ") .map(|i| { @@ -97,7 +100,7 @@ impl CoturnAllocationEvent { ) })?; - if event_type == "total_traffic" { + if event_type == TOTAL_TRAFFIC { Ok(CoturnAllocationEvent::TotalTraffic { received_bytes, received_packets, From e09d1f4613b9d9ca1a093b76a51d6da18c7acfea Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 15:44:05 +0200 Subject: [PATCH 040/224] fixes --- Cargo.toml | 2 +- config.toml | 4 ++-- src/conf/turn.rs | 30 +++++++++++++++--------------- src/media/ice_user.rs | 1 + src/signalling/participants.rs | 6 +++--- src/signalling/room.rs | 4 ++-- src/turn/mod.rs | 2 +- src/turn/service.rs | 3 ++- 8 files changed, 27 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3c61f9bf3..a96200bb5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ actix-web-actors = "2.0" async-trait = "0.1" chrono = "0.4" config = "0.10" -coturn-telnet = {path = "crates/coturn-telnet"} +coturn-telnet = { path = "crates/coturn-telnet" } deadpool = "0.5" deadpool-redis = "0.5" derive_more = "0.99" diff --git a/config.toml b/config.toml index 0b7325cc0..74e5b7bc4 100644 --- a/config.toml +++ b/config.toml @@ -165,10 +165,10 @@ # Default: # create = "5s" -# Timeout when recycling connection. 0 means no timeout and is not +# Timeout when recycling connection. 0 means no timeout and is not # recommended. # -# Env var: MEDEA_TURN__CLI__POLL__RECYCLE +# Env var: MEDEA_TURN__CLI__POOL__RECYCLE # Default: # recycle = "5s" diff --git a/src/conf/turn.rs b/src/conf/turn.rs index 12a5f21d4..27d2cce3c 100644 --- a/src/conf/turn.rs +++ b/src/conf/turn.rs @@ -68,23 +68,23 @@ pub struct Redis { /// The database number to use. This is usually 0. #[default = 0] pub db_number: i64, - //TODO: replace with PoolConfig + // TODO: replace with PoolConfig /// The duration to wait to start a connection before returning err. #[default(Duration::from_secs(5))] #[serde(with = "humantime_serde")] pub connection_timeout: Duration, } -/// Setting of [coturn] server telnet interface. +/// Settings of [Coturn] server telnet interface. /// -/// [coturn]: https://github.com/coturn/coturn +/// [Coturn]: https://github.com/coturn/coturn #[derive(Clone, Debug, Deserialize, Serialize, SmartDefault)] #[serde(default)] pub struct CoturnCli { - /// Coturn server IP address. Defaults to `127.0.0.1`. + /// Coturn server cli IP address. Defaults to `127.0.0.1`. #[default(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)))] pub ip: IpAddr, - /// Coturn server port. Defaults to `5766`. + /// Coturn server cli port. Defaults to `5766`. #[default = 5766] pub port: u16, /// Password for authorize on Coturn server telnet interface. @@ -225,7 +225,7 @@ mod spec { #[serial] fn coturn_cli() { let default_conf = Conf::default(); - let env_conf: Conf = overrided_by_env_conf!( + let env_conf = overrided_by_env_conf!( "MEDEA_TURN__CLI__IP" => "4.4.4.4", "MEDEA_TURN__CLI__PORT" => "1234", "MEDEA_TURN__CLI__PASS" => "clipass", @@ -244,11 +244,11 @@ mod spec { #[serial] fn coturn_cli_pool() { let default_conf = Conf::default(); - let env_conf: Conf = overrided_by_env_conf!( + let env_conf = overrided_by_env_conf!( "MEDEA_TURN__CLI__POOL__MAX_SIZE" => "10", "MEDEA_TURN__CLI__POOL__WAIT" => "1s", "MEDEA_TURN__CLI__POOL__CREATE" => "2s", - "MEDEA_TURN__CLI__POLL__RECYCLE" => "3s", + "MEDEA_TURN__CLI__POOL__RECYCLE" => "3s", ); assert_ne!( @@ -268,13 +268,13 @@ mod spec { env_conf.turn.cli.pool.recycle ); - assert_eq!(env_conf.turn.cli.pool.max_size, 10); - assert_eq!(env_conf.turn.cli.pool.wait, Some(Duration::from_secs(1))); - assert_eq!(env_conf.turn.cli.pool.create, Some(Duration::from_secs(2))); - assert_eq!( - env_conf.turn.cli.pool.recycle, - Some(Duration::from_secs(3)) - ); +// assert_eq!(env_conf.turn.cli.pool.max_size, 10); +// assert_eq!(env_conf.turn.cli.pool.wait, Some(Duration::from_secs(1))); +// assert_eq!(env_conf.turn.cli.pool.create, Some(Duration::from_secs(2))); +// assert_eq!( +// env_conf.turn.cli.pool.recycle, +// Some(Duration::from_secs(3)) +// ); } #[test] diff --git a/src/media/ice_user.rs b/src/media/ice_user.rs index 94c7680dd..e06805a13 100644 --- a/src/media/ice_user.rs +++ b/src/media/ice_user.rs @@ -7,6 +7,7 @@ use medea_client_api_proto::IceServer; use crate::api::control::RoomId; +/// Username for authorization on Turn server. #[derive(AsRef, Clone, Debug, Display, From, Into)] #[as_ref(forward)] pub struct IceUsername(String); diff --git a/src/signalling/participants.rs b/src/signalling/participants.rs index 6bfb24c93..1008afa6b 100644 --- a/src/signalling/participants.rs +++ b/src/signalling/participants.rs @@ -343,9 +343,9 @@ impl ParticipantService { match self.get_member_by_id(&member_id) { None => future::ok(()).boxed_local(), Some(member) => { - if let Some(turn_user) = member.take_ice_user() { + if let Some(ice_user) = member.take_ice_user() { let turn_service = self.turn_service.clone(); - async move { turn_service.delete(&[turn_user]).await } + async move { turn_service.delete(&[ice_user]).await } .boxed_local() } else { future::ok(()).boxed_local() @@ -389,7 +389,7 @@ impl ParticipantService { let turn_service = self.turn_service.clone(); let delete_ice_users = async move { if let Err(e) = turn_service.delete(ice_users.as_slice()).await { - error!("Error removing IceUser {:?}", e) + error!("Error removing IceUsers {:?}", e) }; }; diff --git a/src/signalling/room.rs b/src/signalling/room.rs index f5ea3c2eb..0f06ebc99 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -248,7 +248,7 @@ impl Room { sdp_offer: None, tracks: sender.tracks(), ice_servers, - force_relay: true, + force_relay: sender.is_force_relayed(), }; self.peers.add_peer(sender); Ok(Box::new( @@ -824,7 +824,7 @@ impl CommandHandler for Room { sdp_offer: Some(sdp_offer), tracks: to_peer.tracks(), ice_servers, - force_relay: true, + force_relay: to_peer.is_force_relayed(), }; self.peers.add_peer(from_peer); diff --git a/src/turn/mod.rs b/src/turn/mod.rs index bbf887586..d53d62330 100644 --- a/src/turn/mod.rs +++ b/src/turn/mod.rs @@ -2,7 +2,7 @@ //! //! [TURN]: https://webrtcglossary.com/turn -pub mod cli; +mod cli; pub mod repo; pub mod service; diff --git a/src/turn/service.rs b/src/turn/service.rs index 91d0284f0..168f5626b 100644 --- a/src/turn/service.rs +++ b/src/turn/service.rs @@ -70,6 +70,7 @@ struct Service { /// Turn credentials repository. turn_db: TurnDatabase, + /// Connection to Coturn server admin interface. coturn_cli: CoturnTelnetClient, /// TurnAuthRepo password. @@ -131,7 +132,7 @@ impl TurnAuthService for Service { } /// Deletes provided [`IceUser`]s from [`TurnDatabase`] and closes their - /// sessions on Coturn. + /// sessions on Coturn TURN server. async fn delete(&self, users: &[IceUser]) -> Result<(), TurnServiceErr> { if users.is_empty() { return Ok(()); From 04aea39872b4f83338f688fcf9fa342a8e6d155c Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 15:47:36 +0200 Subject: [PATCH 041/224] fixes --- src/conf/turn.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/conf/turn.rs b/src/conf/turn.rs index 27d2cce3c..0b6447a48 100644 --- a/src/conf/turn.rs +++ b/src/conf/turn.rs @@ -268,13 +268,13 @@ mod spec { env_conf.turn.cli.pool.recycle ); -// assert_eq!(env_conf.turn.cli.pool.max_size, 10); -// assert_eq!(env_conf.turn.cli.pool.wait, Some(Duration::from_secs(1))); -// assert_eq!(env_conf.turn.cli.pool.create, Some(Duration::from_secs(2))); -// assert_eq!( -// env_conf.turn.cli.pool.recycle, -// Some(Duration::from_secs(3)) -// ); + assert_eq!(env_conf.turn.cli.pool.max_size, 10); + assert_eq!(env_conf.turn.cli.pool.wait, Some(Duration::from_secs(1))); + assert_eq!(env_conf.turn.cli.pool.create, Some(Duration::from_secs(2))); + assert_eq!( + env_conf.turn.cli.pool.recycle, + Some(Duration::from_secs(3)) + ); } #[test] From 47aa64ad18f77dfc4fbd63c27207d943720b7e95 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 11 Feb 2020 16:20:50 +0200 Subject: [PATCH 042/224] k8s integration --- _dev/coturn/turnserver.conf | 1 + jason/demo/chart/medea-demo/templates/configmap.server.yaml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/_dev/coturn/turnserver.conf b/_dev/coturn/turnserver.conf index 47082fe91..32239a121 100644 --- a/_dev/coturn/turnserver.conf +++ b/_dev/coturn/turnserver.conf @@ -6,3 +6,4 @@ realm=medea redis-userdb="ip=127.0.0.1 port=6379 dbname=0 password=turn" user=USER:PASS cli-password=turn +cli-port=5766 diff --git a/jason/demo/chart/medea-demo/templates/configmap.server.yaml b/jason/demo/chart/medea-demo/templates/configmap.server.yaml index 391fccb50..8fde5d316 100644 --- a/jason/demo/chart/medea-demo/templates/configmap.server.yaml +++ b/jason/demo/chart/medea-demo/templates/configmap.server.yaml @@ -23,7 +23,6 @@ data: {{- $coturnConf := .Values.server.coturn.conf }} lt-cred-mech fingerprint - no-cli no-tls no-dtls realm=medea From 1e05b16f936846341d6e5963297b74e13005a059 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Wed, 12 Feb 2020 09:56:46 +0200 Subject: [PATCH 043/224] k8s --- .../demo/chart/medea-demo/templates/deployment.server.yaml | 7 +++++++ jason/demo/chart/medea-demo/templates/secret.server.yaml | 2 ++ jason/demo/chart/medea-demo/values.yaml | 4 ++++ jason/demo/staging.vals.yaml | 2 ++ 4 files changed, 15 insertions(+) diff --git a/jason/demo/chart/medea-demo/templates/deployment.server.yaml b/jason/demo/chart/medea-demo/templates/deployment.server.yaml index 4bec1198d..c041b8cbb 100644 --- a/jason/demo/chart/medea-demo/templates/deployment.server.yaml +++ b/jason/demo/chart/medea-demo/templates/deployment.server.yaml @@ -113,6 +113,8 @@ spec: - --relay-ip=$(EXTERNAL_IP) - --redis-userdb=ip=127.0.0.1 port={{ $coturnDb.conf.port | int }} dbname={{ .Values.server.conf.turn.db.redis.db_number }} password=$(MEDEA_TURN__DB__REDIS__PASS) - --user={{ .Values.server.conf.turn.user }}:$(MEDEA_TURN__PASS) + - --cli-port={{ $coturn.conf.cli_port | int }} + - --cli-password=$(MEDEA_TURN__CLI__PASS) {{- with $coturn.extraArgs }} {{- toYaml . | nindent 12 }} {{- end }} @@ -135,6 +137,11 @@ spec: secretKeyRef: name: {{ printf "%s.server.cred" (include "medea-demo.fullname" .) | quote }} key: MEDEA_TURN__DB__REDIS__PASS + - name: MEDEA_TURN__CLI__PASS + valueFrom: + secretKeyRef: + name: {{ printf "%s.server.cred" (include "medea-demo.fullname" .) | quote }} + key: MEDEA_TURN__CLI__PASS ports: - name: turn containerPort: {{ $coturn.conf.listening_port | int }} diff --git a/jason/demo/chart/medea-demo/templates/secret.server.yaml b/jason/demo/chart/medea-demo/templates/secret.server.yaml index d2e8017ea..7c62182b7 100644 --- a/jason/demo/chart/medea-demo/templates/secret.server.yaml +++ b/jason/demo/chart/medea-demo/templates/secret.server.yaml @@ -16,5 +16,7 @@ type: Opaque data: {{- $medeaConf := .Values.server.conf }} {{- $coturnDbConf := index .Values "server" "coturn-db" "conf" }} + {{- $coturnConf := index .Values "server" "coturn" "conf" }} MEDEA_TURN__PASS: {{ $medeaConf.turn.pass | b64enc | quote }} MEDEA_TURN__DB__REDIS__PASS: {{ $coturnDbConf.requirepass | b64enc | quote }} + MEDEA_TURN__CLI__PASS: {{ $coturnConf.cli_pass | b64enc | quote }} diff --git a/jason/demo/chart/medea-demo/values.yaml b/jason/demo/chart/medea-demo/values.yaml index 56fdb3f66..f0df97521 100644 --- a/jason/demo/chart/medea-demo/values.yaml +++ b/jason/demo/chart/medea-demo/values.yaml @@ -29,6 +29,8 @@ server: db: redis: db_number: 0 + cli: + port: 5766 deployment: revisionHistoryLimit: 0 @@ -82,6 +84,8 @@ server: # Coturn TURN server configuration. conf: listening_port: 3478 + cli_port: 5766 + cli_pass: turn # IP adress to be used by Coturn as `external-ip`. # If empty then `status.hostIP` of Pod will be used. external_ip: "" diff --git a/jason/demo/staging.vals.yaml b/jason/demo/staging.vals.yaml index 9af6bf98f..50cac4f7e 100644 --- a/jason/demo/staging.vals.yaml +++ b/jason/demo/staging.vals.yaml @@ -30,6 +30,8 @@ server: pullPolicy: Always conf: listening_port: 9934 + cli_port: 5766 + cli_pass: changeme coturn-db: image: From 0911d0e9f6bb14b133cc666ca93e7abaf1496718 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Wed, 12 Feb 2020 11:03:13 +0200 Subject: [PATCH 044/224] k8s [run ci] --- jason/demo/chart/medea-demo/templates/deployment.server.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/jason/demo/chart/medea-demo/templates/deployment.server.yaml b/jason/demo/chart/medea-demo/templates/deployment.server.yaml index c041b8cbb..19f8071da 100644 --- a/jason/demo/chart/medea-demo/templates/deployment.server.yaml +++ b/jason/demo/chart/medea-demo/templates/deployment.server.yaml @@ -62,6 +62,8 @@ spec: value: {{ $coturn.conf.listening_port | quote }} - name: MEDEA_TURN__DB__REDIS__PORT value: {{ $coturnDb.conf.port | quote }} + - name: MEDEA_TURN__CLI__PORT + value: {{ $coturn.conf.cli_port | quote }} envFrom: - secretRef: name: {{ printf "%s.server.cred" (include "medea-demo.fullname" .) | quote }} @@ -94,7 +96,7 @@ spec: imagePullPolicy: {{ $controlMock.image.pullPolicy | quote }} args: - --addr=0.0.0.0:{{ $controlMock.conf.bind_port | int }} - - --medea-addr=127.0.0.1:{{ .Values.server.conf.server.control.grpc.bind_port | int }} + - --medea-addr=http://127.0.0.1:{{ .Values.server.conf.server.control.grpc.bind_port | int }} env: - name: RUST_LOG value: {{ $controlMock.conf.log.level | quote }} From 1b7cd09d89b58f8bfa1f3dd3e6dcc42800634045 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Wed, 12 Feb 2020 11:34:47 +0200 Subject: [PATCH 045/224] changelog --- CHANGELOG.md | 2 ++ crates/coturn-telnet/CHANGELOG.md | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cb17f66b..04fb6cd73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,8 @@ All user visible changes to this project will be documented in this file. This p - `rpc.ping_interval` option to configure `Ping`s sending interval ([#75]). - Testing: - E2E tests for signalling ([#28]). +- Turn server integration: + - Turn sessions cancellation ([#84](/../../pull/84)). [#28]: /../../pull/28 [#33]: /../../pull/33 diff --git a/crates/coturn-telnet/CHANGELOG.md b/crates/coturn-telnet/CHANGELOG.md index 6421f07f6..677f967da 100644 --- a/crates/coturn-telnet/CHANGELOG.md +++ b/crates/coturn-telnet/CHANGELOG.md @@ -11,12 +11,13 @@ All user visible changes to this project will be documented in this file. This p ### Added -- Asynchronous [Coturn] client. -- Connection pool. -- Requests: +- Asynchronous [Coturn] client ([#84]). +- Connection pool ([#84]). +- Requests ([#84]): - `ps [username]`, that prints sessions, with optional exact user match. - `cs `, that forcefully cancels session. +[#28]: /../../pull/84 From 68dfa1bb1c65e9945abfde5a5b5e0f093e9dc054 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Wed, 12 Feb 2020 12:16:54 +0200 Subject: [PATCH 046/224] rename coturn-telnet to medea-coturn-telnet [run ci] --- Cargo.lock | 34 +++++++++---------- Cargo.toml | 4 +-- Dockerfile | 4 +-- .../CHANGELOG.md | 4 +-- .../Cargo.toml | 8 ++--- .../LICENSE-APACHE.md | 0 .../LICENSE-MIT.md | 0 .../README.md | 14 ++++---- .../src/codec.rs | 0 .../src/connection.rs | 0 .../src/lib.rs | 0 .../src/pool.rs | 0 src/turn/cli.rs | 2 +- 13 files changed, 35 insertions(+), 35 deletions(-) rename crates/{coturn-telnet => medea-coturn-telnet}/CHANGELOG.md (83%) rename crates/{coturn-telnet => medea-coturn-telnet}/Cargo.toml (83%) rename crates/{coturn-telnet => medea-coturn-telnet}/LICENSE-APACHE.md (100%) rename crates/{coturn-telnet => medea-coturn-telnet}/LICENSE-MIT.md (100%) rename crates/{coturn-telnet => medea-coturn-telnet}/README.md (54%) rename crates/{coturn-telnet => medea-coturn-telnet}/src/codec.rs (100%) rename crates/{coturn-telnet => medea-coturn-telnet}/src/connection.rs (100%) rename crates/{coturn-telnet => medea-coturn-telnet}/src/lib.rs (100%) rename crates/{coturn-telnet => medea-coturn-telnet}/src/pool.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index f951d9c4b..afa6ad101 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -621,22 +621,6 @@ name = "copyless" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "coturn-telnet" -version = "0.1.0-dev" -dependencies = [ - "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-test 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crc32fast" version = "1.2.0" @@ -1368,7 +1352,6 @@ dependencies = [ "awc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "config 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "coturn-telnet 0.1.0-dev", "deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "deadpool-redis 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "derive_builder 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1380,6 +1363,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "medea-client-api-proto 0.2.0-dev", "medea-control-api-proto 0.1.0-dev", + "medea-coturn-telnet 0.1.0-dev", "medea-macro 0.2.0-dev", "mockall 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1446,6 +1430,22 @@ dependencies = [ "tonic-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "medea-coturn-telnet" +version = "0.1.0-dev" +dependencies = [ + "async-trait 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "deadpool 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-test 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "medea-jason" version = "0.2.0-dev" diff --git a/Cargo.toml b/Cargo.toml index a96200bb5..ed1accb11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ include = ["/src/", "/Cargo.*", "/CHANGELOG.md", "/LICENSE.md", "/README.md"] [workspace] members = [ "crates/medea-macro", - "crates/coturn-telnet", + "crates/medea-coturn-telnet", "jason", "mock/control-api", "proto/client-api", @@ -33,7 +33,7 @@ actix-web-actors = "2.0" async-trait = "0.1" chrono = "0.4" config = "0.10" -coturn-telnet = { path = "crates/coturn-telnet" } +medea-coturn-telnet = { path = "crates/medea-coturn-telnet" } deadpool = "0.5" deadpool-redis = "0.5" derive_more = "0.99" diff --git a/Dockerfile b/Dockerfile index 644ca68d1..4c87ed0e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,7 +26,7 @@ RUN apt-get update \ # Prepare Cargo workspace for building dependencies only. COPY crates/medea-macro/Cargo.toml /app/crates/medea-macro/ -COPY crates/coturn-telnet/Cargo.toml /app/crates/coturn-telnet/ +COPY crates/medea-coturn-telnet/Cargo.toml /app/crates/medea-coturn-telnet/ COPY mock/control-api/Cargo.toml /app/mock/control-api/ COPY proto/client-api/Cargo.toml /app/proto/client-api/ COPY proto/control-api/Cargo.toml /app/proto/control-api/ @@ -39,7 +39,7 @@ COPY jason/Cargo.toml /app/jason/ COPY Cargo.toml Cargo.lock /app/ WORKDIR /app/ RUN mkdir -p crates/medea-macro/src/ && touch crates/medea-macro/src/lib.rs \ - && mkdir -p crates/coturn-telnet/src/ && touch crates/coturn-telnet/src/lib.rs \ + && mkdir -p crates/medea-coturn-telnet/src/ && touch crates/medea-coturn-telnet/src/lib.rs \ && mkdir -p mock/control-api/src/ && touch mock/control-api/src/lib.rs \ && mkdir -p proto/client-api/src/ && touch proto/client-api/src/lib.rs \ && mkdir -p proto/control-api/src/ && touch proto/control-api/src/lib.rs \ diff --git a/crates/coturn-telnet/CHANGELOG.md b/crates/medea-coturn-telnet/CHANGELOG.md similarity index 83% rename from crates/coturn-telnet/CHANGELOG.md rename to crates/medea-coturn-telnet/CHANGELOG.md index 677f967da..ef0b23d12 100644 --- a/crates/coturn-telnet/CHANGELOG.md +++ b/crates/medea-coturn-telnet/CHANGELOG.md @@ -1,4 +1,4 @@ -`coturn-telnet` changelog +`medea-coturn-telnet` changelog ======================= All user visible changes to this project will be documented in this file. This project uses [Semantic Versioning 2.0.0]. @@ -7,7 +7,7 @@ All user visible changes to this project will be documented in this file. This p ## TBD [0.1.0] · 2019-??-?? -[0.1.0]: /../../tree/coturn-telnet-0.1.0/crates/coturn-telnet +[0.1.0]: /../../tree/medea-coturn-telnet-0.1.0/crates/medea-coturn-telnet ### Added diff --git a/crates/coturn-telnet/Cargo.toml b/crates/medea-coturn-telnet/Cargo.toml similarity index 83% rename from crates/coturn-telnet/Cargo.toml rename to crates/medea-coturn-telnet/Cargo.toml index d545405d8..65d3ad873 100644 --- a/crates/coturn-telnet/Cargo.toml +++ b/crates/medea-coturn-telnet/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "coturn-telnet" +name = "medea-coturn-telnet" version = "0.1.0-dev" edition = "2018" description = "Coturn TURN server telnet client" authors = ["Instrumentisto Team "] license = "MIT/Apache-2.0" -documentation = "https://docs.rs/coturn-telnet" -homepage = "https://github.com/instrumentisto/medea/tree/master/crates/coturn-telnet" -repository = "https://github.com/instrumentisto/medea/tree/master/crates/coturn-telnet" +documentation = "https://docs.rs/medea-coturn-telnet" +homepage = "https://github.com/instrumentisto/medea/tree/master/crates/medea-coturn-telnet" +repository = "https://github.com/instrumentisto/medea/tree/master/crates/medea-coturn-telnet" readme = "README.md" keywords = ["coturn", "telnet", "cli"] categories = ["web-programming"] diff --git a/crates/coturn-telnet/LICENSE-APACHE.md b/crates/medea-coturn-telnet/LICENSE-APACHE.md similarity index 100% rename from crates/coturn-telnet/LICENSE-APACHE.md rename to crates/medea-coturn-telnet/LICENSE-APACHE.md diff --git a/crates/coturn-telnet/LICENSE-MIT.md b/crates/medea-coturn-telnet/LICENSE-MIT.md similarity index 100% rename from crates/coturn-telnet/LICENSE-MIT.md rename to crates/medea-coturn-telnet/LICENSE-MIT.md diff --git a/crates/coturn-telnet/README.md b/crates/medea-coturn-telnet/README.md similarity index 54% rename from crates/coturn-telnet/README.md rename to crates/medea-coturn-telnet/README.md index 63dbe12a2..2a1b59a25 100644 --- a/crates/coturn-telnet/README.md +++ b/crates/medea-coturn-telnet/README.md @@ -1,11 +1,11 @@ -coturn-telnet +medea-coturn-telnet =========== -[![Crates.io](https://img.shields.io/crates/v/coturn-telnet)](https://crates.io/crates/coturn-telnet) -![Crates.io license](https://img.shields.io/crates/l/coturn-telnet) +[![Crates.io](https://img.shields.io/crates/v/medea-coturn-telnet)](https://crates.io/crates/medea-coturn-telnet) +![Crates.io license](https://img.shields.io/crates/l/medea-coturn-telnet) -[API Docs](https://docs.rs/coturn-telnet) | -[Changelog](https://github.com/instrumentisto/medea/blob/master/crates/coturn-telnet/CHANGELOG.md) +[API Docs](https://docs.rs/medea-coturn-telnet) | +[Changelog](https://github.com/instrumentisto/medea/blob/master/crates/medea-coturn-telnet/CHANGELOG.md) [Coturn] telnet admin interface client implementation. @@ -16,8 +16,8 @@ coturn-telnet This project is licensed under either of -- Apache License, Version 2.0, ([LICENSE-APACHE](https://github.com/instrumentisto/medea/blob/master/crates/coturn-telnet/LICENSE-APACHE.md) or http://www.apache.org/licenses/LICENSE-2.0) -- MIT license ([LICENSE-MIT](https://github.com/instrumentisto/medea/blob/master/crates/coturn-telnet/LICENSE-MIT.md) or http://opensource.org/licenses/MIT) +- Apache License, Version 2.0, ([LICENSE-APACHE](https://github.com/instrumentisto/medea/blob/master/crates/medea-coturn-telnet/LICENSE-APACHE.md) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](https://github.com/instrumentisto/medea/blob/master/crates/medea-coturn-telnet/LICENSE-MIT.md) or http://opensource.org/licenses/MIT) at your option. diff --git a/crates/coturn-telnet/src/codec.rs b/crates/medea-coturn-telnet/src/codec.rs similarity index 100% rename from crates/coturn-telnet/src/codec.rs rename to crates/medea-coturn-telnet/src/codec.rs diff --git a/crates/coturn-telnet/src/connection.rs b/crates/medea-coturn-telnet/src/connection.rs similarity index 100% rename from crates/coturn-telnet/src/connection.rs rename to crates/medea-coturn-telnet/src/connection.rs diff --git a/crates/coturn-telnet/src/lib.rs b/crates/medea-coturn-telnet/src/lib.rs similarity index 100% rename from crates/coturn-telnet/src/lib.rs rename to crates/medea-coturn-telnet/src/lib.rs diff --git a/crates/coturn-telnet/src/pool.rs b/crates/medea-coturn-telnet/src/pool.rs similarity index 100% rename from crates/coturn-telnet/src/pool.rs rename to crates/medea-coturn-telnet/src/pool.rs diff --git a/src/turn/cli.rs b/src/turn/cli.rs index 2a3c47197..80e1c6893 100644 --- a/src/turn/cli.rs +++ b/src/turn/cli.rs @@ -1,9 +1,9 @@ use std::{fmt, ops::DerefMut}; -use coturn_telnet::{CoturnTelnetError, Manager, Pool, PoolError}; use deadpool::managed::PoolConfig; use derive_more::{Display, From}; use failure::Fail; +use medea_coturn_telnet::{CoturnTelnetError, Manager, Pool, PoolError}; use crate::media::IceUser; From c06d1204e7b913d5b2bd3f489203ec8bc24e3a4d Mon Sep 17 00:00:00 2001 From: alexlapa Date: Wed, 12 Feb 2020 12:58:50 +0200 Subject: [PATCH 047/224] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04fb6cd73..a8022e621 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ All user visible changes to this project will be documented in this file. This p - Send relay mode in `Event::PeerCreated` which is used for configuring client's `RtcIceTransportPolicy` ([#79](/../../pull/79)). - Configuration: - `[server.control.grpc]` section to configure Control API gRPC server ([#33]); + - `[turn.cli]` and `[turn.cli.pool]` sections to configure access to [Coturn] admin interface ([#84](/../../pull/84)); - `server.client.http.public_url` option to configure public URL of Client API HTTP server ([#33]); - `rpc.ping_interval` option to configure `Ping`s sending interval ([#75]). - Testing: From 17eefe7fa0fc1df092b10593cdbc73aedb6f0c64 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Thu, 13 Feb 2020 09:38:59 +0200 Subject: [PATCH 048/224] quickfix [run ci] --- Makefile | 4 ++++ crates/medea-coturn-telnet/Cargo.toml | 2 +- crates/medea-coturn-telnet/src/pool.rs | 4 ++-- mock/control-api/Dockerfile | 2 ++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 7e957f41b..49736de3b 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,9 @@ endif ifeq ($(crate),medea-macro) crate-dir = crates/medea-macro endif +ifeq ($(crate),medea-coturn-telnet) +crate-dir = "crates/medea-coturn-telnet" +endif @@ -346,6 +349,7 @@ ifeq ($(test-unit-crate),@all) @make test.unit crate=medea-client-api-proto @make test.unit crate=medea-jason @make test.unit crate=medea + @make test.unit crate=medea-coturn-telnet else ifeq ($(test-unit-crate),medea) cargo test --lib --bin medea diff --git a/crates/medea-coturn-telnet/Cargo.toml b/crates/medea-coturn-telnet/Cargo.toml index 65d3ad873..b1d22e974 100644 --- a/crates/medea-coturn-telnet/Cargo.toml +++ b/crates/medea-coturn-telnet/Cargo.toml @@ -20,7 +20,7 @@ derive_more = "0.99" futures = "0.3" lazy_static = "1.4" regex = "1.3" -tokio = { version = "0.2", features = ["dns", "macros"] } +tokio = { version = "0.2", features = ["dns", "macros", "tcp"] } tokio-util = { version = "0.2", features = ["codec"] } [dev-dependencies] diff --git a/crates/medea-coturn-telnet/src/pool.rs b/crates/medea-coturn-telnet/src/pool.rs index 75d59da27..c8cccdeee 100644 --- a/crates/medea-coturn-telnet/src/pool.rs +++ b/crates/medea-coturn-telnet/src/pool.rs @@ -5,9 +5,9 @@ //! //! # Example //! -//! ```rust +//! ```rust,should_panic //! use std::ops::DerefMut; -//! use coturn_telnet::{Manager, Pool}; +//! use medea_coturn_telnet::{Manager, Pool}; //! //! let mut rt = tokio::runtime::Runtime::new().unwrap(); //! rt.block_on(async { diff --git a/mock/control-api/Dockerfile b/mock/control-api/Dockerfile index b089a3439..4dd2c291f 100644 --- a/mock/control-api/Dockerfile +++ b/mock/control-api/Dockerfile @@ -26,6 +26,7 @@ RUN apt-get update \ # Prepare Cargo workspace for building dependencies only. COPY crates/medea-macro/Cargo.toml /app/crates/medea-macro/ +COPY crates/medea-coturn-telnet/Cargo.toml /app/crates/medea-coturn-telnet/ COPY mock/control-api/Cargo.toml /app/mock/control-api/ COPY proto/client-api/Cargo.toml /app/proto/client-api/ COPY proto/control-api/Cargo.toml /app/proto/control-api/ @@ -38,6 +39,7 @@ COPY jason/Cargo.toml /app/jason/ COPY Cargo.toml Cargo.lock /app/ WORKDIR /app/ RUN mkdir -p crates/medea-macro/src/ && touch crates/medea-macro/src/lib.rs \ + && mkdir -p crates/medea-coturn-telnet/src/ && touch crates/medea-coturn-telnet/src/lib.rs \ && mkdir -p mock/control-api/src/ && touch mock/control-api/src/lib.rs \ && mkdir -p proto/client-api/src/ && touch proto/client-api/src/lib.rs \ && mkdir -p proto/control-api/src/ && touch proto/control-api/src/lib.rs \ From e9184d5a7033216299a32aafe286e3edc34b4af4 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Thu, 13 Feb 2020 18:10:03 +0300 Subject: [PATCH 049/224] Add Coturn sessions parser --- Cargo.lock | 1 + crates/coturn-telnet/Cargo.toml | 1 + crates/coturn-telnet/src/codec.rs | 20 +- crates/coturn-telnet/src/connection.rs | 15 +- crates/coturn-telnet/src/lib.rs | 1 + crates/coturn-telnet/src/sessions_parser.rs | 196 ++++++++++++++++++++ src/turn/cli.rs | 3 +- 7 files changed, 217 insertions(+), 20 deletions(-) create mode 100644 crates/coturn-telnet/src/sessions_parser.rs diff --git a/Cargo.lock b/Cargo.lock index f951d9c4b..55bfc565a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -631,6 +631,7 @@ dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "nom 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-test 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/crates/coturn-telnet/Cargo.toml b/crates/coturn-telnet/Cargo.toml index d545405d8..6135524d7 100644 --- a/crates/coturn-telnet/Cargo.toml +++ b/crates/coturn-telnet/Cargo.toml @@ -22,6 +22,7 @@ lazy_static = "1.4" regex = "1.3" tokio = { version = "0.2", features = ["dns", "macros"] } tokio-util = { version = "0.2", features = ["codec"] } +nom = "5.1" [dev-dependencies] tokio-test = "0.2" diff --git a/crates/coturn-telnet/src/codec.rs b/crates/coturn-telnet/src/codec.rs index c23549381..c05daa6f3 100644 --- a/crates/coturn-telnet/src/codec.rs +++ b/crates/coturn-telnet/src/codec.rs @@ -15,6 +15,8 @@ use bytes::{BufMut as _, Bytes, BytesMut}; use regex::Regex; use tokio_util::codec::{Decoder, Encoder}; +use crate::sessions_parser::{parse_sessions, Session}; + // Cursor is received when telnet server has finished writing response and is // ready to receive new requests. static CURSOR: &str = "> "; @@ -36,7 +38,7 @@ lazy_static::lazy_static! { } /// Messages that can be received from Coturn telnet server. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug)] pub enum CoturnCliResponse { /// Current telnet connection requires authentication. Next message sent to /// server should be [`CoturnCliRequest::Auth`]. @@ -50,7 +52,7 @@ pub enum CoturnCliResponse { /// Answer to [`CoturnCliRequest::PrintSessions`], contains list of session /// ids associated with username provided in /// [`CoturnCliRequest::PrintSessions`] message. - Sessions(Vec), + Sessions(Vec), /// Coturn telnet server did not recognized last command. UnknownCommand, @@ -95,17 +97,9 @@ impl TryFrom for CoturnCliResponse { } if IS_SESSIONS_REGEX.is_match(msg) { - let mut session_ids: Vec = Vec::new(); - for mat in EXTRACT_SESSIONS_REGEX.captures_iter(msg) { - if let Some(id) = mat.get(1) { - session_ids.push(id.as_str().to_owned()); - } else { - return Err(CoturnResponseParseError::BadResponseFormat( - msg.to_owned(), - )); - } - } - return Ok(CoturnCliResponse::Sessions(session_ids)); + let (_, sessions) = parse_sessions(&msg).unwrap(); + + return Ok(CoturnCliResponse::Sessions(sessions)); } Err(CoturnResponseParseError::CannotDetermineResponseType( diff --git a/crates/coturn-telnet/src/connection.rs b/crates/coturn-telnet/src/connection.rs index 5754392db..fa7a11d7b 100644 --- a/crates/coturn-telnet/src/connection.rs +++ b/crates/coturn-telnet/src/connection.rs @@ -7,9 +7,12 @@ use futures::{SinkExt, StreamExt}; use tokio::net::{TcpStream, ToSocketAddrs}; use tokio_util::codec::Framed; -use crate::codec::{ - CoturnCliCodec, CoturnCliCodecError, CoturnCliRequest, CoturnCliResponse, - CoturnResponseParseError, +use crate::{ + codec::{ + CoturnCliCodec, CoturnCliCodecError, CoturnCliRequest, + CoturnCliResponse, CoturnResponseParseError, + }, + sessions_parser::{Session, SessionId}, }; /// Any errors that can be thrown from [`CoturnTelnetConnection`]. @@ -73,7 +76,7 @@ impl CoturnTelnetConnection { pub async fn print_sessions( &mut self, username: String, - ) -> Result, CoturnTelnetError> { + ) -> Result, CoturnTelnetError> { // Send `CoturnCliRequest::PrintSessions`. self.0 .send(CoturnCliRequest::PrintSessions(username)) @@ -122,12 +125,12 @@ impl CoturnTelnetConnection { /// For each provided session id: /// 1. Sends [`CoturnCliRequest::CloseSession`] with specified session id. /// 2. Awaits for [`CoturnCliResponse::Ready`]. - pub async fn delete_sessions>( + pub async fn delete_sessions>( &mut self, session_ids: T, ) -> Result<(), CoturnTelnetError> { for session_id in session_ids { - self.delete_session(session_id).await?; + self.delete_session(session_id.to_string()).await?; } Ok(()) } diff --git a/crates/coturn-telnet/src/lib.rs b/crates/coturn-telnet/src/lib.rs index b4ca61b19..691e198c5 100644 --- a/crates/coturn-telnet/src/lib.rs +++ b/crates/coturn-telnet/src/lib.rs @@ -9,6 +9,7 @@ pub mod codec; pub mod connection; pub mod pool; +pub mod sessions_parser; pub use connection::{CoturnTelnetConnection, CoturnTelnetError}; pub use pool::{Connection, Manager, Pool, PoolError}; diff --git a/crates/coturn-telnet/src/sessions_parser.rs b/crates/coturn-telnet/src/sessions_parser.rs new file mode 100644 index 000000000..17573f3fe --- /dev/null +++ b/crates/coturn-telnet/src/sessions_parser.rs @@ -0,0 +1,196 @@ +use std::{convert::TryFrom, fmt, time::Duration}; + +use nom::{ + bytes::complete::{is_a, is_not, tag}, + character::complete::{ + alpha1, alphanumeric1, char, digit1, multispace0, one_of, space0, + }, + multi::{many0, many1}, + sequence::{delimited, terminated}, + IResult, +}; + +#[derive(Debug)] +pub struct UnknownProtocol; + +#[derive(Debug, Clone, Copy)] +pub enum Protocol { + Udp, + Tcp, +} + +impl TryFrom<&str> for Protocol { + type Error = UnknownProtocol; + + fn try_from(value: &str) -> Result { + match value { + "TCP" => Ok(Protocol::Tcp), + "UDP" => Ok(Protocol::Udp), + _ => Err(UnknownProtocol), + } + } +} + +const TURN_SESSION_ID_FACTOR: u64 = 1000000000000000; + +#[derive(Clone, Copy, Debug)] +pub struct SessionId(pub u64); + +impl SessionId { + pub fn server_id(self) -> u64 { + self.0 / TURN_SESSION_ID_FACTOR + } + + pub fn session_id(self) -> u64 { + self.0 - (self.server_id() * TURN_SESSION_ID_FACTOR) + } +} + +impl fmt::Display for SessionId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + write!(f, "{:018}", self.0) + } +} + +#[derive(Debug, Clone)] +pub struct Session { + pub num: u32, + pub id: SessionId, + pub user: String, + pub realm: String, + pub started: Duration, + pub expiring_in: Duration, + pub client_protocol: Protocol, + pub relay_protocol: Protocol, + pub client_addr: String, + pub server_addr: String, + pub relay_addr: String, + pub fingreprints_enforced: bool, + pub mobile: bool, + pub usage_rp: String, + pub usage_rb: String, + pub usage_sp: String, + pub usage_sb: String, + pub rate_sent: String, + pub rate_receive: String, + pub total_rate: String, + pub peers: Vec, +} + +fn parse_session(input: &str) -> IResult<&str, Session> { + let (input, num) = + delimited(many0(one_of(" \n\r,")), digit1, char(')'))(input)?; + let num: u32 = num.parse().unwrap(); + + let (input, _) = coturn_field_name(input, "id=")?; + let (input, id) = digit1(input)?; + let id: u64 = id.parse().unwrap(); + + let (input, _) = coturn_field_name(input, "user")?; + let (input, user) = delimited(char('<'), is_not(">"), char('>'))(input)?; + + let (input, _) = coturn_field_name(input, "realm:")?; + let (input, realm) = alphanumeric1(input)?; + + let (input, _) = coturn_field_name(input, "started")?; + let (input, started) = terminated(digit1, tag(" secs ago"))(input)?; + let started: u64 = started.parse().unwrap(); + + let (input, _) = coturn_field_name(input, "expiring in")?; + let (input, expiring_in) = terminated(digit1, tag(" secs"))(input)?; + let expiring_in: u64 = expiring_in.parse().unwrap(); + + let (input, _) = coturn_field_name(input, "client protocol")?; + let (input, client_protocol) = alpha1(input)?; + + let (input, _) = coturn_field_name(input, "relay protocol")?; + let (input, relay_protocol) = alpha1(input)?; + + let (input, _) = coturn_field_name(input, "client addr")?; + let (input, client_addr) = address(input)?; + + let (input, _) = coturn_field_name(input, "server addr")?; + let (input, server_addr) = address(input)?; + + let (input, _) = coturn_field_name(input, "relay addr")?; + let (input, relay_addr) = address(input)?; + + let (input, _) = coturn_field_name(input, "fingerprints enforced:")?; + let (input, fingreprints_enforced) = alpha1(input)?; + + let (input, _) = coturn_field_name(input, "mobile:")?; + let (input, mobile) = alpha1(input)?; + + let (input, _) = coturn_field_name(input, "usage:")?; + let (input, rp) = coturn_stat(input, "rp=")?; + let (input, rb) = coturn_stat(input, "rb=")?; + let (input, sp) = coturn_stat(input, "sp=")?; + let (input, sb) = coturn_stat(input, "sb=")?; + + let (input, _) = coturn_field_name(input, "rate:")?; + let (input, rate_receive) = coturn_stat(input, "r=")?; + let (input, rate_sent) = coturn_stat(input, "s=")?; + let (input, total_rate) = + delimited(tag("total="), digit1, tag(" (bytes per sec)"))(input)?; + + let (input, peers) = match coturn_field_name(input, "peers:") { + Ok((input, _)) => { + let (input, peers) = + many1(delimited(space0, address, tag("\r\n")))(input)?; + (input, peers) + } + Err(_) => (input, Vec::new()), + }; + + let session = Session { + num, + id: SessionId(id), + user: user.to_string(), + realm: realm.to_string(), + started: Duration::from_secs(started), + expiring_in: Duration::from_secs(expiring_in), + client_protocol: Protocol::try_from(client_protocol).unwrap(), + relay_protocol: Protocol::try_from(relay_protocol).unwrap(), + client_addr: client_addr.to_string(), + server_addr: server_addr.to_string(), + relay_addr: relay_addr.to_string(), + fingreprints_enforced: coturn_bool_to_bool(fingreprints_enforced), + mobile: coturn_bool_to_bool(mobile), + usage_rp: rp.to_string(), + usage_rb: rb.to_string(), + usage_sp: sp.to_string(), + usage_sb: sb.to_string(), + rate_receive: rate_receive.to_string(), + rate_sent: rate_sent.to_string(), + total_rate: total_rate.to_string(), + peers: peers.into_iter().map(ToString::to_string).collect(), + }; + + Ok((input, session)) +} + +fn coturn_bool_to_bool(input: &str) -> bool { + input == "ON" +} + +fn coturn_field_name<'a>( + input: &'a str, + field_name: &str, +) -> IResult<&'a str, &'a str> { + delimited(many0(one_of(" \n\t\r,:")), tag(field_name), multispace0)(input) +} + +fn coturn_stat<'a>( + input: &'a str, + predicate: &str, +) -> IResult<&'a str, &'a str> { + delimited(tag(predicate), digit1, many0(one_of(" \n\t\r,")))(input) +} + +fn address<'a>(input: &'a str) -> IResult<&'a str, &'a str> { + is_a("1234567890.:[]")(input) +} + +pub fn parse_sessions(input: &str) -> IResult<&str, Vec> { + many0(parse_session)(input) +} diff --git a/src/turn/cli.rs b/src/turn/cli.rs index 2a3c47197..363cd4207 100644 --- a/src/turn/cli.rs +++ b/src/turn/cli.rs @@ -44,7 +44,8 @@ impl CoturnTelnetClient { .deref_mut() .print_sessions(user.user().clone().into()) .await?; - connection.deref_mut().delete_sessions(sessions).await?; + let sessions_ids = sessions.into_iter().map(|session| session.id); + connection.deref_mut().delete_sessions(sessions_ids).await?; } Ok(()) From cc82e4f73803aab9ef1d9d932c6fb5c9ccadb229 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 17 Feb 2020 14:27:34 +0300 Subject: [PATCH 050/224] Add TrafficUsage --- .../src/sessions_parser.rs | 46 +++-- src/media/ice_user.rs | 2 +- src/turn/coturn_stats.rs | 177 ++++++++---------- src/turn/mod.rs | 2 +- 4 files changed, 119 insertions(+), 108 deletions(-) diff --git a/crates/medea-coturn-telnet/src/sessions_parser.rs b/crates/medea-coturn-telnet/src/sessions_parser.rs index 17573f3fe..08da8aade 100644 --- a/crates/medea-coturn-telnet/src/sessions_parser.rs +++ b/crates/medea-coturn-telnet/src/sessions_parser.rs @@ -67,16 +67,44 @@ pub struct Session { pub relay_addr: String, pub fingreprints_enforced: bool, pub mobile: bool, - pub usage_rp: String, - pub usage_rb: String, - pub usage_sp: String, - pub usage_sb: String, + pub traffic_usage: TrafficUsage, pub rate_sent: String, pub rate_receive: String, pub total_rate: String, pub peers: Vec, } +#[derive(Clone, Debug)] +pub struct TrafficUsage { + pub received_packets: u64, + pub received_bytes: u64, + pub sent_packets: u64, + pub sent_bytes: u64, +} + +impl TrafficUsage { + pub fn parse(input: &str) -> IResult<&str, Self> { + let (input, rp) = coturn_stat(input, "rp=")?; + let received_packets = rp.parse().unwrap(); + let (input, rb) = coturn_stat(input, "rb=")?; + let received_bytes = rb.parse().unwrap(); + let (input, sp) = coturn_stat(input, "sp=")?; + let sent_packets = sp.parse().unwrap(); + let (input, sb) = coturn_stat(input, "sb=")?; + let sent_bytes = sb.parse().unwrap(); + + Ok(( + input, + Self { + received_packets, + received_bytes, + sent_packets, + sent_bytes, + }, + )) + } +} + fn parse_session(input: &str) -> IResult<&str, Session> { let (input, num) = delimited(many0(one_of(" \n\r,")), digit1, char(')'))(input)?; @@ -122,10 +150,7 @@ fn parse_session(input: &str) -> IResult<&str, Session> { let (input, mobile) = alpha1(input)?; let (input, _) = coturn_field_name(input, "usage:")?; - let (input, rp) = coturn_stat(input, "rp=")?; - let (input, rb) = coturn_stat(input, "rb=")?; - let (input, sp) = coturn_stat(input, "sp=")?; - let (input, sb) = coturn_stat(input, "sb=")?; + let (input, traffic_usage) = TrafficUsage::parse(input)?; let (input, _) = coturn_field_name(input, "rate:")?; let (input, rate_receive) = coturn_stat(input, "r=")?; @@ -156,10 +181,7 @@ fn parse_session(input: &str) -> IResult<&str, Session> { relay_addr: relay_addr.to_string(), fingreprints_enforced: coturn_bool_to_bool(fingreprints_enforced), mobile: coturn_bool_to_bool(mobile), - usage_rp: rp.to_string(), - usage_rb: rb.to_string(), - usage_sp: sp.to_string(), - usage_sb: sb.to_string(), + traffic_usage, rate_receive: rate_receive.to_string(), rate_sent: rate_sent.to_string(), total_rate: total_rate.to_string(), diff --git a/src/media/ice_user.rs b/src/media/ice_user.rs index 64c28ccf4..20d28ce49 100644 --- a/src/media/ice_user.rs +++ b/src/media/ice_user.rs @@ -2,8 +2,8 @@ //! //! [coturn]: https://github.com/coturn/coturn -use medea_client_api_proto::{IceServer, PeerId}; use derive_more::{AsRef, Display, From, Into}; +use medea_client_api_proto::{IceServer, PeerId}; use crate::api::control::{EndpointId, RoomId}; diff --git a/src/turn/coturn_stats.rs b/src/turn/coturn_stats.rs index 91e6c8fc8..167aeb90c 100644 --- a/src/turn/coturn_stats.rs +++ b/src/turn/coturn_stats.rs @@ -4,7 +4,6 @@ use async_trait::async_trait; use derive_more::{Display, From}; use failure::Fail; use rand::{distributions::Alphanumeric, Rng}; -use redis::{ConnectionInfo, IntoConnectionInfo, PubSub}; use crate::{ api::control::{EndpointId, MemberId, RoomId}, @@ -13,31 +12,84 @@ use crate::{ media::IceUser, turn::repo::{TurnDatabase, TurnDatabaseErr}, }; -use actix::{Actor, AsyncContext, StreamHandler}; +use actix::{Actor, AsyncContext, StreamHandler, WrapFuture}; use futures::channel::mpsc; use medea_client_api_proto::PeerId; +use medea_coturn_telnet::sessions_parser::TrafficUsage; +use redis::{ConnectionInfo, IntoConnectionInfo, PubSub}; use std::{collections::HashMap, time::Duration}; +#[derive(Clone, Debug)] +pub struct Traffic { + pub received_packets: u64, + pub received_bytes: u64, + pub sent_packets: u64, + pub sent_bytes: u64, +} + +impl Traffic { + pub fn parse(body: String) -> Result { + let mut items: HashMap<&str, u64> = body + .split(", ") + .map(|i| { + let mut splitted_item = i.split('='); + let key = splitted_item.next().ok_or_else(|| { + CoturnEventParseError::FailedToParseTrafficMap(body.clone()) + })?; + let value: u64 = splitted_item + .next() + .ok_or_else(|| { + CoturnEventParseError::FailedToParseTrafficMap( + body.clone(), + ) + })? + .parse() + .map_err(|_| { + CoturnEventParseError::FailedToParseTrafficMap( + body.clone(), + ) + })?; + + Ok((key, value)) + }) + .collect::>()?; + + let received_packets = items.remove("rcvp").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "rcvp".to_string(), + ) + })?; + let received_bytes = items.remove("rcvb").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "rcvb".to_string(), + ) + })?; + let sent_packets = items.remove("sentp").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "sentp".to_string(), + ) + })?; + let sent_bytes = items.remove("sentb").ok_or_else(|| { + CoturnEventParseError::FieldNotFoundInTrafficUpdate( + "sentb".to_string(), + ) + })?; + + Ok(Self { + received_packets, + received_bytes, + sent_packets, + sent_bytes, + }) + } +} + #[derive(Debug)] pub enum CoturnAllocationEvent { - New { - lifetime: Duration, - }, - Refreshed { - lifetime: Duration, - }, - Traffic { - received_packets: u64, - received_bytes: u64, - sent_packets: u64, - sent_bytes: u64, - }, - TotalTraffic { - received_packets: u64, - received_bytes: u64, - sent_packets: u64, - sent_bytes: u64, - }, + New { lifetime: Duration }, + Refreshed { lifetime: Duration }, + Traffic { traffic: Traffic }, + TotalTraffic { traffic: Traffic }, Deleted, } @@ -46,76 +98,13 @@ impl CoturnAllocationEvent { event_type: &str, body: String, ) -> Result { - const TOTAL_TRAFFIC: &str = "total_traffic"; - const TRAFFIC: &str = "traffic"; - match event_type { - TOTAL_TRAFFIC | TRAFFIC => { - let mut items: HashMap<&str, u64> = body - .split(", ") - .map(|i| { - let mut splitted_item = i.split('='); - let key = splitted_item.next().ok_or_else(|| { - CoturnEventParseError::FailedToParseTrafficMap( - body.clone(), - ) - })?; - let value: u64 = splitted_item - .next() - .ok_or_else(|| { - CoturnEventParseError::FailedToParseTrafficMap( - body.clone(), - ) - })? - .parse() - .map_err(|_| { - CoturnEventParseError::FailedToParseTrafficMap( - body.clone(), - ) - })?; - - Ok((key, value)) - }) - .collect::>()?; - - let received_packets = - items.remove("rcvp").ok_or_else(|| { - CoturnEventParseError::FieldNotFoundInTrafficUpdate( - "rcvp".to_string(), - ) - })?; - let received_bytes = items.remove("rcvb").ok_or_else(|| { - CoturnEventParseError::FieldNotFoundInTrafficUpdate( - "rcvb".to_string(), - ) - })?; - let sent_packets = items.remove("sentp").ok_or_else(|| { - CoturnEventParseError::FieldNotFoundInTrafficUpdate( - "sentp".to_string(), - ) - })?; - let sent_bytes = items.remove("sentb").ok_or_else(|| { - CoturnEventParseError::FieldNotFoundInTrafficUpdate( - "sentb".to_string(), - ) - })?; - - if event_type == TOTAL_TRAFFIC { - Ok(CoturnAllocationEvent::TotalTraffic { - received_bytes, - received_packets, - sent_bytes, - sent_packets, - }) - } else { - Ok(CoturnAllocationEvent::Traffic { - received_bytes, - received_packets, - sent_bytes, - sent_packets, - }) - } - } + "total_traffic" => Ok(CoturnAllocationEvent::TotalTraffic { + traffic: Traffic::parse(body)?, + }), + "traffic" => Ok(CoturnAllocationEvent::Traffic { + traffic: Traffic::parse(body)?, + }), "status" => { let mut splitted = body.split(' '); let status = splitted @@ -164,7 +153,7 @@ impl CoturnAllocationEvent { #[derive(Debug)] pub struct CoturnEvent { event: CoturnAllocationEvent, - member_id: MemberId, + room_id: RoomId, peer_id: PeerId, allocation_id: u64, } @@ -176,12 +165,12 @@ impl CoturnEvent { .map_err(|_| CoturnEventParseError::NoChannelInfo)?; let mut channel_splitted = channel.split('/').skip(4); - let (member_id, peer_id) = { + let (room_id, peer_id) = { let user = channel_splitted .next() .ok_or(CoturnEventParseError::NoUserInfo)?; let mut user_splitted = user.split('_'); - let member_id = MemberId( + let room_id = RoomId( user_splitted .next() .ok_or(CoturnEventParseError::NoMemberId)? @@ -195,7 +184,7 @@ impl CoturnEvent { .map_err(|_| CoturnEventParseError::NoPeerId)?, ); - (member_id, peer_id) + (room_id, peer_id) }; let mut channel_splitted = channel_splitted.skip(1); @@ -216,7 +205,7 @@ impl CoturnEvent { Ok(CoturnEvent { event, - member_id, + room_id, peer_id, allocation_id, }) diff --git a/src/turn/mod.rs b/src/turn/mod.rs index fe32b4b25..6561bc2f9 100644 --- a/src/turn/mod.rs +++ b/src/turn/mod.rs @@ -2,8 +2,8 @@ //! //! [TURN]: https://webrtcglossary.com/turn -pub mod coturn_stats; mod cli; +pub mod coturn_stats; pub mod repo; pub mod service; From 9e0215370389e406ffb79b8a97cea9a7bf32fbb1 Mon Sep 17 00:00:00 2001 From: alexlapa Date: Thu, 20 Feb 2020 17:45:15 +0200 Subject: [PATCH 051/224] examine --- jason/src/peer/conn.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/jason/src/peer/conn.rs b/jason/src/peer/conn.rs index c462168a6..def89a9a5 100644 --- a/jason/src/peer/conn.rs +++ b/jason/src/peer/conn.rs @@ -3,7 +3,8 @@ use std::{cell::RefCell, rc::Rc}; use derive_more::Display; use medea_client_api_proto::{Direction as DirectionProto, IceServer}; use tracerr::Traced; -use wasm_bindgen_futures::JsFuture; +use wasm_bindgen::{JsCast, closure::Closure, JsValue, prelude::*}; +use wasm_bindgen_futures::{JsFuture, spawn_local}; use web_sys::{ Event, RtcConfiguration, RtcIceCandidateInit, RtcIceConnectionState, RtcIceTransportPolicy, RtcPeerConnection as SysRtcPeerConnection, @@ -14,7 +15,7 @@ use web_sys::{ use crate::{ media::TrackConstraints, - utils::{EventListener, EventListenerBindError, JsCaused, JsError}, + utils::{EventListener, EventListenerBindError, JsCaused, JsError, window, console_error}, }; use super::ice_server::RtcIceServers; @@ -244,8 +245,25 @@ impl RtcPeerConnection { .map_err(RTCPeerConnectionError::PeerCreationError) .map_err(tracerr::wrap!())?; + let peer = Rc::new(peer); + + + let peer_clone = Rc::clone(&peer); + let a = Closure::wrap(Box::new(move || { + let another_peer_clone = Rc::clone(&peer_clone); + spawn_local(async move { + let stats = JsFuture::from(another_peer_clone.get_stats()) + .await.unwrap(); + asd(&stats); +// js_sys::JSON::stringify +// console_error(&stats); + }); + }) as Box); + window().set_interval_with_callback_and_timeout_and_arguments_0(a.as_ref().unchecked_ref(), 1000).unwrap(); + a.forget(); + Ok(Self { - peer: Rc::new(peer), + peer, on_ice_candidate: RefCell::new(None), on_ice_connection_state_changed: RefCell::new(None), on_track: RefCell::new(None), @@ -537,3 +555,11 @@ impl Drop for RtcPeerConnection { self.peer.close(); } } + + +#[wasm_bindgen(inline_js = "export function asd(arg) { window.asd = arg; }")] +extern "C" { + fn asd( + arg: &JsValue, + ); +} From 889ab8f3e0aa16d5323b4fe2776b9ae10e3576cb Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Fri, 21 Feb 2020 13:41:00 +0300 Subject: [PATCH 052/224] Add basic on_start/on_stop support --- Cargo.lock | 23 +- Cargo.toml | 1 + _dev/specs/fully-not-relayed.yml | 34 ++ _dev/specs/fully-relayed.yml | 38 ++ _dev/specs/relayed-not-relayed.yml | 36 ++ .../src/sessions_parser.rs | 9 + src/lib.rs | 12 +- src/main.rs | 16 +- src/signalling/room.rs | 41 +- src/turn/cli.rs | 10 + src/turn/coturn_stats.rs | 424 ++++++++++++++++-- src/turn/mod.rs | 2 +- 12 files changed, 590 insertions(+), 56 deletions(-) create mode 100644 _dev/specs/fully-not-relayed.yml create mode 100644 _dev/specs/fully-relayed.yml create mode 100644 _dev/specs/relayed-not-relayed.yml diff --git a/Cargo.lock b/Cargo.lock index be713cbfc..80f139691 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -841,7 +841,7 @@ dependencies = [ "deadpool", "futures 0.3.4", "log 0.4.8", - "redis", + "redis 0.15.1", "serde 1.0.104", ] @@ -1508,7 +1508,8 @@ dependencies = [ "medea-macro", "mockall 0.6.0", "rand 0.7.3", - "redis", + "redis 0.15.1", + "redis 0.15.2-alpha.0", "rust-crypto", "serde 1.0.104", "serde_json", @@ -2217,6 +2218,24 @@ dependencies = [ "url", ] +[[package]] +name = "redis" +version = "0.15.2-alpha.0" +dependencies = [ + "bytes", + "combine", + "dtoa", + "futures-executor", + "futures-util", + "itoa", + "percent-encoding 2.1.0", + "pin-project-lite", + "sha1", + "tokio", + "tokio-util", + "url", +] + [[package]] name = "redox_syscall" version = "0.1.56" diff --git a/Cargo.toml b/Cargo.toml index ed1accb11..84d054ccb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ medea-control-api-proto = { path = "proto/control-api" } medea-macro = { path = "crates/medea-macro" } rand = "0.7" redis = "0.15" +patched_redis = { path = "../redis-rs", package = "redis" } rust-crypto = "0.2" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/_dev/specs/fully-not-relayed.yml b/_dev/specs/fully-not-relayed.yml new file mode 100644 index 000000000..433349a05 --- /dev/null +++ b/_dev/specs/fully-not-relayed.yml @@ -0,0 +1,34 @@ +kind: Room +id: fully-not-relayed +spec: + pipeline: + member-2: + kind: Member + credentials: test + on_join: "grpc://127.0.0.1:9099" + on_leave: "grpc://127.0.0.1:9099" + spec: + pipeline: + publish: + kind: WebRtcPublishEndpoint + spec: + p2p: Always + play-responder: + kind: WebRtcPlayEndpoint + spec: + src: "local://fully-not-relayed/member-1/publish" + member-1: + kind: Member + credentials: test + on_join: "grpc://127.0.0.1:9099" + on_leave: "grpc://127.0.0.1:9099" + spec: + pipeline: + publish: + kind: WebRtcPublishEndpoint + spec: + p2p: Always + play-caller: + kind: WebRtcPlayEndpoint + spec: + src: "local://fully-not-relayed/member-2/publish" diff --git a/_dev/specs/fully-relayed.yml b/_dev/specs/fully-relayed.yml new file mode 100644 index 000000000..f291ffe23 --- /dev/null +++ b/_dev/specs/fully-relayed.yml @@ -0,0 +1,38 @@ +kind: Room +id: fully-relayed +spec: + pipeline: + member-2: + kind: Member + credentials: test + on_join: "grpc://127.0.0.1:9099" + on_leave: "grpc://127.0.0.1:9099" + spec: + pipeline: + publish: + kind: WebRtcPublishEndpoint + spec: + p2p: Always + force_relay: true + play-responder: + kind: WebRtcPlayEndpoint + spec: + src: "local://fully-not-relayed/member-1/publish" + force_relay: true + member-1: + kind: Member + credentials: test + on_join: "grpc://127.0.0.1:9099" + on_leave: "grpc://127.0.0.1:9099" + spec: + pipeline: + publish: + kind: WebRtcPublishEndpoint + spec: + p2p: Always + force_relay: true + play-caller: + kind: WebRtcPlayEndpoint + spec: + src: "local://fully-not-relayed/member-2/publish" + force_relay: true diff --git a/_dev/specs/relayed-not-relayed.yml b/_dev/specs/relayed-not-relayed.yml new file mode 100644 index 000000000..7ab797639 --- /dev/null +++ b/_dev/specs/relayed-not-relayed.yml @@ -0,0 +1,36 @@ +kind: Room +id: relayed-not-relayed +spec: + pipeline: + relayed-member: + kind: Member + credentials: test + on_join: "grpc://127.0.0.1:9099" + on_leave: "grpc://127.0.0.1:9099" + spec: + pipeline: + publish: + kind: WebRtcPublishEndpoint + spec: + p2p: Always + force_relay: true + play-responder: + kind: WebRtcPlayEndpoint + spec: + src: "local://relayed-not-relayed/not-relayed-member/publish" + force_relay: true + not-relayed-member: + kind: Member + credentials: test + on_join: "grpc://127.0.0.1:9099" + on_leave: "grpc://127.0.0.1:9099" + spec: + pipeline: + publish: + kind: WebRtcPublishEndpoint + spec: + p2p: Always + play-caller: + kind: WebRtcPlayEndpoint + spec: + src: "local://relayed-not-relayed/relayed-member/publish" diff --git a/crates/medea-coturn-telnet/src/sessions_parser.rs b/crates/medea-coturn-telnet/src/sessions_parser.rs index 08da8aade..3fd213b4d 100644 --- a/crates/medea-coturn-telnet/src/sessions_parser.rs +++ b/crates/medea-coturn-telnet/src/sessions_parser.rs @@ -31,6 +31,15 @@ impl TryFrom<&str> for Protocol { } } +impl fmt::Display for Protocol { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Protocol::Udp => write!(f, "UDP"), + Protocol::Tcp => write!(f, "TCP"), + } + } +} + const TURN_SESSION_ID_FACTOR: u64 = 1000000000000000; #[derive(Clone, Copy, Debug)] diff --git a/src/lib.rs b/src/lib.rs index 8919683d1..c1dc9056a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,8 +21,9 @@ use crate::{ clients::CallbackClientFactoryImpl, service::CallbackService, }, conf::Conf, - turn::TurnAuthService, + turn::{coturn_stats::CoturnStats, TurnAuthService}, }; +use actix::Addr; /// Global application context. #[derive(Clone, Debug)] @@ -39,16 +40,23 @@ pub struct AppContext { /// /// [`CallbackEvent`]: crate::api::control::callbacks::CallbackEvent pub callbacks: CallbackService, + + pub coturn_stats: Addr, } impl AppContext { /// Creates new [`AppContext`]. #[inline] - pub fn new(config: Conf, turn: Arc) -> Self { + pub fn new( + config: Conf, + turn: Arc, + coturn_stats: Addr, + ) -> Self { Self { config: Arc::new(config), turn_service: turn, callbacks: CallbackService::default(), + coturn_stats, } } } diff --git a/src/main.rs b/src/main.rs index 86e87c141..e373025b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,8 @@ use medea::{ shutdown::{self, GracefulShutdown}, signalling::{room_repo::RoomRepository, room_service::RoomService}, turn::{ - coturn_stats::{new_coturn_stats_watcher, CoturnStatsWatcher}, + cli::CoturnTelnetClient, + coturn_stats::{run_coturn_stats_watcher, CoturnStats}, new_turn_auth_service, }, AppContext, @@ -36,11 +37,18 @@ fn main() -> Result<(), Error> { Arbiter::spawn( async move { let turn_service = new_turn_auth_service(&config.turn)?; - let coturn_stats_watcher = - new_coturn_stats_watcher(&config.turn).unwrap().start(); let graceful_shutdown = GracefulShutdown::new(config.shutdown.timeout).start(); - let app_context = AppContext::new(config.clone(), turn_service); + let coturn_client = CoturnTelnetClient::new( + (config.turn.cli.ip.to_string(), config.turn.cli.port), + config.turn.cli.pass.clone(), + config.turn.cli.pool.into(), + ); + let coturn_stats = CoturnStats::new(&config.turn, coturn_client) + .unwrap() + .start(); + let app_context = + AppContext::new(config.clone(), turn_service, coturn_stats); let room_repo = RoomRepository::new(HashMap::new()); let room_service = RoomService::new( diff --git a/src/signalling/room.rs b/src/signalling/room.rs index b62e0e0b4..4c75d6d3d 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -6,8 +6,8 @@ use std::collections::{HashMap, HashSet}; use actix::{ - Actor, ActorFuture, Addr, Context, ContextFutureSpawner as _, Handler, - Message, WrapFuture as _, WrapFuture, + Actor, ActorFuture, Addr, AsyncContext, Context, ContextFutureSpawner as _, + Handler, Message, WrapFuture as _, WrapFuture, }; use derive_more::Display; use failure::Fail; @@ -55,6 +55,7 @@ use crate::{ participants::{ParticipantService, ParticipantServiceErr}, peers::PeerRepository, }, + turn::coturn_stats::{CoturnStats, EventType, Subscribe}, utils::ResponseActAnyFuture, AppContext, }; @@ -175,6 +176,8 @@ pub struct Room { /// Current state of this [`Room`]. state: State, + + coturn_stats: Addr, } impl Room { @@ -197,6 +200,7 @@ impl Room { members: ParticipantService::new(room_spec, context)?, state: State::Started, callbacks: context.callbacks.clone(), + coturn_stats: context.coturn_stats.clone(), }) } @@ -344,6 +348,20 @@ impl Room { first_peer: PeerId, second_peer: PeerId, ) { + self.coturn_stats.do_send(Subscribe { + peer_id: first_peer, + partner_peer_id: second_peer, + room_id: self.id.clone(), + addr: ctx.address(), + events_type: HashSet::new(), + }); + self.coturn_stats.do_send(Subscribe { + peer_id: second_peer, + partner_peer_id: first_peer, + room_id: self.id.clone(), + addr: ctx.address(), + events_type: HashSet::new(), + }); match self.send_peer_created(first_peer, second_peer) { Ok(res) => Box::new(res.then(|res, this, ctx| -> ActFuture<()> { if res.is_ok() { @@ -1307,3 +1325,22 @@ impl Handler for Room { Ok(()) } } + +#[derive(Message, Debug)] +#[rtype(result = "()")] +pub struct OnStartOnStopCallback { + pub event: EventType, + pub peer_id: PeerId, +} + +impl Handler for Room { + type Result = (); + + fn handle( + &mut self, + msg: OnStartOnStopCallback, + ctx: &mut Self::Context, + ) -> Self::Result { + debug!("LOOK AT ME: {:?}", msg); + } +} diff --git a/src/turn/cli.rs b/src/turn/cli.rs index 93a24fdfa..9fd7bc3fc 100644 --- a/src/turn/cli.rs +++ b/src/turn/cli.rs @@ -6,6 +6,7 @@ use failure::Fail; use medea_coturn_telnet::{CoturnTelnetError, Manager, Pool, PoolError}; use crate::media::IceUser; +use medea_coturn_telnet::sessions_parser::Session; #[derive(Display, Debug, Fail, From)] pub enum CoturnCliError { @@ -50,6 +51,15 @@ impl CoturnTelnetClient { Ok(()) } + + pub async fn get_sessions( + &self, + username: String, + ) -> Result, CoturnCliError> { + let mut connection = self.0.get().await?; + + Ok(connection.print_sessions(username).await?) + } } impl fmt::Debug for CoturnTelnetClient { diff --git a/src/turn/coturn_stats.rs b/src/turn/coturn_stats.rs index 167aeb90c..1c427020d 100644 --- a/src/turn/coturn_stats.rs +++ b/src/turn/coturn_stats.rs @@ -1,5 +1,6 @@ use std::{fmt, sync::Arc}; +use actix::Message; use async_trait::async_trait; use derive_more::{Display, From}; use failure::Fail; @@ -12,14 +13,17 @@ use crate::{ media::IceUser, turn::repo::{TurnDatabase, TurnDatabaseErr}, }; -use actix::{Actor, AsyncContext, StreamHandler, WrapFuture}; +use actix::{ + Actor, ActorFuture, Addr, AsyncContext, Handler, SpawnHandle, + StreamHandler, WrapFuture, +}; use futures::channel::mpsc; use medea_client_api_proto::PeerId; -use medea_coturn_telnet::sessions_parser::TrafficUsage; -use redis::{ConnectionInfo, IntoConnectionInfo, PubSub}; +use medea_coturn_telnet::sessions_parser::{Session, TrafficUsage}; +use patched_redis::{ConnectionInfo, IntoConnectionInfo}; use std::{collections::HashMap, time::Duration}; -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Copy)] pub struct Traffic { pub received_packets: u64, pub received_bytes: u64, @@ -159,7 +163,9 @@ pub struct CoturnEvent { } impl CoturnEvent { - pub fn parse(msg: redis::Msg) -> Result { + pub fn parse( + msg: patched_redis::Msg, + ) -> Result { let channel: String = msg .get_channel() .map_err(|_| CoturnEventParseError::NoChannelInfo)?; @@ -273,41 +279,33 @@ pub struct CoturnStatsWatcher { client: redis::Client, } -impl CoturnStatsWatcher { - pub fn new( - conf: T, - ) -> Result { - let client = redis::Client::open(conf)?; - - Ok(Self { client }) - } -} - -impl Actor for CoturnStatsWatcher { - type Context = actix::Context; +use crate::{ + media::peer::Context, + signalling::{room::OnStartOnStopCallback, Room}, + turn::{ + cli::{CoturnCliError, CoturnTelnetClient}, + coturn_stats::EventType::OnStart, + }, +}; +use actix_web::web::patch; +use futures::{StreamExt, TryFutureExt}; +use patched_redis::Client as RedisClient; +use redis::Msg; +use std::{ + cell::RefCell, collections::HashSet, rc::Rc, thread::JoinHandle, + time::Instant, +}; - fn started(&mut self, ctx: &mut Self::Context) { - let mut conn = self.client.get_connection().unwrap(); - let (tx, rx) = mpsc::unbounded(); - std::thread::spawn(move || { - let mut pubsub = conn.as_pubsub(); - pubsub - .psubscribe("turn/realm/*/user/*/allocation/*") - .unwrap(); - loop { - let msg = pubsub.get_message().unwrap(); - if tx.unbounded_send(msg).is_err() { - break; - } - } - }); - ctx.add_stream(rx); - } -} +pub async fn coturn_watcher_loop( + client: patched_redis::Client, +) -> Result<(), patched_redis::RedisError> { + let conn = client.get_async_connection().await?; + let mut pusub = conn.into_pubsub(); + pusub.psubscribe("turn/realm/*/user/*/allocation/*").await?; + let mut pubsub_stream = pusub.on_message(); -impl StreamHandler for CoturnStatsWatcher { - fn handle(&mut self, item: redis::Msg, ctx: &mut Self::Context) { - match CoturnEvent::parse(item) { + while let Some(msg) = pubsub_stream.next().await { + match CoturnEvent::parse(msg) { Ok(event) => { debug!("Coturn stats: {:?}", event); } @@ -316,13 +314,13 @@ impl StreamHandler for CoturnStatsWatcher { } } } + + Ok(()) } -pub fn new_coturn_stats_watcher( - cf: &conf::Turn, -) -> Result { - let turn_db = CoturnStatsWatcher::new(ConnectionInfo { - addr: Box::new(redis::ConnectionAddr::Tcp( +pub fn run_coturn_stats_watcher(cf: &conf::Turn) { + let connection_info = ConnectionInfo { + addr: Box::new(patched_redis::ConnectionAddr::Tcp( cf.db.redis.ip.to_string(), cf.db.redis.port, )), @@ -332,7 +330,343 @@ pub fn new_coturn_stats_watcher( } else { Some(cf.db.redis.pass.clone()) }, - })?; + }; + let client = patched_redis::Client::open(connection_info).unwrap(); + actix::spawn(async move { + coturn_watcher_loop(client).await.ok(); + }); +} + +#[derive(Debug)] +pub enum PublisherAllocationState { + Stopped, + Playing, +} + +// TODO: when this will be Dropped - spawn on_stop event (if state is not +// PublisherAllocationState::Stopped). +#[derive(Debug)] +pub struct PublisherAllocation { + allocation_id: u64, + peer_id: PeerId, + last_update: Instant, + prev_sent_bytes: u64, + prev_received_bytes: u64, + current_sent_bytes: u64, + current_received_bytes: u64, + state: PublisherAllocationState, + // TODO: recipient + room_addr: Addr, + events: HashSet, +} + +impl PublisherAllocation { + pub fn update_traffic(&mut self, traffic: Traffic) { + self.update_send_bytes(traffic.sent_bytes); + self.update_received_bytes(traffic.received_bytes); + } + + fn update_send_bytes(&mut self, sent_bytes: u64) { + if self.current_sent_bytes < sent_bytes { + self.prev_sent_bytes = self.current_sent_bytes; + self.current_sent_bytes = sent_bytes; + } + self.refresh_last_update(); + } + + fn update_received_bytes(&mut self, received_bytes: u64) { + if self.current_received_bytes < received_bytes { + self.prev_received_bytes = self.current_received_bytes; + self.current_received_bytes = received_bytes; + } + self.refresh_last_update(); + } + + fn refresh_last_update(&mut self) { + self.last_update = Instant::now(); + } + + pub fn on_start(&self) { + self.room_addr.do_send(OnStartOnStopCallback { + peer_id: self.peer_id, + event: EventType::OnStart, + }); + } +} + +impl Drop for PublisherAllocation { + fn drop(&mut self) { + self.room_addr.do_send(OnStartOnStopCallback { + peer_id: self.peer_id, + event: EventType::OnStop, + }) + } +} + +#[derive(Eq, PartialEq, Hash, Debug)] +pub enum EventType { + OnStart, + OnStop, +} + +type Alloc = Rc>; + +#[derive(Debug)] +pub struct CoturnStats { + allocations: HashMap)>, + client: patched_redis::Client, + // TODO: PeerId -> CoturnUsername + awaits_allocation: HashMap, + coturn_client: CoturnTelnetClient, + relay_allocations_ids: HashMap, +} + +impl CoturnStats { + pub fn new( + cf: &crate::conf::turn::Turn, + coturn_client: CoturnTelnetClient, + ) -> Result { + let connection_info = ConnectionInfo { + addr: Box::new(patched_redis::ConnectionAddr::Tcp( + cf.db.redis.ip.to_string(), + cf.db.redis.port, + )), + db: cf.db.redis.db_number, + passwd: if cf.db.redis.pass.is_empty() { + None + } else { + Some(cf.db.redis.pass.clone()) + }, + }; + let client = patched_redis::Client::open(connection_info)?; + + Ok(Self { + allocations: HashMap::new(), + client, + awaits_allocation: HashMap::new(), + coturn_client, + relay_allocations_ids: HashMap::new(), + }) + } +} + +impl Actor for CoturnStats { + type Context = actix::Context; + + fn started(&mut self, ctx: &mut Self::Context) { + let (msg_tx, msg_stream) = mpsc::unbounded(); + let client = self.client.clone(); + + ctx.spawn( + async move { + let conn = client.get_async_connection().await.unwrap(); + let mut pubsub = conn.into_pubsub(); + pubsub + .psubscribe("turn/realm/*/user/*/allocation/*") + .await + .unwrap(); + + let mut msg_stream = pubsub.on_message(); + while msg_tx.unbounded_send(msg_stream.next().await).is_ok() {} + } + .into_actor(self), + ); + ctx.add_stream(msg_stream); + } +} - Ok(turn_db) +fn find_relay_session(sessions: Vec) -> Option { + for session in sessions { + if session.peers.len() > 0 { + return Some(session); + } + } + + None +} + +impl StreamHandler> for CoturnStats { + fn handle( + &mut self, + item: Option, + ctx: &mut Self::Context, + ) { + if let Some(msg) = item { + let event = if let Ok(event) = CoturnEvent::parse(msg) { + event + } else { + return; + }; + let peer_id = event.peer_id; + + match event.event { + CoturnAllocationEvent::New { lifetime: _ } => { + if let Some(subscription_request) = + self.awaits_allocation.get(&event.peer_id) + { + let coturn_client = self.coturn_client.clone(); + let room_id = subscription_request.room_id.clone(); + ctx.spawn( + async move { + let sess = format!("{}_{}", room_id, event.peer_id.to_string()); + coturn_client.get_sessions(sess).await + } + .into_actor(self) + .map(move |res, this, ctx| { + let sessions = res.unwrap(); + let relay_session = if let Some(relay_session) = find_relay_session(sessions){ + relay_session + } else { + return; + }; + let subscription_req = this.awaits_allocation.remove(&peer_id).unwrap(); + let partner_peer_id = subscription_req.partner_peer_id; + let allocation = Rc::new(RefCell::new(PublisherAllocation { + allocation_id: relay_session.id.0, + peer_id, + state: PublisherAllocationState::Playing, + current_received_bytes: relay_session.traffic_usage.received_bytes, + current_sent_bytes: relay_session.traffic_usage.sent_bytes, + prev_received_bytes: 0, + prev_sent_bytes: 0, + events: subscription_req.events_type, + last_update: Instant::now(), + room_addr: subscription_req.addr, + })); + allocation.borrow_mut().on_start(); + + if let Some(partner_allocation_id) = this.relay_allocations_ids.get(&partner_peer_id) { + let partner_allocation_subs = this.allocations + .get_mut(partner_allocation_id).unwrap(); + let partner_allocation = partner_allocation_subs.0.clone(); + partner_allocation_subs.1 = Some(allocation.clone()); + + this.allocations.insert(relay_session.id.0, (allocation, Some(partner_allocation))); + } else { + this.allocations.insert(relay_session.id.0, (allocation, None)); + } + this.relay_allocations_ids.insert(peer_id, relay_session.id.0); + }) + ); + } + } + CoturnAllocationEvent::Traffic { traffic } => { + if let Some((allocation, partner_allocation)) = + self.allocations.get(&event.allocation_id) + { + allocation.borrow_mut().update_traffic(traffic); + if let Some(partner_allocation) = partner_allocation { + partner_allocation + .borrow_mut() + .update_received_bytes(traffic.sent_bytes); + partner_allocation + .borrow_mut() + .update_send_bytes(traffic.received_bytes); + } + } + } + CoturnAllocationEvent::Deleted => { + if let Some((allocation, partner_allocation)) = + self.allocations.remove(&event.allocation_id) + { + if let Some(partner_allocation) = partner_allocation { + let partner_allocation_id = + partner_allocation.borrow().allocation_id; + self.allocations.remove(&partner_allocation_id); + } + } + } + _ => (), + } + } else { + todo!("Implement reconnection logic.") + } + } +} + +#[derive(Message, Debug)] +#[rtype(result = "Result<(), CoturnCliError>")] +pub struct Subscribe { + // TODO: recipient + pub addr: Addr, + pub events_type: HashSet, + pub room_id: RoomId, + pub partner_peer_id: PeerId, + pub peer_id: PeerId, +} + +pub type ActFuture = Box>; + +impl Handler for CoturnStats { + type Result = ActFuture>; + + fn handle( + &mut self, + msg: Subscribe, + ctx: &mut Self::Context, + ) -> Self::Result { + let coturn_client = self.coturn_client.clone(); + let peer_id = msg.peer_id; + let session_id = format!("{}_{}", msg.room_id, msg.peer_id); + Box::new( + async move { coturn_client.get_sessions(session_id).await } + .into_actor(self) + .map(move |res, this, ctx| { + let sessions = res?; + + let relay_session = if let Some(relay_session) = + find_relay_session(sessions) + { + relay_session + } else { + this.awaits_allocation.insert(peer_id, msg); + return Ok(()); + }; + let subscription_req = msg; + let partner_peer_id = subscription_req.partner_peer_id; + let allocation = + Rc::new(RefCell::new(PublisherAllocation { + allocation_id: relay_session.id.0, + peer_id, + state: PublisherAllocationState::Playing, + current_received_bytes: relay_session + .traffic_usage + .received_bytes, + current_sent_bytes: relay_session + .traffic_usage + .sent_bytes, + prev_received_bytes: 0, + prev_sent_bytes: 0, + events: subscription_req.events_type, + last_update: Instant::now(), + room_addr: subscription_req.addr, + })); + allocation.borrow_mut().on_start(); + + if let Some(partner_allocation_id) = + this.relay_allocations_ids.get(&partner_peer_id) + { + let partner_allocation_subs = this + .allocations + .get_mut(partner_allocation_id) + .unwrap(); + let partner_allocation = + partner_allocation_subs.0.clone(); + partner_allocation_subs.1 = Some(allocation.clone()); + + this.allocations.insert( + relay_session.id.0, + (allocation, Some(partner_allocation)), + ); + } else { + this.allocations + .insert(relay_session.id.0, (allocation, None)); + } + this.relay_allocations_ids + .insert(peer_id, relay_session.id.0); + + Ok(()) + }), + ) + } } diff --git a/src/turn/mod.rs b/src/turn/mod.rs index 6561bc2f9..2f80a7beb 100644 --- a/src/turn/mod.rs +++ b/src/turn/mod.rs @@ -2,7 +2,7 @@ //! //! [TURN]: https://webrtcglossary.com/turn -mod cli; +pub mod cli; pub mod coturn_stats; pub mod repo; pub mod service; From e38e5b5017a5df5ada6ea54e07b676f3f0c2aad8 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Fri, 21 Feb 2020 17:45:51 +0300 Subject: [PATCH 053/224] Refactor --- src/turn/coturn_stats.rs | 202 ++++++++++++++++++++++----------------- 1 file changed, 115 insertions(+), 87 deletions(-) diff --git a/src/turn/coturn_stats.rs b/src/turn/coturn_stats.rs index 1c427020d..9d9173ab6 100644 --- a/src/turn/coturn_stats.rs +++ b/src/turn/coturn_stats.rs @@ -448,6 +448,62 @@ impl CoturnStats { relay_allocations_ids: HashMap::new(), }) } + + pub fn try_init_allocation( + &mut self, + sessions: Vec, + peer_id: PeerId, + ) -> Result<(), CoturnCliError> { + let relay_session = + if let Some(relay_session) = find_relay_session(sessions) { + relay_session + } else { + return Ok(()); + }; + let subscription_req = + if let Some(s) = self.awaits_allocation.remove(&peer_id) { + s + } else { + return Ok(()); + }; + let partner_peer_id = subscription_req.partner_peer_id; + let allocation = Rc::new(RefCell::new(PublisherAllocation { + allocation_id: relay_session.id.0, + peer_id, + state: PublisherAllocationState::Playing, + current_received_bytes: relay_session.traffic_usage.received_bytes, + current_sent_bytes: relay_session.traffic_usage.sent_bytes, + prev_received_bytes: 0, + prev_sent_bytes: 0, + events: subscription_req.events_type, + last_update: Instant::now(), + room_addr: subscription_req.addr, + })); + allocation.borrow_mut().on_start(); + + if let Some(partner_allocation_id) = + self.relay_allocations_ids.get(&partner_peer_id) + { + let partner_allocation_subs = self + .allocations + .get_mut(partner_allocation_id) + .expect("476"); + let partner_allocation = partner_allocation_subs.0.clone(); + partner_allocation_subs.1 = Some(allocation.clone()); + + self.allocations.insert( + relay_session.id.0, + (allocation, Some(partner_allocation)), + ); + } else { + self.allocations + .insert(relay_session.id.0, (allocation, None)); + } + self.relay_allocations_ids + .insert(peer_id, relay_session.id.0); + + Ok(()) + } } impl Actor for CoturnStats { @@ -508,45 +564,30 @@ impl StreamHandler> for CoturnStats { let room_id = subscription_request.room_id.clone(); ctx.spawn( async move { - let sess = format!("{}_{}", room_id, event.peer_id.to_string()); + tokio::time::delay_for(Duration::from_millis( + 500, + )) + .await; + let sess = format!( + "{}_{}", + room_id, + event.peer_id.to_string() + ); coturn_client.get_sessions(sess).await } - .into_actor(self) - .map(move |res, this, ctx| { - let sessions = res.unwrap(); - let relay_session = if let Some(relay_session) = find_relay_session(sessions){ - relay_session - } else { - return; - }; - let subscription_req = this.awaits_allocation.remove(&peer_id).unwrap(); - let partner_peer_id = subscription_req.partner_peer_id; - let allocation = Rc::new(RefCell::new(PublisherAllocation { - allocation_id: relay_session.id.0, - peer_id, - state: PublisherAllocationState::Playing, - current_received_bytes: relay_session.traffic_usage.received_bytes, - current_sent_bytes: relay_session.traffic_usage.sent_bytes, - prev_received_bytes: 0, - prev_sent_bytes: 0, - events: subscription_req.events_type, - last_update: Instant::now(), - room_addr: subscription_req.addr, - })); - allocation.borrow_mut().on_start(); - - if let Some(partner_allocation_id) = this.relay_allocations_ids.get(&partner_peer_id) { - let partner_allocation_subs = this.allocations - .get_mut(partner_allocation_id).unwrap(); - let partner_allocation = partner_allocation_subs.0.clone(); - partner_allocation_subs.1 = Some(allocation.clone()); - - this.allocations.insert(relay_session.id.0, (allocation, Some(partner_allocation))); - } else { - this.allocations.insert(relay_session.id.0, (allocation, None)); + .into_actor(self) + .map( + move |res, this, ctx| match res { + Ok(sessions) => { + this.try_init_allocation( + sessions, peer_id, + ); } - this.relay_allocations_ids.insert(peer_id, relay_session.id.0); - }) + Err(e) => { + println!("\n\n{:?}\n\n", e); + } + }, + ), ); } } @@ -563,6 +604,36 @@ impl StreamHandler> for CoturnStats { .borrow_mut() .update_send_bytes(traffic.received_bytes); } + } else { + if let Some(subscription_request) = + self.awaits_allocation.get(&event.peer_id) + { + let coturn_client = self.coturn_client.clone(); + let room_id = subscription_request.room_id.clone(); + ctx.spawn( + async move { + let sess = format!( + "{}_{}", + room_id, + event.peer_id.to_string() + ); + coturn_client.get_sessions(sess).await + } + .into_actor(self) + .map( + move |res, this, ctx| match res { + Ok(sessions) => { + this.try_init_allocation( + sessions, peer_id, + ); + } + Err(e) => { + println!("\n\n{:?}\n\n", e); + } + }, + ), + ); + } } } CoturnAllocationEvent::Deleted => { @@ -608,62 +679,19 @@ impl Handler for CoturnStats { let coturn_client = self.coturn_client.clone(); let peer_id = msg.peer_id; let session_id = format!("{}_{}", msg.room_id, msg.peer_id); + self.awaits_allocation.insert(peer_id, msg); Box::new( async move { coturn_client.get_sessions(session_id).await } .into_actor(self) .map(move |res, this, ctx| { - let sessions = res?; - - let relay_session = if let Some(relay_session) = - find_relay_session(sessions) - { - relay_session - } else { - this.awaits_allocation.insert(peer_id, msg); - return Ok(()); - }; - let subscription_req = msg; - let partner_peer_id = subscription_req.partner_peer_id; - let allocation = - Rc::new(RefCell::new(PublisherAllocation { - allocation_id: relay_session.id.0, - peer_id, - state: PublisherAllocationState::Playing, - current_received_bytes: relay_session - .traffic_usage - .received_bytes, - current_sent_bytes: relay_session - .traffic_usage - .sent_bytes, - prev_received_bytes: 0, - prev_sent_bytes: 0, - events: subscription_req.events_type, - last_update: Instant::now(), - room_addr: subscription_req.addr, - })); - allocation.borrow_mut().on_start(); - - if let Some(partner_allocation_id) = - this.relay_allocations_ids.get(&partner_peer_id) - { - let partner_allocation_subs = this - .allocations - .get_mut(partner_allocation_id) - .unwrap(); - let partner_allocation = - partner_allocation_subs.0.clone(); - partner_allocation_subs.1 = Some(allocation.clone()); - - this.allocations.insert( - relay_session.id.0, - (allocation, Some(partner_allocation)), - ); - } else { - this.allocations - .insert(relay_session.id.0, (allocation, None)); + match res { + Ok(sessions) => { + this.try_init_allocation(sessions, peer_id); + } + Err(e) => { + println!("\n\n{:?}\n\n", e); + } } - this.relay_allocations_ids - .insert(peer_id, relay_session.id.0); Ok(()) }), From 57466866a99ad1bda4eee3f8cefc8f84b10afdef Mon Sep 17 00:00:00 2001 From: alexlapa Date: Tue, 25 Feb 2020 18:59:14 +0200 Subject: [PATCH 054/224] implementing rtc stats parsing --- jason/Cargo.toml | 2 +- jason/src/peer/conn.rs | 31 ++++--- jason/src/peer/mod.rs | 1 + jason/src/peer/stats/mod.rs | 169 ++++++++++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+), 13 deletions(-) create mode 100644 jason/src/peer/stats/mod.rs diff --git a/jason/Cargo.toml b/jason/Cargo.toml index 460b7814d..a85e0077f 100644 --- a/jason/Cargo.toml +++ b/jason/Cargo.toml @@ -62,7 +62,7 @@ wee_alloc = { version = "0.4", optional = true } "RtcRtpReceiver", "RtcRtpSender", "RtcRtpTransceiver", "RtcRtpTransceiverDirection", "RtcRtpTransceiverInit", - "RtcSdpType", + "RtcSdpType", "RtcStats", "RtcSessionDescription", "RtcSessionDescriptionInit", "RtcTrackEvent", "WebSocket", "Window", diff --git a/jason/src/peer/conn.rs b/jason/src/peer/conn.rs index def89a9a5..2552f272c 100644 --- a/jason/src/peer/conn.rs +++ b/jason/src/peer/conn.rs @@ -3,8 +3,8 @@ use std::{cell::RefCell, rc::Rc}; use derive_more::Display; use medea_client_api_proto::{Direction as DirectionProto, IceServer}; use tracerr::Traced; -use wasm_bindgen::{JsCast, closure::Closure, JsValue, prelude::*}; -use wasm_bindgen_futures::{JsFuture, spawn_local}; +use wasm_bindgen::{closure::Closure, prelude::*, JsCast, JsValue}; +use wasm_bindgen_futures::{spawn_local, JsFuture}; use web_sys::{ Event, RtcConfiguration, RtcIceCandidateInit, RtcIceConnectionState, RtcIceTransportPolicy, RtcPeerConnection as SysRtcPeerConnection, @@ -15,7 +15,11 @@ use web_sys::{ use crate::{ media::TrackConstraints, - utils::{EventListener, EventListenerBindError, JsCaused, JsError, window, console_error}, + utils::{ + console_error, window, EventListener, EventListenerBindError, JsCaused, + JsError, + }, + peer::stats::RtcStats }; use super::ice_server::RtcIceServers; @@ -247,19 +251,25 @@ impl RtcPeerConnection { let peer = Rc::new(peer); - let peer_clone = Rc::clone(&peer); let a = Closure::wrap(Box::new(move || { let another_peer_clone = Rc::clone(&peer_clone); spawn_local(async move { let stats = JsFuture::from(another_peer_clone.get_stats()) - .await.unwrap(); + .await + .unwrap(); + + let statssss = RtcStats::from(&stats); + asd(&stats); -// js_sys::JSON::stringify -// console_error(&stats); }); }) as Box); - window().set_interval_with_callback_and_timeout_and_arguments_0(a.as_ref().unchecked_ref(), 1000).unwrap(); + window() + .set_interval_with_callback_and_timeout_and_arguments_0( + a.as_ref().unchecked_ref(), + 10000, + ) + .unwrap(); a.forget(); Ok(Self { @@ -556,10 +566,7 @@ impl Drop for RtcPeerConnection { } } - #[wasm_bindgen(inline_js = "export function asd(arg) { window.asd = arg; }")] extern "C" { - fn asd( - arg: &JsValue, - ); + fn asd(arg: &JsValue); } diff --git a/jason/src/peer/mod.rs b/jason/src/peer/mod.rs index 5030c234d..536b05aa7 100644 --- a/jason/src/peer/mod.rs +++ b/jason/src/peer/mod.rs @@ -6,6 +6,7 @@ mod conn; mod ice_server; mod media; mod repo; +mod stats; mod stream; mod stream_request; mod track; diff --git a/jason/src/peer/stats/mod.rs b/jason/src/peer/stats/mod.rs new file mode 100644 index 000000000..de84103f4 --- /dev/null +++ b/jason/src/peer/stats/mod.rs @@ -0,0 +1,169 @@ +//! Spec is quite new atm, and is poorly adopted by UA's: +//! +//! +//! https://www.w3.org/TR/webrtc-stats/ + +use web_sys::RtcStats as SysRtcStats; +use wasm_bindgen::{prelude::*, JsCast}; + +use crate::utils::get_property_by_name; + +use crate::utils::console_error; +use std::convert::TryFrom; + +#[derive(Debug)] +pub struct RtcStats { + ice_pairs: Vec, +} + +impl From<&JsValue> for RtcStats { + fn from(stats: &JsValue) -> Self { + let entries_fn = + get_property_by_name(&stats, "entries", |func: JsValue| { + Some(func.unchecked_into::()) + }).unwrap(); + + let iterator = entries_fn.call0(stats.as_ref()).unwrap().unchecked_into::(); + + let ice_pairs = Vec::new(); + + let mut next = iterator.next().unwrap(); + while !next.done(){ + let stat = next.value(); + + let stat = RtcStatsType::try_from(stat.as_ref()).unwrap(); +// console_error(&stat); + + next = iterator.next().unwrap(); + } + + RtcStats { + ice_pairs, + } + } +} + +/// https://www.w3.org/TR/webrtc-stats/#rtctatstype-* +#[derive(Debug)] +enum RtcStatsType { + Codec, + InboundRtp, + OutboundRtp, + RemoteInboundRtp, + RemoteOutboundRtp, + MediaSoure, + Csrc, + PeerConnection, + DataChannel, + Stream, + Track, + Transceiver, + Sender, + Receiver, + Transport, + SctpTransport, + CandidatePair(RtcIceCandidatePairStats), + LocalCandidate, + RemoteCandidate, + Certificate, + IceServer, + Unknown(String), +} + +impl TryFrom<&JsValue> for RtcStatsType { + type Error = (); + + fn try_from(val: &JsValue) -> Result { + let _type = get_property_by_name(&val, "type", |_type| { + _type.as_string() + }).unwrap(); + + use RtcStatsType::*; + let stat = match _type.as_ref() { + "codec" => Codec, + "local-candidate" => LocalCandidate, + "remote-candidate" => RemoteCandidate, + "track" => Track, + "candidate-pair" => { + CandidatePair(RtcIceCandidatePairStats::from(&val)) + }, + "inbound-rtp" => InboundRtp, + "outbound-rtp" => OutboundRtp, + "remote-inbound-rtp" => RemoteInboundRtp, + "remote-outbound-rtp" => RemoteOutboundRtp, + "media-source" => MediaSoure, + "csrc" => Csrc, + "peer-connection" => PeerConnection, + "data-channel" => DataChannel, + "stream" => Stream, + "transceiver" => Transceiver, + "sender" => Sender, + "receiver" => Receiver, + "transport" => Transport, + "sctp-transport" => SctpTransport, + "certificate" => Certificate, + "ice-server" => IceServer, + _ => Unknown(_type.to_owned()), + }; + + Ok(stat) + } +} + +// https://www.w3.org/TR/webrtc-stats/#candidatepair-dict* +#[derive(Debug)] +struct RtcIceCandidatePairStats { + state: IceCandidatePairState, + nominated: bool, + writable: bool, + bytes_sent: u64, + bytes_received: u64, + total_round_trip_time: f32, + current_round_trip_time: f32, + available_outgoing_bitrate: u64, +} + +impl From<&JsValue> for RtcIceCandidatePairStats { + fn from(val: &JsValue) -> Self { + let state = get_property_by_name(&val, "state", |val|val.as_string()).unwrap(); + + + let stat = RtcIceCandidatePairStats { + state: IceCandidatePairState::from(state.as_ref()), + nominated: false, + writable: false, + bytes_sent: 0, + bytes_received: 0, + total_round_trip_time: 0.0, + current_round_trip_time: 0.0, + available_outgoing_bitrate: 0 + }; + + stat + } +} + +// https://www.w3.org/TR/webrtc-stats/#rtcstatsicecandidatepairstate-enum +#[derive(Debug)] +enum IceCandidatePairState { + Frozen, + Waiting, + Inprogress, + Failed, + Succeeded, + Unknown(String), +} + +impl From<&str> for IceCandidatePairState { + fn from(state: &str) -> Self { + use IceCandidatePairState::*; + match state { + "waiting" => Waiting, + "succeeded" => Succeeded, + "in-progress" => Inprogress, + "frozen" => Frozen, + "failed" => Failed, + _ => Unknown(state.to_owned()), + } + } +} From 1d00ff62e45b00e38b60258a64a4570bf7963d2b Mon Sep 17 00:00:00 2001 From: alexlapa Date: Wed, 26 Feb 2020 12:55:26 +0200 Subject: [PATCH 055/224] implementing stats --- jason/src/peer/conn.rs | 6 +- jason/src/peer/stats/mod.rs | 159 +++++++++++++++++++++++++++--------- 2 files changed, 122 insertions(+), 43 deletions(-) diff --git a/jason/src/peer/conn.rs b/jason/src/peer/conn.rs index 2552f272c..6c4f5469b 100644 --- a/jason/src/peer/conn.rs +++ b/jason/src/peer/conn.rs @@ -15,11 +15,11 @@ use web_sys::{ use crate::{ media::TrackConstraints, + peer::stats::RtcStats, utils::{ console_error, window, EventListener, EventListenerBindError, JsCaused, JsError, }, - peer::stats::RtcStats }; use super::ice_server::RtcIceServers; @@ -259,9 +259,9 @@ impl RtcPeerConnection { .await .unwrap(); - let statssss = RtcStats::from(&stats); - asd(&stats); + +// let statssss = RtcStats::from(&stats); }); }) as Box); window() diff --git a/jason/src/peer/stats/mod.rs b/jason/src/peer/stats/mod.rs index de84103f4..957bd3474 100644 --- a/jason/src/peer/stats/mod.rs +++ b/jason/src/peer/stats/mod.rs @@ -1,19 +1,59 @@ -//! Spec is quite new atm, and is poorly adopted by UA's: +//! [Spec][] is quite new atm, and is poorly adopted by UA's. //! +//! [RTCStatsReport][2] allows [maplike][3] operations. [entries()][4] operation +//! returns array of arrays, where first value is [RTCStats.id][5] and second is +//! actual [RTCStats][6]. +//! +//! [1]: https://www.w3.org/TR/webrtc-stats/ +//! [2]: https://www.w3.org/TR/webrtc/#rtcstatsreport-object +//! [3]: https://heycam.github.io/webidl/#idl-maplike +//! [4]: https://heycam.github.io/webidl/#es-map-entries +//! [5]: https://www.w3.org/TR/webrtc/#dom-rtcstats-id +//! [6]: https://www.w3.org/TR/webrtc/#dom-rtcstats //! -//! https://www.w3.org/TR/webrtc-stats/ -use web_sys::RtcStats as SysRtcStats; +use std::convert::TryFrom; + use wasm_bindgen::{prelude::*, JsCast}; +use web_sys::RtcStats as SysRtcStats; use crate::utils::get_property_by_name; - use crate::utils::console_error; -use std::convert::TryFrom; + +struct RtcStatsReportEntry(js_sys::JsString, SysRtcStats); + +impl TryFrom for RtcStatsReportEntry { + type Error = (); + + fn try_from(value: js_sys::Array) -> Result { + let id = value.get(0); + let stats = value.get(1); + + if id.is_undefined() { + panic!("asdasd"); + } + + if stats.is_undefined() { + panic!("asdasd2222"); + } + + let id = id.dyn_into::().unwrap(); + let stats = stats.dyn_into::().unwrap(); + + Ok(RtcStatsReportEntry(id, stats)) + } +} + +#[derive(Debug)] +pub struct RtcStat { + id: String, + timestamp: u64, + kind: T, +} #[derive(Debug)] pub struct RtcStats { - ice_pairs: Vec, + ice_pairs: Vec>, } impl From<&JsValue> for RtcStats { @@ -21,25 +61,45 @@ impl From<&JsValue> for RtcStats { let entries_fn = get_property_by_name(&stats, "entries", |func: JsValue| { Some(func.unchecked_into::()) - }).unwrap(); + }) + .unwrap(); - let iterator = entries_fn.call0(stats.as_ref()).unwrap().unchecked_into::(); + let iterator = entries_fn + .call0(stats.as_ref()) + .unwrap() + .unchecked_into::(); - let ice_pairs = Vec::new(); + let mut ice_pairs = Vec::new(); let mut next = iterator.next().unwrap(); - while !next.done(){ + while !next.done() { let stat = next.value(); - - let stat = RtcStatsType::try_from(stat.as_ref()).unwrap(); -// console_error(&stat); + let stat = stat.unchecked_into::(); + let stat = RtcStatsReportEntry::try_from(stat).unwrap(); + let stat = + RtcStatsType::try_from(&stat.1) + .unwrap(); + + match stat { + RtcStatsType::CandidatePair(pair) => { + if pair.nominated { + ice_pairs.push(pair); + } + } + RtcStatsType::Unknown(unknown_stat) => { + // print error + } + _ => { + // ignore + } + } next = iterator.next().unwrap(); } - RtcStats { - ice_pairs, - } + console_error(format!("{:?}", ice_pairs)); + + RtcStats { ice_pairs } } } @@ -62,7 +122,7 @@ enum RtcStatsType { Receiver, Transport, SctpTransport, - CandidatePair(RtcIceCandidatePairStats), + CandidatePair(RtcStat), LocalCandidate, RemoteCandidate, Certificate, @@ -70,23 +130,24 @@ enum RtcStatsType { Unknown(String), } -impl TryFrom<&JsValue> for RtcStatsType { +impl TryFrom<&SysRtcStats> for RtcStatsType { type Error = (); - fn try_from(val: &JsValue) -> Result { - let _type = get_property_by_name(&val, "type", |_type| { - _type.as_string() - }).unwrap(); + fn try_from(val: &SysRtcStats) -> Result { + let type_ = get_property_by_name(&val, "type", |type_| { + type_.as_string() + }) + .unwrap(); use RtcStatsType::*; - let stat = match _type.as_ref() { + let stat = match type_.as_ref() { "codec" => Codec, "local-candidate" => LocalCandidate, "remote-candidate" => RemoteCandidate, "track" => Track, "candidate-pair" => { - CandidatePair(RtcIceCandidatePairStats::from(&val)) - }, + CandidatePair(RtcIceCandidatePairStats::from(val)) + } "inbound-rtp" => InboundRtp, "outbound-rtp" => OutboundRtp, "remote-inbound-rtp" => RemoteInboundRtp, @@ -103,7 +164,7 @@ impl TryFrom<&JsValue> for RtcStatsType { "sctp-transport" => SctpTransport, "certificate" => Certificate, "ice-server" => IceServer, - _ => Unknown(_type.to_owned()), + _ => Unknown(type_), }; Ok(stat) @@ -118,25 +179,32 @@ struct RtcIceCandidatePairStats { writable: bool, bytes_sent: u64, bytes_received: u64, - total_round_trip_time: f32, - current_round_trip_time: f32, - available_outgoing_bitrate: u64, + total_round_trip_time: f64, + current_round_trip_time: Option, + available_outgoing_bitrate: Option, } -impl From<&JsValue> for RtcIceCandidatePairStats { - fn from(val: &JsValue) -> Self { - let state = get_property_by_name(&val, "state", |val|val.as_string()).unwrap(); - +impl From<&SysRtcStats> for RtcIceCandidatePairStats { + fn from(val: &SysRtcStats) -> Self { + let state = + get_property_by_name(&val, "state", |val| val.as_string()).unwrap(); + let nominated = get_property_by_name(&val, "nominated", |val| val.as_bool()).unwrap(); + let writable = get_property_by_name(&val, "writable", |val| val.as_bool()).unwrap(); + let bytes_sent = get_property_by_name(&val, "bytesSent", |val| val.as_f64()).unwrap() as u64; + let bytes_received = get_property_by_name(&val, "bytesReceived", |val| val.as_f64()).unwrap() as u64; + let total_round_trip_time = get_property_by_name(&val, "totalRoundTripTime", |val| val.as_f64()).unwrap(); + let current_round_trip_time = get_property_by_name(&val, "currentRoundTripTime", |val| val.as_f64()); + let available_outgoing_bitrate = get_property_by_name(&val, "availableOutgoingBitrate", |val| val.as_f64()).map(|val| val as u64); let stat = RtcIceCandidatePairStats { state: IceCandidatePairState::from(state.as_ref()), - nominated: false, - writable: false, - bytes_sent: 0, - bytes_received: 0, - total_round_trip_time: 0.0, - current_round_trip_time: 0.0, - available_outgoing_bitrate: 0 + nominated, + writable, + bytes_sent, + bytes_received, + total_round_trip_time, + current_round_trip_time, + available_outgoing_bitrate, }; stat @@ -167,3 +235,14 @@ impl From<&str> for IceCandidatePairState { } } } + +//#[derive(Debug)] +//struct RTCInboundRtpStreamStats { +// nominated: bool, +// writable: bool, +// bytes_sent: u64, +// bytes_received: u64, +// total_round_trip_time: f64, +// current_round_trip_time: Option, +// available_outgoing_bitrate: Option, +//} From fb9f18917d3ee39d49161335f5fc160853241fbd Mon Sep 17 00:00:00 2001 From: alexlapa Date: Wed, 26 Feb 2020 20:02:07 +0200 Subject: [PATCH 056/224] asd --- jason/src/peer/conn.rs | 2 +- jason/src/peer/stats/mod.rs | 105 +++++++++++++++++++++++------------- 2 files changed, 68 insertions(+), 39 deletions(-) diff --git a/jason/src/peer/conn.rs b/jason/src/peer/conn.rs index 6c4f5469b..1db9f18e9 100644 --- a/jason/src/peer/conn.rs +++ b/jason/src/peer/conn.rs @@ -261,7 +261,7 @@ impl RtcPeerConnection { asd(&stats); -// let statssss = RtcStats::from(&stats); + console_error(format!("{:?}", RtcStats::from(&stats))); }); }) as Box); window() diff --git a/jason/src/peer/stats/mod.rs b/jason/src/peer/stats/mod.rs index 957bd3474..2519c3c11 100644 --- a/jason/src/peer/stats/mod.rs +++ b/jason/src/peer/stats/mod.rs @@ -18,7 +18,6 @@ use wasm_bindgen::{prelude::*, JsCast}; use web_sys::RtcStats as SysRtcStats; use crate::utils::get_property_by_name; -use crate::utils::console_error; struct RtcStatsReportEntry(js_sys::JsString, SysRtcStats); @@ -51,6 +50,16 @@ pub struct RtcStat { kind: T, } +impl RtcStat { + fn new(id: String, timestamp: u64, kind: T) -> RtcStat { + RtcStat { + id, + timestamp, + kind, + } + } +} + #[derive(Debug)] pub struct RtcStats { ice_pairs: Vec>, @@ -76,13 +85,11 @@ impl From<&JsValue> for RtcStats { let stat = next.value(); let stat = stat.unchecked_into::(); let stat = RtcStatsReportEntry::try_from(stat).unwrap(); - let stat = - RtcStatsType::try_from(&stat.1) - .unwrap(); + let stat = RtcStatsType::try_from(&stat.1).unwrap(); match stat { RtcStatsType::CandidatePair(pair) => { - if pair.nominated { + if pair.kind.nominated { ice_pairs.push(pair); } } @@ -97,8 +104,6 @@ impl From<&JsValue> for RtcStats { next = iterator.next().unwrap(); } - console_error(format!("{:?}", ice_pairs)); - RtcStats { ice_pairs } } } @@ -134,20 +139,27 @@ impl TryFrom<&SysRtcStats> for RtcStatsType { type Error = (); fn try_from(val: &SysRtcStats) -> Result { - let type_ = get_property_by_name(&val, "type", |type_| { - type_.as_string() + use RtcStatsType::*; + + let id = get_property_by_name(&val, "id", |id| id.as_string()).unwrap(); + let timestamp = get_property_by_name(&val, "timestamp", |timestamp| { + timestamp.as_f64().map(|timestamp| timestamp as u64) }) .unwrap(); + let kind = + get_property_by_name(&val, "type", |type_| type_.as_string()) + .unwrap(); - use RtcStatsType::*; - let stat = match type_.as_ref() { + let kind = match kind.as_ref() { "codec" => Codec, "local-candidate" => LocalCandidate, "remote-candidate" => RemoteCandidate, "track" => Track, - "candidate-pair" => { - CandidatePair(RtcIceCandidatePairStats::from(val)) - } + "candidate-pair" => CandidatePair(RtcStat::new( + id, + timestamp, + RtcIceCandidatePairStats::from(val), + )), "inbound-rtp" => InboundRtp, "outbound-rtp" => OutboundRtp, "remote-inbound-rtp" => RemoteInboundRtp, @@ -164,10 +176,10 @@ impl TryFrom<&SysRtcStats> for RtcStatsType { "sctp-transport" => SctpTransport, "certificate" => Certificate, "ice-server" => IceServer, - _ => Unknown(type_), + _ => Unknown(kind), }; - Ok(stat) + Ok(kind) } } @@ -188,15 +200,35 @@ impl From<&SysRtcStats> for RtcIceCandidatePairStats { fn from(val: &SysRtcStats) -> Self { let state = get_property_by_name(&val, "state", |val| val.as_string()).unwrap(); - let nominated = get_property_by_name(&val, "nominated", |val| val.as_bool()).unwrap(); - let writable = get_property_by_name(&val, "writable", |val| val.as_bool()).unwrap(); - let bytes_sent = get_property_by_name(&val, "bytesSent", |val| val.as_f64()).unwrap() as u64; - let bytes_received = get_property_by_name(&val, "bytesReceived", |val| val.as_f64()).unwrap() as u64; - let total_round_trip_time = get_property_by_name(&val, "totalRoundTripTime", |val| val.as_f64()).unwrap(); - let current_round_trip_time = get_property_by_name(&val, "currentRoundTripTime", |val| val.as_f64()); - let available_outgoing_bitrate = get_property_by_name(&val, "availableOutgoingBitrate", |val| val.as_f64()).map(|val| val as u64); - - let stat = RtcIceCandidatePairStats { + let nominated = + get_property_by_name(&val, "nominated", |val| val.as_bool()) + .unwrap(); + let writable = + get_property_by_name(&val, "writable", |val| val.as_bool()) + .unwrap(); + let bytes_sent = get_property_by_name(&val, "bytesSent", |val| { + val.as_f64() + }) + .unwrap() as u64; + let bytes_received = + get_property_by_name(&val, "bytesReceived", |val| val.as_f64()) + .unwrap() as u64; + let total_round_trip_time = + get_property_by_name(&val, "totalRoundTripTime", |val| { + val.as_f64() + }) + .unwrap(); + let current_round_trip_time = + get_property_by_name(&val, "currentRoundTripTime", |val| { + val.as_f64() + }); + let available_outgoing_bitrate = + get_property_by_name(&val, "availableOutgoingBitrate", |val| { + val.as_f64() + }) + .map(|val| val as u64); + + RtcIceCandidatePairStats { state: IceCandidatePairState::from(state.as_ref()), nominated, writable, @@ -205,9 +237,7 @@ impl From<&SysRtcStats> for RtcIceCandidatePairStats { total_round_trip_time, current_round_trip_time, available_outgoing_bitrate, - }; - - stat + } } } @@ -236,13 +266,12 @@ impl From<&str> for IceCandidatePairState { } } -//#[derive(Debug)] -//struct RTCInboundRtpStreamStats { -// nominated: bool, -// writable: bool, -// bytes_sent: u64, -// bytes_received: u64, -// total_round_trip_time: f64, -// current_round_trip_time: Option, -// available_outgoing_bitrate: Option, -//} +// https://www.w3.org/TR/webrtc-stats/#inboundrtpstats-dict* +#[derive(Debug)] + struct RtcInboundRtpStreamStats { + media_type: bool, + bytes_received: u64, + packets_received: u64, + packets_lost: u64, + jitter: f64 +} From 88aa4c3fea4a363ca4906bd1a154b827e1d9f9a6 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Thu, 27 Feb 2020 16:46:56 +0300 Subject: [PATCH 057/224] on_stop with watchdog --- Cargo.lock | 18 +++++++++++++++--- src/turn/coturn_stats.rs | 31 +++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80f139691..0a604f954 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -641,6 +641,19 @@ dependencies = [ "unreachable", ] +[[package]] +name = "combine" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c875843236b5e2eb535fd0b696387bfb623f896479b10ed626cf442b836e8032" +dependencies = [ + "bytes", + "futures-util", + "memchr", + "pin-project-lite", + "tokio", +] + [[package]] name = "config" version = "0.10.1" @@ -2205,7 +2218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eeb1fe3fc011cde97315f370bc88e4db3c23b08709a04915921e02b1d363b20" dependencies = [ "bytes", - "combine", + "combine 3.8.1", "dtoa", "futures-executor", "futures-util", @@ -2223,9 +2236,8 @@ name = "redis" version = "0.15.2-alpha.0" dependencies = [ "bytes", - "combine", + "combine 4.0.1", "dtoa", - "futures-executor", "futures-util", "itoa", "percent-encoding 2.1.0", diff --git a/src/turn/coturn_stats.rs b/src/turn/coturn_stats.rs index 9d9173ab6..e746f6a54 100644 --- a/src/turn/coturn_stats.rs +++ b/src/turn/coturn_stats.rs @@ -337,7 +337,7 @@ pub fn run_coturn_stats_watcher(cf: &conf::Turn) { }); } -#[derive(Debug)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum PublisherAllocationState { Stopped, Playing, @@ -386,12 +386,22 @@ impl PublisherAllocation { self.last_update = Instant::now(); } - pub fn on_start(&self) { + pub fn on_start(&mut self) { + self.state = PublisherAllocationState::Playing; self.room_addr.do_send(OnStartOnStopCallback { peer_id: self.peer_id, event: EventType::OnStart, }); } + + pub fn on_stop(&mut self) { + self.state = PublisherAllocationState::Stopped; + + self.room_addr.do_send(OnStartOnStopCallback { + peer_id: self.peer_id, + event: EventType::OnStop, + }); + } } impl Drop for PublisherAllocation { @@ -527,6 +537,23 @@ impl Actor for CoturnStats { } .into_actor(self), ); + + ctx.run_interval(Duration::from_millis(500), |this, ctx| { + for (id, (allocation, partner_allocation)) in &this.allocations { + let last_update = allocation.borrow().last_update; + let allocation_state = allocation.borrow().state; + if last_update + Duration::from_secs(3) < Instant::now() { + if allocation_state == PublisherAllocationState::Playing { + allocation.borrow_mut().on_stop(); + } + } else { + if allocation_state == PublisherAllocationState::Stopped { + allocation.borrow_mut().on_start(); + } + } + } + }); + ctx.add_stream(msg_stream); } } From d9942fa9c06f053205196d0d62c1b9cb533bd7d5 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Thu, 27 Feb 2020 18:28:37 +0300 Subject: [PATCH 058/224] Add on_start/on_stop events sending for the WebRtcPlayEndpoint --- src/api/control/callback/mod.rs | 26 +++++++++++ src/signalling/elements/endpoints/mod.rs | 19 ++++++++ .../endpoints/webrtc/play_endpoint.rs | 8 ++++ src/signalling/peers.rs | 25 +++++++++-- src/signalling/room.rs | 44 ++++++++++++++++++- 5 files changed, 118 insertions(+), 4 deletions(-) diff --git a/src/api/control/callback/mod.rs b/src/api/control/callback/mod.rs index 3b943c022..d624faf1d 100644 --- a/src/api/control/callback/mod.rs +++ b/src/api/control/callback/mod.rs @@ -68,11 +68,31 @@ impl Into for OnJoinEvent { } } +#[derive(Debug)] +pub struct OnStartEvent; + +impl Into for OnStartEvent { + fn into(self) -> proto::OnStart { + proto::OnStart {} + } +} + +#[derive(Debug)] +pub struct OnStopEvent; + +impl Into for OnStopEvent { + fn into(self) -> proto::OnStop { + proto::OnStop {} + } +} + /// All callbacks which can happen. #[derive(Debug, From)] pub enum CallbackEvent { OnJoin(OnJoinEvent), OnLeave(OnLeaveEvent), + OnStart(OnStartEvent), + OnStop(OnStopEvent), } impl Into for CallbackEvent { @@ -84,6 +104,12 @@ impl Into for CallbackEvent { Self::OnLeave(on_leave) => { proto::request::Event::OnLeave(on_leave.into()) } + Self::OnStart(on_start) => { + proto::request::Event::OnStart(on_start.into()) + } + Self::OnStop(on_stop) => { + proto::request::Event::OnStop(on_stop.into()) + } } } } diff --git a/src/signalling/elements/endpoints/mod.rs b/src/signalling/elements/endpoints/mod.rs index 4197e2c0e..fae2624cd 100644 --- a/src/signalling/elements/endpoints/mod.rs +++ b/src/signalling/elements/endpoints/mod.rs @@ -24,3 +24,22 @@ impl Into for Endpoint { } } } + +#[derive(Clone, Debug, From)] +pub enum WeakEndpoint { + WebRtcPublishEndpoint(webrtc::publish_endpoint::WeakWebRtcPublishEndpoint), + WebRtcPlayEndpoint(webrtc::play_endpoint::WeakWebRtcPlayEndpoint), +} + +impl WeakEndpoint { + pub fn upgrade(&self) -> Option { + match self { + WeakEndpoint::WebRtcPublishEndpoint(publish_endpoint) => { + publish_endpoint.safe_upgrade().map(|e| e.into()) + } + WeakEndpoint::WebRtcPlayEndpoint(play_endpoint) => { + play_endpoint.safe_upgrade().map(|e| e.into()) + } + } + } +} diff --git a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs index 55c6e657d..9d65497b9 100644 --- a/src/signalling/elements/endpoints/webrtc/play_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/play_endpoint.rs @@ -177,6 +177,14 @@ impl WebRtcPlayEndpoint { self.0.borrow().is_force_relayed } + pub fn on_start(&self) -> Option { + self.0.borrow().on_start.clone() + } + + pub fn on_stop(&self) -> Option { + self.0.borrow().on_stop.clone() + } + /// Downgrades [`WebRtcPlayEndpoint`] to [`WeakWebRtcPlayEndpoint`] weak /// pointer. pub fn downgrade(&self) -> WeakWebRtcPlayEndpoint { diff --git a/src/signalling/peers.rs b/src/signalling/peers.rs index 37db04e08..2ff58fb1d 100644 --- a/src/signalling/peers.rs +++ b/src/signalling/peers.rs @@ -12,12 +12,13 @@ use derive_more::Display; use medea_client_api_proto::{Incrementable, PeerId, TrackId}; use crate::{ - api::control::{MemberId, RoomId}, + api::control::{EndpointId, MemberId, RoomId}, log::prelude::*, media::{IceUser, New, Peer, PeerStateMachine}, signalling::{ - elements::endpoints::webrtc::{ - WebRtcPlayEndpoint, WebRtcPublishEndpoint, + elements::endpoints::{ + webrtc::{WebRtcPlayEndpoint, WebRtcPublishEndpoint}, + WeakEndpoint, }, room::RoomError, }, @@ -49,6 +50,8 @@ pub struct PeerRepository { /// [`MediaTrack`]: crate::media::track::MediaTrack /// [`Room`]: crate::signalling::room::Room tracks_count: Counter, + + peers_endpoints: HashMap, } /// Simple ID counter. @@ -78,6 +81,7 @@ impl PeerRepository { peers: HashMap::new(), peers_count: Counter::default(), tracks_count: Counter::default(), + peers_endpoints: HashMap::new(), } } @@ -367,7 +371,11 @@ impl PeerRepository { src_peer.add_publisher(&mut sink_peer, self.get_tracks_counter()); src.add_peer_id(src_peer_id); + self.peers_endpoints + .insert(src_peer_id, src.downgrade().into()); sink.set_peer_id(sink_peer_id); + self.peers_endpoints + .insert(sink_peer_id, sink.downgrade().into()); self.add_peer(src_peer); self.add_peer(sink_peer); @@ -377,7 +385,11 @@ impl PeerRepository { src_peer.add_publisher(&mut sink_peer, self.get_tracks_counter()); src.add_peer_id(src_peer.id()); + self.peers_endpoints + .insert(src_peer.id(), src.downgrade().into()); sink.set_peer_id(sink_peer.id()); + self.peers_endpoints + .insert(sink_peer.id(), sink.downgrade().into()); let src_peer_id = src_peer.id(); let sink_peer_id = sink_peer.id(); @@ -390,4 +402,11 @@ impl PeerRepository { None } + + pub fn get_endpoint_path_by_peer_id( + &self, + peer_id: PeerId, + ) -> Option { + self.peers_endpoints.get(&peer_id).cloned() + } } diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 4c75d6d3d..69534129c 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -26,7 +26,8 @@ use crate::{ control::{ callback::{ clients::CallbackClientFactoryImpl, service::CallbackService, - OnJoinEvent, OnLeaveEvent, OnLeaveReason, + OnJoinEvent, OnLeaveEvent, OnLeaveReason, OnStartEvent, + OnStopEvent, }, endpoints::{ webrtc_play_endpoint::Validated, @@ -1341,6 +1342,47 @@ impl Handler for Room { msg: OnStartOnStopCallback, ctx: &mut Self::Context, ) -> Self::Result { + let endpoint = self + .peers + .get_endpoint_path_by_peer_id(msg.peer_id) + .and_then(|endpoint| endpoint.upgrade()); + + use super::elements::endpoints::Endpoint; + if let Some(endpoint) = endpoint { + match endpoint { + Endpoint::WebRtcPlayEndpoint(play_endpoint) => { + let fid = play_endpoint + .owner() + .get_fid_to_endpoint(play_endpoint.id().into()); + match msg.event { + EventType::OnStart => { + if let Some(callback_url) = play_endpoint.on_start() + { + self.callbacks.send_callback( + callback_url, + fid.into(), + OnStartEvent, + ); + } + } + EventType::OnStop => { + if let Some(callback_url) = play_endpoint.on_stop() + { + self.callbacks.send_callback( + callback_url, + fid.into(), + OnStopEvent, + ); + } + } + } + } + Endpoint::WebRtcPublishEndpoint(publish_endpoint) => { + // TODO + } + } + } + debug!("LOOK AT ME: {:?}", msg); } } From 1d7e47a6cf7db70beda8c991dc71d8d6bdbb838c Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Thu, 27 Feb 2020 19:17:57 +0300 Subject: [PATCH 059/224] Implement on_start/on_stop for WebRtcPublishEndpoint --- _dev/specs/relay-pub-pub-video-call.yml | 8 +++- src/api/control/callback/clients/grpc.rs | 12 +++-- .../endpoints/webrtc/publish_endpoint.rs | 48 +++++++++++++++++++ src/signalling/elements/member.rs | 4 ++ src/signalling/room.rs | 40 +++++++++++++++- 5 files changed, 105 insertions(+), 7 deletions(-) diff --git a/_dev/specs/relay-pub-pub-video-call.yml b/_dev/specs/relay-pub-pub-video-call.yml index 3fc5ed579..31d2c26e2 100644 --- a/_dev/specs/relay-pub-pub-video-call.yml +++ b/_dev/specs/relay-pub-pub-video-call.yml @@ -14,12 +14,14 @@ spec: spec: p2p: Always force_relay: true + on_start: "grpc://127.0.0.1:9099" + on_stop: "grpc://127.0.0.1:9099" play-responder: kind: WebRtcPlayEndpoint spec: src: "local://relay-pub-pub-video-call/responder/publish" force_relay: true - on_play: "grpc://127.0.0.1:9099" + on_start: "grpc://127.0.0.1:9099" on_stop: "grpc://127.0.0.1:9099" responder: kind: Member @@ -33,10 +35,12 @@ spec: spec: p2p: Always force_relay: true + on_start: "grpc://127.0.0.1:9099" + on_stop: "grpc://127.0.0.1:9099" play-caller: kind: WebRtcPlayEndpoint spec: src: "local://relay-pub-pub-video-call/caller/publish" force_relay: true - on_play: "grpc://127.0.0.1:9099" + on_start: "grpc://127.0.0.1:9099" on_stop: "grpc://127.0.0.1:9099" diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index 6bdcb5ea8..c7f4e86b6 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -9,10 +9,13 @@ use medea_control_api_proto::grpc::callback::{ use futures::future::{FutureExt, LocalBoxFuture}; use tonic::transport::Channel; -use crate::api::control::callback::{ - clients::{CallbackClient, CallbackClientError}, - url::GrpcCallbackUrl, - CallbackRequest, +use crate::{ + api::control::callback::{ + clients::{CallbackClient, CallbackClientError}, + url::GrpcCallbackUrl, + CallbackRequest, + }, + log::prelude::*, }; /// gRPC client for sending [`CallbackRequest`]s. @@ -40,6 +43,7 @@ impl CallbackClient for GrpcCallbackClient { &self, request: CallbackRequest, ) -> LocalBoxFuture<'static, Result<(), CallbackClientError>> { + debug!("Sending {:?} gRPC callback.", request); let mut client = self.client.clone(); Box::pin(async move { client.on_event(tonic::Request::new(request.into())).await?; diff --git a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs index d76e64405..9fdf95de1 100644 --- a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs @@ -20,6 +20,8 @@ use crate::{ }; use super::play_endpoint::WebRtcPlayEndpoint; +use crate::{api::control::callback::url::CallbackUrl, media::Peer}; +use std::collections::HashMap; #[derive(Clone, Debug)] struct WebRtcPublishEndpointInner { @@ -45,6 +47,12 @@ struct WebRtcPublishEndpointInner { /// while removing [`WebRtcPublishEndpoint`] for removing all [`Peer`]s of /// this [`WebRtcPublishEndpoint`]. peer_ids: HashSet, + + peers_status: HashMap, + + on_start: Option, + + on_stop: Option, } impl Drop for WebRtcPublishEndpointInner { @@ -115,6 +123,8 @@ impl WebRtcPublishEndpoint { p2p: P2pMode, owner: WeakMember, is_force_relayed: bool, + on_start: Option, + on_stop: Option, ) -> Self { Self(Rc::new(RefCell::new(WebRtcPublishEndpointInner { id, @@ -123,6 +133,9 @@ impl WebRtcPublishEndpoint { sinks: Vec::new(), owner, peer_ids: HashSet::new(), + peers_status: HashMap::new(), + on_start, + on_stop, }))) } @@ -152,6 +165,7 @@ impl WebRtcPublishEndpoint { /// Adds [`PeerId`] of this [`WebRtcPublishEndpoint`]. pub fn add_peer_id(&self, peer_id: PeerId) { + self.0.borrow_mut().peers_status.insert(peer_id, false); self.0.borrow_mut().add_peer_id(peer_id) } @@ -203,6 +217,40 @@ impl WebRtcPublishEndpoint { self.0.borrow().is_force_relayed } + pub fn change_peer_status(&self, peer_id: PeerId, is_publishing: bool) { + if let Some(peer_status) = + self.0.borrow_mut().peers_status.get_mut(&peer_id) + { + *peer_status = is_publishing; + } + } + + pub fn is_endpoint_publishing(&self) -> bool { + self.0 + .borrow() + .peers_status + .values() + .find(|status| **status == true) + .is_some() + } + + pub fn publishing_peers_count(&self) -> usize { + self.0 + .borrow() + .peers_status + .values() + .filter(|s| **s) + .count() + } + + pub fn on_start(&self) -> Option { + self.0.borrow().on_start.clone() + } + + pub fn on_stop(&self) -> Option { + self.0.borrow().on_stop.clone() + } + /// Downgrades [`WebRtcPublishEndpoint`] to weak pointer /// [`WeakWebRtcPublishEndpoint`]. pub fn downgrade(&self) -> WeakWebRtcPublishEndpoint { diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index d1a568e20..8cc75bf85 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -201,6 +201,8 @@ impl Member { publisher_endpoint.p2p, publisher_member.downgrade(), publisher_endpoint.force_relay, + publisher_endpoint.on_start.clone(), + publisher_endpoint.on_stop.clone(), ); let new_self_play = WebRtcPlayEndpoint::new( @@ -232,6 +234,8 @@ impl Member { e.p2p, this_member.downgrade(), e.force_relay, + e.on_start.clone(), + e.on_stop.clone(), )); }); diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 69534129c..b734ca581 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -599,6 +599,8 @@ impl Room { spec.p2p, member.downgrade(), spec.force_relay, + spec.on_start.clone(), + spec.on_stop.clone(), ); debug!( @@ -720,6 +722,8 @@ impl Room { publish.p2p, signalling_member.downgrade(), publish.force_relay, + publish.on_start.clone(), + publish.on_stop.clone(), ); signalling_member.insert_src(signalling_publish); } @@ -1378,7 +1382,41 @@ impl Handler for Room { } } Endpoint::WebRtcPublishEndpoint(publish_endpoint) => { - // TODO + // TODO: I'm redudant in some if cases!!! + let fid = publish_endpoint + .owner() + .get_fid_to_endpoint(publish_endpoint.id().into()); + match msg.event { + EventType::OnStart => { + publish_endpoint + .change_peer_status(msg.peer_id, true); + if let Some(on_start) = publish_endpoint.on_start() + { + if publish_endpoint.publishing_peers_count() + == 1 + { + self.callbacks.send_callback( + on_start, + fid.into(), + OnStartEvent, + ); + } + } + } + EventType::OnStop => { + publish_endpoint + .change_peer_status(msg.peer_id, true); + if let Some(on_stop) = publish_endpoint.on_stop() { + if !publish_endpoint.is_endpoint_publishing() { + self.callbacks.send_callback( + on_stop, + fid.into(), + OnStopEvent, + ); + } + } + } + } } } } From 923155d732b0b0a74b20f4945481a1ca389f374f Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Fri, 28 Feb 2020 14:35:19 +0300 Subject: [PATCH 060/224] Fmt, warns, lints, fix bug --- crates/medea-coturn-telnet/src/lib.rs | 4 +- .../src/sessions_parser.rs | 2 +- mock/control-api/src/callback/mod.rs | 16 +- src/api/control/callback/clients/grpc.rs | 2 +- src/api/control/callback/mod.rs | 16 +- src/api/control/callback/service.rs | 2 +- .../control/endpoints/webrtc_play_endpoint.rs | 2 - .../endpoints/webrtc_publish_endpoint.rs | 2 - src/api/control/member.rs | 8 +- src/lib.rs | 2 + src/main.rs | 3 +- src/media/ice_user.rs | 2 +- .../endpoints/webrtc/publish_endpoint.rs | 16 +- src/signalling/elements/member.rs | 9 +- src/signalling/participants.rs | 11 +- src/signalling/peers.rs | 27 ++- src/signalling/room.rs | 24 ++- src/turn/coturn_stats.rs | 188 +++++++----------- src/turn/service.rs | 10 +- 19 files changed, 154 insertions(+), 192 deletions(-) diff --git a/crates/medea-coturn-telnet/src/lib.rs b/crates/medea-coturn-telnet/src/lib.rs index 691e198c5..ffbf8bcd2 100644 --- a/crates/medea-coturn-telnet/src/lib.rs +++ b/crates/medea-coturn-telnet/src/lib.rs @@ -4,7 +4,9 @@ //! //! [Coturn]: https://github.com/coturn/coturn //! [deadpool]: https://crates.io/crates/deadpool -#![allow(clippy::module_name_repetitions)] +#![allow(clippy::module_name_repetitions, clippy::must_use_candidate)] +// TODO: remove me +#![allow(clippy::missing_errors_doc)] pub mod codec; pub mod connection; diff --git a/crates/medea-coturn-telnet/src/sessions_parser.rs b/crates/medea-coturn-telnet/src/sessions_parser.rs index 3fd213b4d..02f2d60b7 100644 --- a/crates/medea-coturn-telnet/src/sessions_parser.rs +++ b/crates/medea-coturn-telnet/src/sessions_parser.rs @@ -40,7 +40,7 @@ impl fmt::Display for Protocol { } } -const TURN_SESSION_ID_FACTOR: u64 = 1000000000000000; +const TURN_SESSION_ID_FACTOR: u64 = 1_000_000_000_000_000; #[derive(Clone, Copy, Debug)] pub struct SessionId(pub u64); diff --git a/mock/control-api/src/callback/mod.rs b/mock/control-api/src/callback/mod.rs index 56c9d5f6e..1dc762b6e 100644 --- a/mock/control-api/src/callback/mod.rs +++ b/mock/control-api/src/callback/mod.rs @@ -9,26 +9,26 @@ use serde::Serialize; #[derive(Clone, Serialize)] #[serde(tag = "type")] pub enum CallbackEvent { - OnJoin(join::OnJoin), - OnLeave(leave::OnLeave), - OnStart(on_start::OnStart), - OnStop(on_stop::OnStop), + Join(join::OnJoin), + Leave(leave::OnLeave), + Start(on_start::OnStart), + Stop(on_stop::OnStop), } impl From for CallbackEvent { fn from(proto: proto::request::Event) -> Self { match proto { proto::request::Event::OnLeave(on_leave) => { - Self::OnLeave(on_leave.into()) + Self::Leave(on_leave.into()) } proto::request::Event::OnJoin(on_join) => { - Self::OnJoin(on_join.into()) + Self::Join(on_join.into()) } proto::request::Event::OnStart(on_start) => { - Self::OnStart(on_start.into()) + Self::Start(on_start.into()) } proto::request::Event::OnStop(on_stop) => { - Self::OnStop(on_stop.into()) + Self::Stop(on_stop.into()) } } } diff --git a/src/api/control/callback/clients/grpc.rs b/src/api/control/callback/clients/grpc.rs index c7f4e86b6..8906edaf0 100644 --- a/src/api/control/callback/clients/grpc.rs +++ b/src/api/control/callback/clients/grpc.rs @@ -6,7 +6,7 @@ use std::fmt; use medea_control_api_proto::grpc::callback::{ callback_client::CallbackClient as ProtoCallbackClient }; -use futures::future::{FutureExt, LocalBoxFuture}; +use futures::future::LocalBoxFuture; use tonic::transport::Channel; use crate::{ diff --git a/src/api/control/callback/mod.rs b/src/api/control/callback/mod.rs index d624faf1d..a898314dc 100644 --- a/src/api/control/callback/mod.rs +++ b/src/api/control/callback/mod.rs @@ -89,25 +89,25 @@ impl Into for OnStopEvent { /// All callbacks which can happen. #[derive(Debug, From)] pub enum CallbackEvent { - OnJoin(OnJoinEvent), - OnLeave(OnLeaveEvent), - OnStart(OnStartEvent), - OnStop(OnStopEvent), + Join(OnJoinEvent), + Leave(OnLeaveEvent), + Start(OnStartEvent), + Stop(OnStopEvent), } impl Into for CallbackEvent { fn into(self) -> proto::request::Event { match self { - Self::OnJoin(on_join) => { + Self::Join(on_join) => { proto::request::Event::OnJoin(on_join.into()) } - Self::OnLeave(on_leave) => { + Self::Leave(on_leave) => { proto::request::Event::OnLeave(on_leave.into()) } - Self::OnStart(on_start) => { + Self::Start(on_start) => { proto::request::Event::OnStart(on_start.into()) } - Self::OnStop(on_stop) => { + Self::Stop(on_stop) => { proto::request::Event::OnStop(on_stop.into()) } } diff --git a/src/api/control/callback/service.rs b/src/api/control/callback/service.rs index 54d4af367..adaba6f34 100644 --- a/src/api/control/callback/service.rs +++ b/src/api/control/callback/service.rs @@ -120,7 +120,7 @@ mod tests { fn callback_request() -> CallbackRequest { CallbackRequest::new( StatefulFid::try_from("foo".to_string()).unwrap(), - CallbackEvent::OnJoin(OnJoinEvent), + CallbackEvent::Join(OnJoinEvent), ) } diff --git a/src/api/control/endpoints/webrtc_play_endpoint.rs b/src/api/control/endpoints/webrtc_play_endpoint.rs index 00a6e591b..919bd1277 100644 --- a/src/api/control/endpoints/webrtc_play_endpoint.rs +++ b/src/api/control/endpoints/webrtc_play_endpoint.rs @@ -12,7 +12,6 @@ use serde::Deserialize; use crate::api::control::{ callback::url::CallbackUrl, refs::SrcUri, TryFromProtobufError, }; -use std::marker::PhantomData; /// ID of [`WebRtcPlayEndpoint`]. #[derive( @@ -46,7 +45,6 @@ pub struct WebRtcPlayEndpoint { pub force_relay: bool, #[serde(skip)] - #[serde(bound = "T: From + Default")] _validation_state: T, } diff --git a/src/api/control/endpoints/webrtc_publish_endpoint.rs b/src/api/control/endpoints/webrtc_publish_endpoint.rs index 9511a09be..074da934a 100644 --- a/src/api/control/endpoints/webrtc_publish_endpoint.rs +++ b/src/api/control/endpoints/webrtc_publish_endpoint.rs @@ -10,7 +10,6 @@ use crate::api::control::{ endpoints::webrtc_play_endpoint::{ Unvalidated, Validated, ValidationError, }, - member::MemberElement::WebRtcPlayEndpoint, TryFromProtobufError, }; use medea_control_api_proto::grpc::api as proto; @@ -73,7 +72,6 @@ pub struct WebRtcPublishEndpoint { pub on_stop: Option, #[serde(skip)] - #[serde(bound = "T: From + Default")] _validation_state: T, } diff --git a/src/api/control/member.rs b/src/api/control/member.rs index 491b43133..08c97349f 100644 --- a/src/api/control/member.rs +++ b/src/api/control/member.rs @@ -46,7 +46,7 @@ pub enum MemberElement { /// Can transform into [`EndpointSpec`] enum by `EndpointSpec::try_from`. /// /// [`EndpointSpec`]: crate::api::control::endpoints::EndpointSpec - #[serde(bound = "T: From + Default")] + #[serde(bound = "T: From")] WebRtcPlayEndpoint { spec: WebRtcPlayEndpoint }, } @@ -94,6 +94,9 @@ impl Into> for MemberSpec { } } +type PublishEndpointsItem<'a> = + (WebRtcPublishId, &'a WebRtcPublishEndpoint); + impl MemberSpec { /// Returns all [`WebRtcPlayEndpoint`]s of this [`MemberSpec`]. pub fn play_endpoints( @@ -124,8 +127,7 @@ impl MemberSpec { /// Returns all [`WebRtcPublishEndpoint`]s of this [`MemberSpec`]. pub fn publish_endpoints( &self, - ) -> impl Iterator)> - { + ) -> impl Iterator { self.pipeline.iter().filter_map(|(id, e)| match e { MemberElement::WebRtcPublishEndpoint { spec } => { Some((id.clone().into(), spec)) diff --git a/src/lib.rs b/src/lib.rs index c1dc9056a..78eaca596 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,8 @@ // TODO: Remove `clippy::must_use_candidate` once the issue below is resolved: // https://github.com/rust-lang/rust-clippy/issues/4779 #![allow(clippy::module_name_repetitions, clippy::must_use_candidate)] +// TODO: remove me +#![allow(clippy::missing_errors_doc)] #[macro_use] pub mod utils; diff --git a/src/main.rs b/src/main.rs index e373025b5..0c950f7ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,8 +12,7 @@ use medea::{ shutdown::{self, GracefulShutdown}, signalling::{room_repo::RoomRepository, room_service::RoomService}, turn::{ - cli::CoturnTelnetClient, - coturn_stats::{run_coturn_stats_watcher, CoturnStats}, + cli::CoturnTelnetClient, coturn_stats::CoturnStats, new_turn_auth_service, }, AppContext, diff --git a/src/media/ice_user.rs b/src/media/ice_user.rs index 20d28ce49..577399fa1 100644 --- a/src/media/ice_user.rs +++ b/src/media/ice_user.rs @@ -5,7 +5,7 @@ use derive_more::{AsRef, Display, From, Into}; use medea_client_api_proto::{IceServer, PeerId}; -use crate::api::control::{EndpointId, RoomId}; +use crate::api::control::RoomId; /// Username for authorization on Turn server. #[derive(AsRef, Clone, Debug, Display, From, Into)] diff --git a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs index 9fdf95de1..6ed2d44b7 100644 --- a/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs +++ b/src/signalling/elements/endpoints/webrtc/publish_endpoint.rs @@ -2,7 +2,7 @@ use std::{ cell::RefCell, - collections::HashSet, + collections::{HashMap, HashSet}, rc::{Rc, Weak}, }; @@ -10,8 +10,9 @@ use medea_client_api_proto::PeerId; use medea_control_api_proto::grpc::api as proto; use crate::{ - api::control::endpoints::webrtc_publish_endpoint::{ - P2pMode, WebRtcPublishId as Id, + api::control::{ + callback::url::CallbackUrl, + endpoints::webrtc_publish_endpoint::{P2pMode, WebRtcPublishId as Id}, }, signalling::elements::{ endpoints::webrtc::play_endpoint::WeakWebRtcPlayEndpoint, @@ -20,8 +21,6 @@ use crate::{ }; use super::play_endpoint::WebRtcPlayEndpoint; -use crate::{api::control::callback::url::CallbackUrl, media::Peer}; -use std::collections::HashMap; #[derive(Clone, Debug)] struct WebRtcPublishEndpointInner { @@ -226,12 +225,7 @@ impl WebRtcPublishEndpoint { } pub fn is_endpoint_publishing(&self) -> bool { - self.0 - .borrow() - .peers_status - .values() - .find(|status| **status == true) - .is_some() + self.0.borrow().peers_status.values().any(|status| *status) } pub fn publishing_peers_count(&self) -> usize { diff --git a/src/signalling/elements/member.rs b/src/signalling/elements/member.rs index 8cc75bf85..89c753b49 100644 --- a/src/signalling/elements/member.rs +++ b/src/signalling/elements/member.rs @@ -11,26 +11,27 @@ use std::{ use derive_more::Display; use failure::Fail; -use medea_client_api_proto::{IceServer, PeerId}; +use medea_client_api_proto::PeerId; use medea_control_api_proto::grpc::api as proto; use crate::{ api::control::{ callback::url::CallbackUrl, - endpoints::WebRtcPlayEndpoint as WebRtcPlayEndpointSpec, + endpoints::{ + webrtc_play_endpoint::Validated, + WebRtcPlayEndpoint as WebRtcPlayEndpointSpec, + }, refs::{Fid, StatefulFid, ToEndpoint, ToMember, ToRoom}, EndpointId, MemberId, MemberSpec, RoomId, RoomSpec, TryFromElementError, WebRtcPlayId, WebRtcPublishId, }, log::prelude::*, - media::IceUser, }; use super::endpoints::{ webrtc::{WebRtcPlayEndpoint, WebRtcPublishEndpoint}, Endpoint, }; -use crate::api::control::endpoints::webrtc_play_endpoint::Validated; /// Errors which may occur while loading [`Member`]s from [`RoomSpec`]. #[derive(Debug, Display, Fail)] diff --git a/src/signalling/participants.rs b/src/signalling/participants.rs index 937eb66d2..19c2532d7 100644 --- a/src/signalling/participants.rs +++ b/src/signalling/participants.rs @@ -14,8 +14,8 @@ use std::{ }; use actix::{ - fut::wrap_future, ActorFuture as _, AsyncContext, Context, - ContextFutureSpawner as _, SpawnHandle, WrapFuture, + fut::wrap_future, AsyncContext, Context, ContextFutureSpawner as _, + SpawnHandle, }; use derive_more::Display; use failure::Fail; @@ -43,7 +43,7 @@ use crate::{ room::{ActFuture, RoomError}, Room, }, - turn::{TurnAuthService, TurnServiceErr, UnreachablePolicy}, + turn::{TurnAuthService, TurnServiceErr}, AppContext, }; @@ -251,9 +251,8 @@ impl ParticipantService { .map(move |_| Ok(member)), )) } else { - let turn_service = self.turn_service.clone(); - let cloned_member_id = member_id.clone(); - let room_id = self.room_id.clone(); + // TODO: here was turn_service user creating. Maybe it needed + // here??? self.insert_connection(member_id, conn); Box::new(wrap_future(future::ok(member))) } diff --git a/src/signalling/peers.rs b/src/signalling/peers.rs index 2ff58fb1d..73c016af5 100644 --- a/src/signalling/peers.rs +++ b/src/signalling/peers.rs @@ -4,15 +4,19 @@ //! [`Peer`]: crate::media::peer::Peer use std::{ + cell::RefCell, collections::{HashMap, HashSet}, convert::{TryFrom, TryInto}, + future::Future, + rc::Rc, + sync::Arc, }; use derive_more::Display; use medea_client_api_proto::{Incrementable, PeerId, TrackId}; use crate::{ - api::control::{EndpointId, MemberId, RoomId}, + api::control::{MemberId, RoomId}, log::prelude::*, media::{IceUser, New, Peer, PeerStateMachine}, signalling::{ @@ -24,7 +28,6 @@ use crate::{ }, turn::{TurnAuthService, UnreachablePolicy}, }; -use std::{cell::RefCell, future::Future, rc::Rc, sync::Arc}; #[derive(Debug)] pub struct PeerRepository { @@ -51,7 +54,7 @@ pub struct PeerRepository { /// [`Room`]: crate::signalling::room::Room tracks_count: Counter, - peers_endpoints: HashMap, + peers_endpoints: HashMap>, } /// Simple ID counter. @@ -372,10 +375,14 @@ impl PeerRepository { src.add_peer_id(src_peer_id); self.peers_endpoints - .insert(src_peer_id, src.downgrade().into()); + .entry(src_peer_id) + .or_default() + .push(src.downgrade().into()); sink.set_peer_id(sink_peer_id); self.peers_endpoints - .insert(sink_peer_id, sink.downgrade().into()); + .entry(sink_peer_id) + .or_default() + .push(sink.downgrade().into()); self.add_peer(src_peer); self.add_peer(sink_peer); @@ -386,10 +393,14 @@ impl PeerRepository { src.add_peer_id(src_peer.id()); self.peers_endpoints - .insert(src_peer.id(), src.downgrade().into()); + .entry(src_peer.id()) + .or_default() + .push(src.downgrade().into()); sink.set_peer_id(sink_peer.id()); self.peers_endpoints - .insert(sink_peer.id(), sink.downgrade().into()); + .entry(sink_peer.id()) + .or_default() + .push(sink.downgrade().into()); let src_peer_id = src_peer.id(); let sink_peer_id = sink_peer.id(); @@ -406,7 +417,7 @@ impl PeerRepository { pub fn get_endpoint_path_by_peer_id( &self, peer_id: PeerId, - ) -> Option { + ) -> Option> { self.peers_endpoints.get(&peer_id).cloned() } } diff --git a/src/signalling/room.rs b/src/signalling/room.rs index b734ca581..e6be7b4bb 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -7,7 +7,7 @@ use std::collections::{HashMap, HashSet}; use actix::{ Actor, ActorFuture, Addr, AsyncContext, Context, ContextFutureSpawner as _, - Handler, Message, WrapFuture as _, WrapFuture, + Handler, Message, WrapFuture as _, }; use derive_more::Display; use failure::Fail; @@ -60,7 +60,8 @@ use crate::{ utils::ResponseActAnyFuture, AppContext, }; -use futures::TryFutureExt; + +use super::elements::endpoints::Endpoint; /// Ergonomic type alias for using [`ActorFuture`] for [`Room`]. pub type ActFuture = Box>; @@ -251,7 +252,7 @@ impl Room { let fut = self.peers.get_ice_user(sender_peer_id); Ok(Box::new(fut.into_actor(self).then( - move |ice_user, this, ctx| { + move |ice_user, this, _| { let sender = this.peers.get_peer_by_id(sender_peer_id).unwrap(); let peer_created = Event::PeerCreated { peer_id: sender.id(), @@ -851,7 +852,7 @@ impl CommandHandler for Room { let fut = self.peers.get_ice_user(to_peer_id); Ok(Box::new(fut.into_actor(self).then( - move |ice_user, this, ctx| { + move |ice_user, this, _| { let to_peer = this.peers.get_peer_by_id(to_peer_id).unwrap(); let event = Event::PeerCreated { peer_id: to_peer.id(), @@ -1344,15 +1345,18 @@ impl Handler for Room { fn handle( &mut self, msg: OnStartOnStopCallback, - ctx: &mut Self::Context, + _: &mut Self::Context, ) -> Self::Result { - let endpoint = self + let endpoints: Vec<_> = self .peers .get_endpoint_path_by_peer_id(msg.peer_id) - .and_then(|endpoint| endpoint.upgrade()); + .into_iter() + .flat_map(|endpoints| { + endpoints.into_iter().filter_map(|e| e.upgrade()) + }) + .collect(); - use super::elements::endpoints::Endpoint; - if let Some(endpoint) = endpoint { + for endpoint in endpoints { match endpoint { Endpoint::WebRtcPlayEndpoint(play_endpoint) => { let fid = play_endpoint @@ -1405,7 +1409,7 @@ impl Handler for Room { } EventType::OnStop => { publish_endpoint - .change_peer_status(msg.peer_id, true); + .change_peer_status(msg.peer_id, false); if let Some(on_stop) = publish_endpoint.on_stop() { if !publish_endpoint.is_endpoint_publishing() { self.callbacks.send_callback( diff --git a/src/turn/coturn_stats.rs b/src/turn/coturn_stats.rs index e746f6a54..66cd6ede1 100644 --- a/src/turn/coturn_stats.rs +++ b/src/turn/coturn_stats.rs @@ -1,27 +1,27 @@ -use std::{fmt, sync::Arc}; +use std::{ + cell::RefCell, + collections::{HashMap, HashSet}, + rc::Rc, + time::{Duration, Instant}, +}; -use actix::Message; -use async_trait::async_trait; -use derive_more::{Display, From}; -use failure::Fail; -use rand::{distributions::Alphanumeric, Rng}; +use actix::{ + Actor, ActorFuture, Addr, AsyncContext, Handler, Message, StreamHandler, + WrapFuture, +}; +use derive_more::Display; +use futures::{channel::mpsc, StreamExt}; +use medea_client_api_proto::PeerId; +use medea_coturn_telnet::sessions_parser::Session; +use patched_redis::ConnectionInfo; use crate::{ - api::control::{EndpointId, MemberId, RoomId}, + api::control::RoomId, conf, log::prelude::*, - media::IceUser, - turn::repo::{TurnDatabase, TurnDatabaseErr}, -}; -use actix::{ - Actor, ActorFuture, Addr, AsyncContext, Handler, SpawnHandle, - StreamHandler, WrapFuture, + signalling::{room::OnStartOnStopCallback, Room}, + turn::cli::{CoturnCliError, CoturnTelnetClient}, }; -use futures::channel::mpsc; -use medea_client_api_proto::PeerId; -use medea_coturn_telnet::sessions_parser::{Session, TrafficUsage}; -use patched_redis::{ConnectionInfo, IntoConnectionInfo}; -use std::{collections::HashMap, time::Duration}; #[derive(Clone, Debug, Copy)] pub struct Traffic { @@ -32,25 +32,27 @@ pub struct Traffic { } impl Traffic { - pub fn parse(body: String) -> Result { + pub fn parse(body: &str) -> Result { let mut items: HashMap<&str, u64> = body .split(", ") .map(|i| { let mut splitted_item = i.split('='); let key = splitted_item.next().ok_or_else(|| { - CoturnEventParseError::FailedToParseTrafficMap(body.clone()) + CoturnEventParseError::FailedToParseTrafficMap( + body.to_string(), + ) })?; let value: u64 = splitted_item .next() .ok_or_else(|| { CoturnEventParseError::FailedToParseTrafficMap( - body.clone(), + body.to_string(), ) })? .parse() .map_err(|_| { CoturnEventParseError::FailedToParseTrafficMap( - body.clone(), + body.to_string(), ) })?; @@ -100,7 +102,7 @@ pub enum CoturnAllocationEvent { impl CoturnAllocationEvent { pub fn parse( event_type: &str, - body: String, + body: &str, ) -> Result { match event_type { "total_traffic" => Ok(CoturnAllocationEvent::TotalTraffic { @@ -164,7 +166,7 @@ pub struct CoturnEvent { impl CoturnEvent { pub fn parse( - msg: patched_redis::Msg, + msg: &patched_redis::Msg, ) -> Result { let channel: String = msg .get_channel() @@ -206,7 +208,7 @@ impl CoturnEvent { let event = CoturnAllocationEvent::parse( event_type, - msg.get_payload().unwrap(), + msg.get_payload::().unwrap().as_str(), )?; Ok(CoturnEvent { @@ -275,26 +277,7 @@ pub enum CoturnEventParseError { NoEventType, } -pub struct CoturnStatsWatcher { - client: redis::Client, -} - -use crate::{ - media::peer::Context, - signalling::{room::OnStartOnStopCallback, Room}, - turn::{ - cli::{CoturnCliError, CoturnTelnetClient}, - coturn_stats::EventType::OnStart, - }, -}; -use actix_web::web::patch; -use futures::{StreamExt, TryFutureExt}; -use patched_redis::Client as RedisClient; -use redis::Msg; -use std::{ - cell::RefCell, collections::HashSet, rc::Rc, thread::JoinHandle, - time::Instant, -}; +pub struct CoturnStatsWatcher; pub async fn coturn_watcher_loop( client: patched_redis::Client, @@ -305,7 +288,7 @@ pub async fn coturn_watcher_loop( let mut pubsub_stream = pusub.on_message(); while let Some(msg) = pubsub_stream.next().await { - match CoturnEvent::parse(msg) { + match CoturnEvent::parse(&msg) { Ok(event) => { debug!("Coturn stats: {:?}", event); } @@ -425,7 +408,6 @@ type Alloc = Rc>; pub struct CoturnStats { allocations: HashMap)>, client: patched_redis::Client, - // TODO: PeerId -> CoturnUsername awaits_allocation: HashMap, coturn_client: CoturnTelnetClient, relay_allocations_ids: HashMap, @@ -538,18 +520,18 @@ impl Actor for CoturnStats { .into_actor(self), ); - ctx.run_interval(Duration::from_millis(500), |this, ctx| { - for (id, (allocation, partner_allocation)) in &this.allocations { + ctx.run_interval(Duration::from_millis(500), |this, _| { + // TODO: use partner allocation + for (allocation, _partner_allocation) in this.allocations.values() { let last_update = allocation.borrow().last_update; let allocation_state = allocation.borrow().state; if last_update + Duration::from_secs(3) < Instant::now() { if allocation_state == PublisherAllocationState::Playing { allocation.borrow_mut().on_stop(); } - } else { - if allocation_state == PublisherAllocationState::Stopped { - allocation.borrow_mut().on_start(); - } + } else if allocation_state == PublisherAllocationState::Stopped + { + allocation.borrow_mut().on_start(); } } }); @@ -560,7 +542,7 @@ impl Actor for CoturnStats { fn find_relay_session(sessions: Vec) -> Option { for session in sessions { - if session.peers.len() > 0 { + if !session.peers.is_empty() { return Some(session); } } @@ -575,7 +557,7 @@ impl StreamHandler> for CoturnStats { ctx: &mut Self::Context, ) { if let Some(msg) = item { - let event = if let Ok(event) = CoturnEvent::parse(msg) { + let event = if let Ok(event) = CoturnEvent::parse(&msg) { event } else { return; @@ -583,18 +565,26 @@ impl StreamHandler> for CoturnStats { let peer_id = event.peer_id; match event.event { - CoturnAllocationEvent::New { lifetime: _ } => { - if let Some(subscription_request) = + CoturnAllocationEvent::Traffic { traffic } => { + if let Some((allocation, partner_allocation)) = + self.allocations.get(&event.allocation_id) + { + allocation.borrow_mut().update_traffic(traffic); + if let Some(partner_allocation) = partner_allocation { + partner_allocation + .borrow_mut() + .update_received_bytes(traffic.sent_bytes); + partner_allocation + .borrow_mut() + .update_send_bytes(traffic.received_bytes); + } + } else if let Some(subscription_request) = self.awaits_allocation.get(&event.peer_id) { let coturn_client = self.coturn_client.clone(); let room_id = subscription_request.room_id.clone(); ctx.spawn( async move { - tokio::time::delay_for(Duration::from_millis( - 500, - )) - .await; let sess = format!( "{}_{}", room_id, @@ -604,67 +594,29 @@ impl StreamHandler> for CoturnStats { } .into_actor(self) .map( - move |res, this, ctx| match res { + move |res, this, _| match res { Ok(sessions) => { - this.try_init_allocation( - sessions, peer_id, - ); + if let Err(e) = this + .try_init_allocation( + sessions, peer_id, + ) + { + error!( + "Allocation init error: {:?}", + e + ); + }; } Err(e) => { - println!("\n\n{:?}\n\n", e); + error!("Coturn CLI error: {:?}", e); } }, ), ); } } - CoturnAllocationEvent::Traffic { traffic } => { - if let Some((allocation, partner_allocation)) = - self.allocations.get(&event.allocation_id) - { - allocation.borrow_mut().update_traffic(traffic); - if let Some(partner_allocation) = partner_allocation { - partner_allocation - .borrow_mut() - .update_received_bytes(traffic.sent_bytes); - partner_allocation - .borrow_mut() - .update_send_bytes(traffic.received_bytes); - } - } else { - if let Some(subscription_request) = - self.awaits_allocation.get(&event.peer_id) - { - let coturn_client = self.coturn_client.clone(); - let room_id = subscription_request.room_id.clone(); - ctx.spawn( - async move { - let sess = format!( - "{}_{}", - room_id, - event.peer_id.to_string() - ); - coturn_client.get_sessions(sess).await - } - .into_actor(self) - .map( - move |res, this, ctx| match res { - Ok(sessions) => { - this.try_init_allocation( - sessions, peer_id, - ); - } - Err(e) => { - println!("\n\n{:?}\n\n", e); - } - }, - ), - ); - } - } - } CoturnAllocationEvent::Deleted => { - if let Some((allocation, partner_allocation)) = + if let Some((_, partner_allocation)) = self.allocations.remove(&event.allocation_id) { if let Some(partner_allocation) = partner_allocation { @@ -701,7 +653,7 @@ impl Handler for CoturnStats { fn handle( &mut self, msg: Subscribe, - ctx: &mut Self::Context, + _: &mut Self::Context, ) -> Self::Result { let coturn_client = self.coturn_client.clone(); let peer_id = msg.peer_id; @@ -710,13 +662,17 @@ impl Handler for CoturnStats { Box::new( async move { coturn_client.get_sessions(session_id).await } .into_actor(self) - .map(move |res, this, ctx| { + .map(move |res, this, _| { match res { Ok(sessions) => { - this.try_init_allocation(sessions, peer_id); + if let Err(e) = + this.try_init_allocation(sessions, peer_id) + { + error!("Allocation init failed: {:?}", e); + }; } Err(e) => { - println!("\n\n{:?}\n\n", e); + error!("Get Coturn sessions failed: {:?}", e); } } diff --git a/src/turn/service.rs b/src/turn/service.rs index 009ff302f..ec6d2e32b 100644 --- a/src/turn/service.rs +++ b/src/turn/service.rs @@ -8,23 +8,19 @@ use std::{fmt, sync::Arc}; use async_trait::async_trait; use derive_more::{Display, From}; use failure::Fail; +use medea_client_api_proto::PeerId; use rand::{distributions::Alphanumeric, Rng}; -use redis::{ConnectionInfo, IntoConnectionInfo, PubSub}; +use redis::ConnectionInfo; use crate::{ - api::control::{EndpointId, MemberId, RoomId}, + api::control::RoomId, conf, - log::prelude::*, media::IceUser, turn::{ cli::{CoturnCliError, CoturnTelnetClient}, repo::{TurnDatabase, TurnDatabaseErr}, }, }; -use actix::{Actor, AsyncContext, StreamHandler}; -use futures::channel::mpsc; -use medea_client_api_proto::PeerId; -use std::collections::HashMap; static TURN_PASS_LEN: usize = 16; From 31393584fddaedbb77db40bc0793c12f1776eb84 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 2 Mar 2020 14:06:59 +0300 Subject: [PATCH 061/224] Add binding SysTrackId with TrackId --- jason/src/peer/media/mod.rs | 99 +++++++++++++++++++++++++++++++------ jason/src/peer/stats/mod.rs | 4 +- 2 files changed, 86 insertions(+), 17 deletions(-) diff --git a/jason/src/peer/media/mod.rs b/jason/src/peer/media/mod.rs index f54ff172f..b5784f523 100644 --- a/jason/src/peer/media/mod.rs +++ b/jason/src/peer/media/mod.rs @@ -31,6 +31,7 @@ use super::{ }; pub use self::mute_state::{MuteState, MuteStateTransition, StableMuteState}; +use crate::utils::console_error; /// Errors that may occur in [`MediaConnections`] storage. #[derive(Debug, Display, JsCaused)] @@ -98,6 +99,39 @@ struct InnerMediaConnections { /// [`MediaTrack`] to its [`Receiver`]. receivers: HashMap, + + js_track_id_to_medea_track_id: JsTrackIdToMedeaTrackId, +} + +#[derive(Debug)] +struct JsTrackIdToMedeaTrackId { + senders: HashMap, + receivers: HashMap, +} + +impl JsTrackIdToMedeaTrackId { + pub fn new() -> Self { + Self { + senders: HashMap::new(), + receivers: HashMap::new(), + } + } + + pub fn insert_sender(&mut self, sys_id: String, id: TrackId) { + self.senders.insert(sys_id, id); + } + + pub fn insert_receiver(&mut self, sys_id: String, id: TrackId) { + self.receivers.insert(sys_id, id); + } + + pub fn get_sender(&self, sys_id: &str) -> Option { + self.senders.get(sys_id).copied() + } + + pub fn get_receiver(&self, sys_id: &str) -> Option { + self.receivers.get(sys_id).copied() + } } impl InnerMediaConnections { @@ -122,6 +156,7 @@ impl MediaConnections { peer, senders: HashMap::new(), receivers: HashMap::new(), + js_track_id_to_medea_track_id: JsTrackIdToMedeaTrackId::new(), })) } @@ -303,10 +338,12 @@ impl MediaConnections { // Build sender to track pairs to catch errors before inserting. let mut sender_and_track = Vec::with_capacity(s.senders.len()); + let mut tracks_ids = Vec::new(); for sender in s.senders.values() { if let Some(track) = stream.get_track_by_id(sender.track_id) { if sender.caps.satisfies(&track.track()) { - sender_and_track.push((sender, track)); + tracks_ids.push((track.track().id(), sender.track_id)); + sender_and_track.push((Rc::clone(&sender), track)); } else { return Err(tracerr::new!( MediaConnectionsError::InvalidMediaTrack @@ -318,11 +355,18 @@ impl MediaConnections { )); } } + drop(s); + + let mut s = self.0.borrow_mut(); + for (sys_id, track_id) in tracks_ids { + s.js_track_id_to_medea_track_id + .insert_sender(sys_id, track_id); + } future::try_join_all( sender_and_track .into_iter() - .map(|(s, t)| Sender::insert_and_enable_track(Rc::clone(s), t)), + .map(|(s, t)| Sender::insert_and_enable_track(s, t)), ) .await?; @@ -341,22 +385,47 @@ impl MediaConnections { ) -> Option { let mut s = self.0.borrow_mut(); if let Some(mid) = transceiver.mid() { - for receiver in &mut s.receivers.values_mut() { - if let Some(recv_mid) = &receiver.mid() { - if recv_mid == &mid { - let track = MediaTrack::new( - receiver.track_id, - track, - receiver.caps.clone(), - ); - receiver.transceiver.replace(transceiver); - receiver.track.replace(track); - return Some(receiver.sender_id); - } + let insert; + let sender_id; + + { + let receiver = s.receivers.values_mut().find(|recv| { + recv.mid + .as_ref() + .filter(|recv_mid| recv_mid == &&mid) + .is_some() + }); + if let Some(receiver) = receiver { + insert = Some((track.id(), receiver.track_id)); + + let track = MediaTrack::new( + receiver.track_id, + track, + receiver.caps.clone(), + ); + receiver.transceiver.replace(transceiver); + receiver.track.replace(track); + + sender_id = Some(receiver.sender_id) + } else { + sender_id = None; + insert = None; } } + if let Some((sys_track_id, track_id)) = insert { + s.js_track_id_to_medea_track_id + .insert_receiver(sys_track_id, track_id); + } + + console_error(format!( + "track_ids: {:?}", + s.js_track_id_to_medea_track_id + )); + + sender_id + } else { + None } - None } /// Returns [`MediaTrack`]s being received from a specified sender, diff --git a/jason/src/peer/stats/mod.rs b/jason/src/peer/stats/mod.rs index 2519c3c11..36facd69d 100644 --- a/jason/src/peer/stats/mod.rs +++ b/jason/src/peer/stats/mod.rs @@ -268,10 +268,10 @@ impl From<&str> for IceCandidatePairState { // https://www.w3.org/TR/webrtc-stats/#inboundrtpstats-dict* #[derive(Debug)] - struct RtcInboundRtpStreamStats { +struct RtcInboundRtpStreamStats { media_type: bool, bytes_received: u64, packets_received: u64, packets_lost: u64, - jitter: f64 + jitter: f64, } From c21c80e94164a120a174dc726c88119beb91ce47 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Mon, 2 Mar 2020 19:20:11 +0300 Subject: [PATCH 062/224] Add basic metrics --- jason/src/peer/stats/mod.rs | 227 ++++++++++++++++++++++++------------ 1 file changed, 152 insertions(+), 75 deletions(-) diff --git a/jason/src/peer/stats/mod.rs b/jason/src/peer/stats/mod.rs index 36facd69d..6fed09b26 100644 --- a/jason/src/peer/stats/mod.rs +++ b/jason/src/peer/stats/mod.rs @@ -14,10 +14,12 @@ use std::convert::TryFrom; +use serde::Deserialize; use wasm_bindgen::{prelude::*, JsCast}; use web_sys::RtcStats as SysRtcStats; -use crate::utils::get_property_by_name; +use crate::utils::{console_error, get_property_by_name}; +use futures::future::Remote; struct RtcStatsReportEntry(js_sys::JsString, SysRtcStats); @@ -87,12 +89,16 @@ impl From<&JsValue> for RtcStats { let stat = RtcStatsReportEntry::try_from(stat).unwrap(); let stat = RtcStatsType::try_from(&stat.1).unwrap(); + console_error(format!("Stat: {:?}", stat)); + match stat { RtcStatsType::CandidatePair(pair) => { - if pair.kind.nominated { + if pair.kind.nominated.unwrap_or_default() { ice_pairs.push(pair); } } + RtcStatsType::OutboundRtp(stat) => { + } RtcStatsType::Unknown(unknown_stat) => { // print error } @@ -112,8 +118,8 @@ impl From<&JsValue> for RtcStats { #[derive(Debug)] enum RtcStatsType { Codec, - InboundRtp, - OutboundRtp, + InboundRtp(RtcStat), + OutboundRtp(RtcStat), RemoteInboundRtp, RemoteOutboundRtp, MediaSoure, @@ -121,15 +127,15 @@ enum RtcStatsType { PeerConnection, DataChannel, Stream, - Track, + Track(RtcStat), Transceiver, Sender, Receiver, Transport, SctpTransport, CandidatePair(RtcStat), - LocalCandidate, - RemoteCandidate, + LocalCandidate(RtcStat), + RemoteCandidate(RtcStat), Certificate, IceServer, Unknown(String), @@ -152,16 +158,24 @@ impl TryFrom<&SysRtcStats> for RtcStatsType { let kind = match kind.as_ref() { "codec" => Codec, - "local-candidate" => LocalCandidate, - "remote-candidate" => RemoteCandidate, - "track" => Track, + "local-candidate" => LocalCandidate(RtcStat::new(id, timestamp, LocalCandidateStat::from(val))), + "remote-candidate" => RemoteCandidate(RtcStat::new(id, timestamp, RemoteCandidateStat::from(val))), + "track" => Track(RtcStat::new(id, timestamp, TrackStat::from(val))), "candidate-pair" => CandidatePair(RtcStat::new( id, timestamp, RtcIceCandidatePairStats::from(val), )), - "inbound-rtp" => InboundRtp, - "outbound-rtp" => OutboundRtp, + "inbound-rtp" => InboundRtp(RtcStat::new( + id, + timestamp, + InboundRtcStats::from(val), + )), + "outbound-rtp" => OutboundRtp(RtcStat::new( + id, + timestamp, + OutboundRtcStats::from(val), + )), "remote-inbound-rtp" => RemoteInboundRtp, "remote-outbound-rtp" => RemoteOutboundRtp, "media-source" => MediaSoure, @@ -184,86 +198,37 @@ impl TryFrom<&SysRtcStats> for RtcStatsType { } // https://www.w3.org/TR/webrtc-stats/#candidatepair-dict* -#[derive(Debug)] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] struct RtcIceCandidatePairStats { - state: IceCandidatePairState, - nominated: bool, - writable: bool, - bytes_sent: u64, - bytes_received: u64, - total_round_trip_time: f64, + state: Option, + nominated: Option, + writable: Option, + bytes_sent: Option, + bytes_received: Option, + total_round_trip_time: Option, current_round_trip_time: Option, available_outgoing_bitrate: Option, } impl From<&SysRtcStats> for RtcIceCandidatePairStats { fn from(val: &SysRtcStats) -> Self { - let state = - get_property_by_name(&val, "state", |val| val.as_string()).unwrap(); - let nominated = - get_property_by_name(&val, "nominated", |val| val.as_bool()) - .unwrap(); - let writable = - get_property_by_name(&val, "writable", |val| val.as_bool()) - .unwrap(); - let bytes_sent = get_property_by_name(&val, "bytesSent", |val| { - val.as_f64() - }) - .unwrap() as u64; - let bytes_received = - get_property_by_name(&val, "bytesReceived", |val| val.as_f64()) - .unwrap() as u64; - let total_round_trip_time = - get_property_by_name(&val, "totalRoundTripTime", |val| { - val.as_f64() - }) - .unwrap(); - let current_round_trip_time = - get_property_by_name(&val, "currentRoundTripTime", |val| { - val.as_f64() - }); - let available_outgoing_bitrate = - get_property_by_name(&val, "availableOutgoingBitrate", |val| { - val.as_f64() - }) - .map(|val| val as u64); - - RtcIceCandidatePairStats { - state: IceCandidatePairState::from(state.as_ref()), - nominated, - writable, - bytes_sent, - bytes_received, - total_round_trip_time, - current_round_trip_time, - available_outgoing_bitrate, - } + JsValue::from(val).into_serde().unwrap() } } // https://www.w3.org/TR/webrtc-stats/#rtcstatsicecandidatepairstate-enum -#[derive(Debug)] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "kebab-case")] enum IceCandidatePairState { Frozen, Waiting, Inprogress, Failed, Succeeded, - Unknown(String), -} - -impl From<&str> for IceCandidatePairState { - fn from(state: &str) -> Self { - use IceCandidatePairState::*; - match state { - "waiting" => Waiting, - "succeeded" => Succeeded, - "in-progress" => Inprogress, - "frozen" => Frozen, - "failed" => Failed, - _ => Unknown(state.to_owned()), - } - } + // TODO: make it Unknown(String) with unknown state inside. + #[serde(other)] + Unknown, } // https://www.w3.org/TR/webrtc-stats/#inboundrtpstats-dict* @@ -275,3 +240,115 @@ struct RtcInboundRtpStreamStats { packets_lost: u64, jitter: f64, } + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct TrackStat { + #[serde(rename = "trackIdentifier")] + track_id: String, + remote_source: Option, + ended: bool, + detached: bool, + kind: String, + media_source_id: Option, + jitter_buffer_delay: Option, + jitter_buffer_emitted_count: Option, + frame_width: Option, + frames_received: Option, + frames_decoded: Option, + frames_dropped: Option, +} + +impl From<&SysRtcStats> for TrackStat { + fn from(val: &SysRtcStats) -> Self { + JsValue::from(val).into_serde().unwrap() + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct InboundRtcStats { + jitter: Option, + kind: Option, + media_type: Option, + nack_count: Option, + packets_loss: Option, + packets_received: Option, + remote_id: Option, + ssrc: Option, +} + +impl From<&SysRtcStats> for InboundRtcStats { + fn from(val: &SysRtcStats) -> Self { + JsValue::from(val).into_serde().unwrap() + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct OutboundRtcStats { + bitrate_mean: Option, + bitrate_std_dev: Option, + bytes_sent: Option, + dropped_frames: Option, + fir_count: Option, + framerate_mean: Option, + framedrate_std_dev: Option, + framed_encoded: Option, + kind: Option, + media_type: Option, + nack_count: Option, + packets_sent: Option, + pli_count: Option, + qp_sum: Option, + remote_id: Option, + ssrc: Option, +} + +impl From<&SysRtcStats> for OutboundRtcStats { + fn from(val: &SysRtcStats) -> Self { + JsValue::from(val).into_serde().unwrap() + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct LocalCandidateStat { + network_type: Option, + address: Option, + transport_id: Option, + port: Option, + protocol: Option, + candidate_type: Option, + priority: Option, + url: Option, + relay_protocol: Option, + deleted: Option, +} + +impl From<&SysRtcStats> for LocalCandidateStat { + fn from(val: &SysRtcStats) -> Self { + JsValue::from(val).into_serde().unwrap() + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RemoteCandidateStat { + transport_id: Option, + network_type: Option, + address: Option, + port: Option, + protocol: Option, + candidate_type: Option, + priority: Option, + url: Option, + relay_protocol: Option, + deleted: Option, +} + +impl From<&SysRtcStats> for RemoteCandidateStat { + fn from(val: &SysRtcStats) -> Self { + JsValue::from(val).into_serde().unwrap() + } +} From 2a7c587ce0ca7b323d9d9222e4b76b1528b88398 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 3 Mar 2020 13:01:49 +0300 Subject: [PATCH 063/224] Print all stats as HashMap --- jason/src/peer/conn.rs | 2 +- jason/src/peer/stats/mod.rs | 71 ++++++++++++++++++++++++------------- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/jason/src/peer/conn.rs b/jason/src/peer/conn.rs index 1db9f18e9..18f931d12 100644 --- a/jason/src/peer/conn.rs +++ b/jason/src/peer/conn.rs @@ -261,7 +261,7 @@ impl RtcPeerConnection { asd(&stats); - console_error(format!("{:?}", RtcStats::from(&stats))); + console_error(format!("{:#?}", RtcStats::from(&stats))); }); }) as Box); window() diff --git a/jason/src/peer/stats/mod.rs b/jason/src/peer/stats/mod.rs index 6fed09b26..12b54761e 100644 --- a/jason/src/peer/stats/mod.rs +++ b/jason/src/peer/stats/mod.rs @@ -20,6 +20,7 @@ use web_sys::RtcStats as SysRtcStats; use crate::utils::{console_error, get_property_by_name}; use futures::future::Remote; +use std::collections::HashMap; struct RtcStatsReportEntry(js_sys::JsString, SysRtcStats); @@ -63,9 +64,7 @@ impl RtcStat { } #[derive(Debug)] -pub struct RtcStats { - ice_pairs: Vec>, -} +pub struct RtcStats(HashMap); impl From<&JsValue> for RtcStats { fn from(stats: &JsValue) -> Self { @@ -80,7 +79,7 @@ impl From<&JsValue> for RtcStats { .unwrap() .unchecked_into::(); - let mut ice_pairs = Vec::new(); + let mut stats = HashMap::new(); let mut next = iterator.next().unwrap(); while !next.done() { @@ -89,28 +88,12 @@ impl From<&JsValue> for RtcStats { let stat = RtcStatsReportEntry::try_from(stat).unwrap(); let stat = RtcStatsType::try_from(&stat.1).unwrap(); - console_error(format!("Stat: {:?}", stat)); - - match stat { - RtcStatsType::CandidatePair(pair) => { - if pair.kind.nominated.unwrap_or_default() { - ice_pairs.push(pair); - } - } - RtcStatsType::OutboundRtp(stat) => { - } - RtcStatsType::Unknown(unknown_stat) => { - // print error - } - _ => { - // ignore - } - } + stats.insert(stat.stat_name(), stat); next = iterator.next().unwrap(); } - RtcStats { ice_pairs } + RtcStats(stats) } } @@ -141,6 +124,38 @@ enum RtcStatsType { Unknown(String), } +impl RtcStatsType { + pub fn stat_name(&self) -> String { + use RtcStatsType::*; + + match self { + Codec => "codec", + InboundRtp(_) => "inbound-rtp", + OutboundRtp(_) => "outbound-rtp", + RemoteInboundRtp => "remote-inbound-rtp", + RemoteOutboundRtp => "remote-outbound-rtp", + MediaSoure => "media-source", + Csrc => "csrc", + PeerConnection => "peer-connection", + DataChannel => "data-channel", + Stream => "stream", + Track(_) => "track", + Transceiver => "transceiver", + Sender => "sender", + Receiver => "receiver", + Transport => "transport", + SctpTransport => "sctp-transport", + CandidatePair(_) => "candidate-pair", + LocalCandidate(_) => "local-candidate", + RemoteCandidate(_) => "remote-candidate", + Certificate => "certificate", + IceServer => "ice-server", + Unknown(s) => s.as_str(), + } + .to_string() + } +} + impl TryFrom<&SysRtcStats> for RtcStatsType { type Error = (); @@ -158,8 +173,16 @@ impl TryFrom<&SysRtcStats> for RtcStatsType { let kind = match kind.as_ref() { "codec" => Codec, - "local-candidate" => LocalCandidate(RtcStat::new(id, timestamp, LocalCandidateStat::from(val))), - "remote-candidate" => RemoteCandidate(RtcStat::new(id, timestamp, RemoteCandidateStat::from(val))), + "local-candidate" => LocalCandidate(RtcStat::new( + id, + timestamp, + LocalCandidateStat::from(val), + )), + "remote-candidate" => RemoteCandidate(RtcStat::new( + id, + timestamp, + RemoteCandidateStat::from(val), + )), "track" => Track(RtcStat::new(id, timestamp, TrackStat::from(val))), "candidate-pair" => CandidatePair(RtcStat::new( id, From bc96d24e2f842c9bea714d1749635779304b8902 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 3 Mar 2020 17:55:53 +0300 Subject: [PATCH 064/224] Add all available stats --- jason/src/peer/stats/mod.rs | 643 +++++++++++++++++++++++++----------- 1 file changed, 453 insertions(+), 190 deletions(-) diff --git a/jason/src/peer/stats/mod.rs b/jason/src/peer/stats/mod.rs index 12b54761e..d0ab1afd7 100644 --- a/jason/src/peer/stats/mod.rs +++ b/jason/src/peer/stats/mod.rs @@ -20,7 +20,7 @@ use web_sys::RtcStats as SysRtcStats; use crate::utils::{console_error, get_property_by_name}; use futures::future::Remote; -use std::collections::HashMap; +use std::{collections::HashMap, time::Duration}; struct RtcStatsReportEntry(js_sys::JsString, SysRtcStats); @@ -46,25 +46,16 @@ impl TryFrom for RtcStatsReportEntry { } } -#[derive(Debug)] +#[derive(Debug, Deserialize)] pub struct RtcStat { id: String, - timestamp: u64, + timestamp: f32, + #[serde(flatten)] kind: T, } -impl RtcStat { - fn new(id: String, timestamp: u64, kind: T) -> RtcStat { - RtcStat { - id, - timestamp, - kind, - } - } -} - #[derive(Debug)] -pub struct RtcStats(HashMap); +pub struct RtcStats(Vec); impl From<&JsValue> for RtcStats { fn from(stats: &JsValue) -> Self { @@ -79,7 +70,7 @@ impl From<&JsValue> for RtcStats { .unwrap() .unchecked_into::(); - let mut stats = HashMap::new(); + let mut stats = Vec::new(); let mut next = iterator.next().unwrap(); while !next.done() { @@ -88,7 +79,7 @@ impl From<&JsValue> for RtcStats { let stat = RtcStatsReportEntry::try_from(stat).unwrap(); let stat = RtcStatsType::try_from(&stat.1).unwrap(); - stats.insert(stat.stat_name(), stat); + stats.push(stat); next = iterator.next().unwrap(); } @@ -98,125 +89,309 @@ impl From<&JsValue> for RtcStats { } /// https://www.w3.org/TR/webrtc-stats/#rtctatstype-* -#[derive(Debug)] -enum RtcStatsType { - Codec, - InboundRtp(RtcStat), - OutboundRtp(RtcStat), - RemoteInboundRtp, - RemoteOutboundRtp, - MediaSoure, - Csrc, - PeerConnection, - DataChannel, - Stream, +#[derive(Debug, Deserialize)] +#[serde(tag = "type")] +#[serde(rename_all = "kebab-case")] +enum KnownRtcStatsType { + Codec(RtcStat), + InboundRtp(RtcStat), + OutboundRtp(RtcStat), + RemoteInboundRtp(RtcStat), + RemoteOutboundRtp(RtcStat), + Csrc(RtcStat), + PeerConnection(RtcStat), + DataChannel(RtcStat), + Stream(RtcStat), Track(RtcStat), - Transceiver, - Sender, - Receiver, - Transport, - SctpTransport, + Transceiver(RtcStat), + Sender(RtcStat), + Receiver(RtcStat), + Transport(RtcStat), + SctpTransport(RtcStat), CandidatePair(RtcStat), LocalCandidate(RtcStat), RemoteCandidate(RtcStat), - Certificate, - IceServer, - Unknown(String), + Certificate(RtcStat), + IceServer(RtcStat), + MediaSource(RtcStat), } -impl RtcStatsType { - pub fn stat_name(&self) -> String { - use RtcStatsType::*; - - match self { - Codec => "codec", - InboundRtp(_) => "inbound-rtp", - OutboundRtp(_) => "outbound-rtp", - RemoteInboundRtp => "remote-inbound-rtp", - RemoteOutboundRtp => "remote-outbound-rtp", - MediaSoure => "media-source", - Csrc => "csrc", - PeerConnection => "peer-connection", - DataChannel => "data-channel", - Stream => "stream", - Track(_) => "track", - Transceiver => "transceiver", - Sender => "sender", - Receiver => "receiver", - Transport => "transport", - SctpTransport => "sctp-transport", - CandidatePair(_) => "candidate-pair", - LocalCandidate(_) => "local-candidate", - RemoteCandidate(_) => "remote-candidate", - Certificate => "certificate", - IceServer => "ice-server", - Unknown(s) => s.as_str(), - } - .to_string() - } +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct MediaStreamStat { + /// `stream.id` property. + #[serde(rename = "streamIdentifier")] + stream_id: String, + + /// This is the id of the stats object, not the `track.id`. + track_ids: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct DataChannelStat { + /// The "label" value of the [`RTCDataChannel`] object. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + label: Option, + + /// The "protocol" value of the [`RTCDataChannel`] object. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + protocol: Option, + + /// The "id" attribute of the [`RTCDataChannel`] object. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + #[serde(rename = "dataChannelIdentifier")] + data_channel_id: Option, + + /// A [stats object reference] for the transport used to carry this + /// datachannel. + /// + /// [stats object reference]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-stats-object-reference + transport_id: Option, + + /// The "readyState" value of the [`RTCDataChannel`] object. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + state: Option, + + /// Represents the total number of API "message" events sent. + messages_sent: Option, + + /// Represents the total number of payload bytes sent on this + /// [`RTCDataChannel`], i.e., not including headers or padding. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + bytes_sent: Option, + + /// Represents the total number of API "message" events received. + messages_received: Option, + + /// Represents the total number of bytes received on this + /// [`RTCDataChannel`], i.e., not including headers or padding. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + bytes_received: Option, +} + +pub type DataChannelState = NonExhaustive; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum KnownDataChannelState { + Connecting, + Open, + Closing, + Closed, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RtcPeerConnectionStat { + /// Represents the number of unique `DataChannel`s that have entered the + /// "open" state during their lifetime. + data_channels_opened: Option, + + /// Represents the number of unique `DataChannel`s that have left the + /// "open" state during their lifetime (due to being closed by either + /// end or the underlying transport being closed). `DataChannel`s that + /// transition from "connecting" to "closing" or "closed" without ever + /// being "open" are not counted in this number. + data_channels_closed: Option, + + /// Represents the number of unique `DataChannel`s returned from a + /// successful `createDataChannel()` call on the `RTCPeerConnection`. + /// If the underlying data transport is not established, these may be + /// in the "connecting" state. + data_channels_requested: Option, + + /// Represents the number of unique `DataChannel`s signaled in a + /// "datachannel" event on the `RTCPeerConnection`. + data_channels_accepted: Option, } +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RtpContributingSourceStat { + /// The SSRC identifier of the contributing source represented by this + /// stats object, as defined by [RFC3550]. It is a 32-bit unsigned integer + /// that appears in the CSRC list of any packets the relevant source + /// contributed to. + /// + /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 + contributor_ssrc: Option, + + /// The ID of the [`RTCInboundRtpStreamStats`] object representing the + /// inbound RTP stream that this contributing source is contributing to. + /// + /// [`RTCInboundRtpStreamStats`]: + /// https://www.w3.org/TR/webrtc-stats/#dom-rtcinboundrtpstreamstats + inbound_rtp_stream_id: Option, + + /// The total number of RTP packets that this contributing source + /// contributed to. This value is incremented each time a packet is counted + /// by [`RTCInboundRtpStreamStats.packetsReceived`], and the packet's CSRC + /// list (as defined by [RFC3550] section 5.1) contains the SSRC identifier + /// of this contributing source, [`contributorSsrc`]. + /// + /// [`RTCInboundRtpStreamStats.packetsReceived`]: + /// https://tinyurl.com/rreuf49 + /// [`contributorSsrc`]: https://tinyurl.com/tf8c7j4 + packets_contributed_to: Option, + + /// Present if the last received RTP packet that this source contributed to + /// contained an [RFC6465] mixer-to-client audio level header extension. + /// The value of `audioLevel` is between `0..1` (linear), where `1.0` + /// represents `0 dBov`, `0` represents silence, and `0.5` represents + /// approximately `6 dBSPL` change in the sound pressure level from 0 + /// dBov. The [RFC6465] header extension contains values in the range + /// `0..127`, in units of `-dBov`, where `127` represents silence. To + /// convert these values to the linear `0..1` range of `audioLevel`, a + /// value of `127` is converted to `0`, and all other values are + /// converted using the equation: `f(rfc6465_level) = + /// 10^(-rfc6465_level/20)`. + /// + /// [RFC6465]: https://www.w3.org/TR/webrtc-stats/#bib-rfc6465 + audio_level: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RemoteOutboundRtpStreamStat { + /// The `localId` is used for looking up the local + /// [`RTCInboundRtpStreamStats`] object for the same SSRC. + /// + /// [`RTCInboundRtpStreamStats`]: + /// https://www.w3.org/TR/webrtc-stats/#dom-rtcinboundrtpstreamstats + local_id: Option, + + /// `remoteTimestamp`, of type `DOMHighResTimeStamp` [HIGHRES-TIME], + /// represents the remote timestamp at which these statistics were sent by + /// the remote endpoint. This differs from timestamp, which represents the + /// time at which the statistics were generated or received by the local + /// endpoint. The remoteTimestamp, if present, is derived from the NTP + /// timestamp in an RTCP Sender Report (SR) block, which reflects the + /// remote endpoint's clock. That clock may not be synchronized with the + /// local clock. + /// + /// [HIGRES-TIME]: https://www.w3.org/TR/webrtc-stats/#bib-highres-time + // TODO: test that this is correct. + remote_timestamp: Option, + + /// Represents the total number of RTCP SR blocks sent for this SSRC. + reports_sent: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RemoteInboundRtpStreamStat { + /// The `localId` is used for looking up the local + /// [`RTCOutboundRtpStreamStats`] object for the same SSRC. + /// + /// [`RTCOutBoundRtpStreamStats`]: + /// https://www.w3.org/TR/webrtc-stats/#dom-rtcoutboundrtpstreamstats + local_id: Option, + + /// Estimated round trip time for this SSRC based on the RTCP timestamps in + /// the RTCP Receiver Report (RR) and measured in seconds. Calculated as + /// defined in section 6.4.1. of [RFC3550]. If no RTCP Receiver Report is + /// received with a DLSR value other than 0, the round trip time is left + /// undefined. + /// + /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 + round_trip_time: Option, + + /// The fraction packet loss reported for this SSRC. Calculated as defined + /// in [RFC3550] section 6.4.1 and Appendix A.3. + /// + /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 + fraction_lost: Option, + + /// Represents the total number of RTCP RR blocks received for this SSRC. + reports_received: Option, + + /// Represents the total number of RTCP RR blocks received for this SSRC + /// that contain a valid round trip time. This counter will increment if + /// the roundTripTime is undefined. + round_trip_time_measurements: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RtpTransceiverStat { + sender_id: Option, + receiver_id: Option, + mid: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SctpTransport { + smoothed_round_trip_time: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TransportStat { + /// Represents the total number of packets sent over this transport. + packets_sent: Option, + + /// Represents the total number of packets received on this transport. + packets_received: Option, + + /// Represents the total number of payload bytes sent on this + /// `PeerConnection`, i.e., not including headers or padding. + bytes_sent: Option, + + /// Represents the total number of bytes received on this PeerConnection, + /// i.e., not including headers or padding. + bytes_received: Option, + + /// Set to the current value of the "role" attribute of the underlying + /// RTCDtlsTransport's "transport". + ice_role: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum IceRole { + Unknown, + Controlling, + Controlled, +} + +#[derive(Debug, Deserialize)] +#[serde(tag = "kind")] +#[serde(rename_all = "camelCase")] +pub enum SenderStatsKind { + Audio { media_source_id: Option }, + Video { media_source_id: Option }, +} + +#[derive(Debug, Deserialize)] +#[serde(tag = "kind")] +#[serde(rename_all = "camelCase")] +pub enum ReceiverStatsKind { + Audio {}, + Video {}, +} + +type RtcStatsType = NonExhaustive; + impl TryFrom<&SysRtcStats> for RtcStatsType { - type Error = (); + type Error = serde_json::Error; fn try_from(val: &SysRtcStats) -> Result { - use RtcStatsType::*; - - let id = get_property_by_name(&val, "id", |id| id.as_string()).unwrap(); - let timestamp = get_property_by_name(&val, "timestamp", |timestamp| { - timestamp.as_f64().map(|timestamp| timestamp as u64) - }) - .unwrap(); - let kind = - get_property_by_name(&val, "type", |type_| type_.as_string()) - .unwrap(); - - let kind = match kind.as_ref() { - "codec" => Codec, - "local-candidate" => LocalCandidate(RtcStat::new( - id, - timestamp, - LocalCandidateStat::from(val), - )), - "remote-candidate" => RemoteCandidate(RtcStat::new( - id, - timestamp, - RemoteCandidateStat::from(val), - )), - "track" => Track(RtcStat::new(id, timestamp, TrackStat::from(val))), - "candidate-pair" => CandidatePair(RtcStat::new( - id, - timestamp, - RtcIceCandidatePairStats::from(val), - )), - "inbound-rtp" => InboundRtp(RtcStat::new( - id, - timestamp, - InboundRtcStats::from(val), - )), - "outbound-rtp" => OutboundRtp(RtcStat::new( - id, - timestamp, - OutboundRtcStats::from(val), - )), - "remote-inbound-rtp" => RemoteInboundRtp, - "remote-outbound-rtp" => RemoteOutboundRtp, - "media-source" => MediaSoure, - "csrc" => Csrc, - "peer-connection" => PeerConnection, - "data-channel" => DataChannel, - "stream" => Stream, - "transceiver" => Transceiver, - "sender" => Sender, - "receiver" => Receiver, - "transport" => Transport, - "sctp-transport" => SctpTransport, - "certificate" => Certificate, - "ice-server" => IceServer, - _ => Unknown(kind), - }; - - Ok(kind) + JsValue::from(val).into_serde() } } @@ -224,55 +399,115 @@ impl TryFrom<&SysRtcStats> for RtcStatsType { #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] struct RtcIceCandidatePairStats { - state: Option, - nominated: Option, - writable: Option, - bytes_sent: Option, - bytes_received: Option, + state: IceCandidatePairState, + nominated: bool, + writable: bool, + bytes_sent: u64, + bytes_received: u64, total_round_trip_time: Option, current_round_trip_time: Option, available_outgoing_bitrate: Option, } -impl From<&SysRtcStats> for RtcIceCandidatePairStats { - fn from(val: &SysRtcStats) -> Self { - JsValue::from(val).into_serde().unwrap() - } +#[derive(Debug, Deserialize)] +#[serde(untagged)] +pub enum NonExhaustive { + Known(T), + Unknown(String), } -// https://www.w3.org/TR/webrtc-stats/#rtcstatsicecandidatepairstate-enum #[derive(Debug, Deserialize)] #[serde(rename_all = "kebab-case")] -enum IceCandidatePairState { +enum KnownIceCandidatePairState { Frozen, Waiting, - Inprogress, + InProgress, Failed, Succeeded, - // TODO: make it Unknown(String) with unknown state inside. - #[serde(other)] - Unknown, +} + +type IceCandidatePairState = NonExhaustive; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "lowercase")] +enum KnownProtocol { + Udp, + Tcp, +} + +type Protocol = NonExhaustive; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "lowercase")] +enum KnownCandidateType { + Prflx, + Host, +} + +type CandidateType = NonExhaustive; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "lowercase")] +enum KnownMediaType { + Audio, + Video, +} + +type MediaType = NonExhaustive; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +#[serde(tag = "mediaType")] +enum RtcInboundRtpStreamMediaType { + Audio { + voice_activity_flag: Option, + total_samples_received: Option, + concealed_samples: Option, + silent_concealed_samples: Option, + audio_level: Option, + total_audio_energy: Option, + total_samples_duration: Option, + }, + Video { + frames_decoded: Option, + key_frames_decoded: Option, + frame_width: Option, + frame_height: Option, + total_inter_frame_delay: Option, + #[serde(rename = "framesPerSecond")] + fps: Option, + frame_bit_depth: Option, + fir_count: Option, + pli_count: Option, + sli_count: Option, + concealment_events: Option, + frames_received: Option, + }, } // https://www.w3.org/TR/webrtc-stats/#inboundrtpstats-dict* -#[derive(Debug)] +#[derive(Debug, Deserialize)] struct RtcInboundRtpStreamStats { - media_type: bool, - bytes_received: u64, - packets_received: u64, - packets_lost: u64, - jitter: f64, + track_id: Option, + #[serde(flatten)] + media_type: RtcInboundRtpStreamMediaType, + bytes_received: Option, + packets_received: Option, + packets_lost: Option, + jitter: Option, + total_decode_time: Option, + jitter_buffer_emitted_count: Option, } #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] struct TrackStat { #[serde(rename = "trackIdentifier")] - track_id: String, + track_id: Option, remote_source: Option, - ended: bool, - detached: bool, - kind: String, + ended: Option, + detached: Option, + kind: Option, media_source_id: Option, jitter_buffer_delay: Option, jitter_buffer_emitted_count: Option, @@ -282,34 +517,23 @@ struct TrackStat { frames_dropped: Option, } -impl From<&SysRtcStats> for TrackStat { - fn from(val: &SysRtcStats) -> Self { - JsValue::from(val).into_serde().unwrap() - } -} - #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -struct InboundRtcStats { - jitter: Option, +struct InboundRtpStats { kind: Option, - media_type: Option, - nack_count: Option, + media_type: MediaType, + jitter: Option, + nack_count: Option, packets_loss: Option, - packets_received: Option, + packets_received: Option, remote_id: Option, ssrc: Option, -} - -impl From<&SysRtcStats> for InboundRtcStats { - fn from(val: &SysRtcStats) -> Self { - JsValue::from(val).into_serde().unwrap() - } + transport_id: Option, } #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -struct OutboundRtcStats { +struct OutboundRtpStats { bitrate_mean: Option, bitrate_std_dev: Option, bytes_sent: Option, @@ -319,7 +543,8 @@ struct OutboundRtcStats { framedrate_std_dev: Option, framed_encoded: Option, kind: Option, - media_type: Option, + framed_decoded: Option, + media_type: Option, nack_count: Option, packets_sent: Option, pli_count: Option, @@ -328,12 +553,6 @@ struct OutboundRtcStats { ssrc: Option, } -impl From<&SysRtcStats> for OutboundRtcStats { - fn from(val: &SysRtcStats) -> Self { - JsValue::from(val).into_serde().unwrap() - } -} - #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct LocalCandidateStat { @@ -341,20 +560,14 @@ pub struct LocalCandidateStat { address: Option, transport_id: Option, port: Option, - protocol: Option, - candidate_type: Option, + protocol: Option, + candidate_type: Option, priority: Option, url: Option, - relay_protocol: Option, + relay_protocol: Option, deleted: Option, } -impl From<&SysRtcStats> for LocalCandidateStat { - fn from(val: &SysRtcStats) -> Self { - JsValue::from(val).into_serde().unwrap() - } -} - #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RemoteCandidateStat { @@ -362,16 +575,66 @@ pub struct RemoteCandidateStat { network_type: Option, address: Option, port: Option, - protocol: Option, - candidate_type: Option, + protocol: Option, + candidate_type: Option, priority: Option, url: Option, - relay_protocol: Option, + relay_protocol: Option, deleted: Option, } -impl From<&SysRtcStats> for RemoteCandidateStat { - fn from(val: &SysRtcStats) -> Self { - JsValue::from(val).into_serde().unwrap() - } +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +#[serde(tag = "kind")] +pub enum MediaSourceKind { + Video { + width: Option, + height: Option, + #[serde(rename = "framesPerSecond")] + fps: Option, + }, + Audio { + audio_level: Option, + total_audio_energy: Option, + total_samples_duration: Option, + }, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct MediaSourceStat { + #[serde(rename = "trackIdentifier")] + track_id: Option, + #[serde(flatten)] + kind: MediaSourceKind, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CodecStat { + payload_type: Option, + // TODO: Parse it as MIME. + mime_type: Option, + clock_rate: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +// TODO: Maybe extract this data somehow? +pub struct CertificateStat { + fingerprint: Option, + // TODO: enum + fingerprint_algorithm: Option, + base64_certificate: Option, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct IceServerStat { + url: String, + port: u16, + protocol: Protocol, + total_requests_sent: Option, + total_responses_received: Option, + total_round_trip_time: Option, } From 82e39fbb43b97a265c28b977c81754af79c77392 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Tue, 3 Mar 2020 19:36:34 +0300 Subject: [PATCH 065/224] Add sending and receiving of stats update --- jason/src/api/room.rs | 9 + jason/src/peer/conn.rs | 29 +- jason/src/peer/mod.rs | 22 ++ jason/src/peer/stats/mod.rs | 558 +-------------------------------- proto/client-api/src/lib.rs | 7 + proto/client-api/src/stats.rs | 569 ++++++++++++++++++++++++++++++++++ src/signalling/room.rs | 11 + 7 files changed, 630 insertions(+), 575 deletions(-) create mode 100644 proto/client-api/src/stats.rs diff --git a/jason/src/api/room.rs b/jason/src/api/room.rs index 979ed405f..4b4a64dfe 100644 --- a/jason/src/api/room.rs +++ b/jason/src/api/room.rs @@ -39,6 +39,8 @@ use crate::{ }; use super::{connection::Connection, ConnectionHandle}; +use crate::peer::RtcStats; +use medea_client_api_proto::stats::RtcStat; /// Reason of why [`Room`] has been closed. /// @@ -894,6 +896,13 @@ impl PeerEventHandler for InnerRoom { ), }); } + + fn on_stats_update(&mut self, peer_id: PeerId, stats: RtcStats) { + self.rpc.send_command(Command::AddPeerConnectionStats { + peer_id, + stats: stats.0, + }); + } } impl Drop for InnerRoom { diff --git a/jason/src/peer/conn.rs b/jason/src/peer/conn.rs index 18f931d12..a99a93e08 100644 --- a/jason/src/peer/conn.rs +++ b/jason/src/peer/conn.rs @@ -251,27 +251,6 @@ impl RtcPeerConnection { let peer = Rc::new(peer); - let peer_clone = Rc::clone(&peer); - let a = Closure::wrap(Box::new(move || { - let another_peer_clone = Rc::clone(&peer_clone); - spawn_local(async move { - let stats = JsFuture::from(another_peer_clone.get_stats()) - .await - .unwrap(); - - asd(&stats); - - console_error(format!("{:#?}", RtcStats::from(&stats))); - }); - }) as Box); - window() - .set_interval_with_callback_and_timeout_and_arguments_0( - a.as_ref().unchecked_ref(), - 10000, - ) - .unwrap(); - a.forget(); - Ok(Self { peer, on_ice_candidate: RefCell::new(None), @@ -280,6 +259,14 @@ impl RtcPeerConnection { }) } + pub async fn get_stats(&self) -> RtcStats { + let js_stats = JsFuture::from(self.peer.get_stats()).await.unwrap(); + + asd(&js_stats); + + RtcStats::from(&js_stats) + } + /// Sets handler for [`RtcTrackEvent`] event (see [RTCTrackEvent][1] and /// [`ontrack` callback][2]). /// diff --git a/jason/src/peer/mod.rs b/jason/src/peer/mod.rs index 536b05aa7..5d83f5e9c 100644 --- a/jason/src/peer/mod.rs +++ b/jason/src/peer/mod.rs @@ -48,6 +48,10 @@ pub use self::{ stream_request::{SimpleStreamRequest, StreamRequest, StreamRequestError}, track::MediaTrack, }; +pub use crate::peer::stats::RtcStats; +use crate::utils::delay_for; +use std::time::Duration; +use wasm_bindgen_futures::spawn_local; /// Errors that may occur in [RTCPeerConnection][1]. /// @@ -144,6 +148,10 @@ pub enum PeerEvent { /// New [`IceConnectionState`]. ice_connection_state: IceConnectionState, }, + StatsUpdate { + peer_id: Id, + stats: RtcStats, + }, } /// High-level wrapper around [`RtcPeerConnection`]. @@ -212,6 +220,20 @@ impl PeerConnection { ice_candidates_buffer: RefCell::new(vec![]), }; + let id = peer.id; + let sender = peer.peer_events_sender.clone(); + let peer_clone = peer.peer.clone(); + spawn_local(async move { + loop { + delay_for(Duration::from_secs(5).into()).await; + let stats = peer_clone.get_stats().await; + let _ = sender.unbounded_send(PeerEvent::StatsUpdate { + peer_id: id, + stats, + }); + } + }); + // Bind to `icecandidate` event. let id = peer.id; let sender = peer.peer_events_sender.clone(); diff --git a/jason/src/peer/stats/mod.rs b/jason/src/peer/stats/mod.rs index d0ab1afd7..7b3edc28c 100644 --- a/jason/src/peer/stats/mod.rs +++ b/jason/src/peer/stats/mod.rs @@ -10,10 +10,10 @@ //! [4]: https://heycam.github.io/webidl/#es-map-entries //! [5]: https://www.w3.org/TR/webrtc/#dom-rtcstats-id //! [6]: https://www.w3.org/TR/webrtc/#dom-rtcstats -//! use std::convert::TryFrom; +use medea_client_api_proto::stats::RtcStatsType; use serde::Deserialize; use wasm_bindgen::{prelude::*, JsCast}; use web_sys::RtcStats as SysRtcStats; @@ -55,7 +55,7 @@ pub struct RtcStat { } #[derive(Debug)] -pub struct RtcStats(Vec); +pub struct RtcStats(pub Vec); impl From<&JsValue> for RtcStats { fn from(stats: &JsValue) -> Self { @@ -77,7 +77,8 @@ impl From<&JsValue> for RtcStats { let stat = next.value(); let stat = stat.unchecked_into::(); let stat = RtcStatsReportEntry::try_from(stat).unwrap(); - let stat = RtcStatsType::try_from(&stat.1).unwrap(); + let stat: RtcStatsType = + JsValue::from(&stat.1).into_serde().unwrap(); stats.push(stat); @@ -87,554 +88,3 @@ impl From<&JsValue> for RtcStats { RtcStats(stats) } } - -/// https://www.w3.org/TR/webrtc-stats/#rtctatstype-* -#[derive(Debug, Deserialize)] -#[serde(tag = "type")] -#[serde(rename_all = "kebab-case")] -enum KnownRtcStatsType { - Codec(RtcStat), - InboundRtp(RtcStat), - OutboundRtp(RtcStat), - RemoteInboundRtp(RtcStat), - RemoteOutboundRtp(RtcStat), - Csrc(RtcStat), - PeerConnection(RtcStat), - DataChannel(RtcStat), - Stream(RtcStat), - Track(RtcStat), - Transceiver(RtcStat), - Sender(RtcStat), - Receiver(RtcStat), - Transport(RtcStat), - SctpTransport(RtcStat), - CandidatePair(RtcStat), - LocalCandidate(RtcStat), - RemoteCandidate(RtcStat), - Certificate(RtcStat), - IceServer(RtcStat), - MediaSource(RtcStat), -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct MediaStreamStat { - /// `stream.id` property. - #[serde(rename = "streamIdentifier")] - stream_id: String, - - /// This is the id of the stats object, not the `track.id`. - track_ids: Vec, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct DataChannelStat { - /// The "label" value of the [`RTCDataChannel`] object. - /// - /// [`RTCDataChannel`]: - /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel - label: Option, - - /// The "protocol" value of the [`RTCDataChannel`] object. - /// - /// [`RTCDataChannel`]: - /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel - protocol: Option, - - /// The "id" attribute of the [`RTCDataChannel`] object. - /// - /// [`RTCDataChannel`]: - /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel - #[serde(rename = "dataChannelIdentifier")] - data_channel_id: Option, - - /// A [stats object reference] for the transport used to carry this - /// datachannel. - /// - /// [stats object reference]: - /// https://www.w3.org/TR/webrtc-stats/#dfn-stats-object-reference - transport_id: Option, - - /// The "readyState" value of the [`RTCDataChannel`] object. - /// - /// [`RTCDataChannel`]: - /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel - state: Option, - - /// Represents the total number of API "message" events sent. - messages_sent: Option, - - /// Represents the total number of payload bytes sent on this - /// [`RTCDataChannel`], i.e., not including headers or padding. - /// - /// [`RTCDataChannel`]: - /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel - bytes_sent: Option, - - /// Represents the total number of API "message" events received. - messages_received: Option, - - /// Represents the total number of bytes received on this - /// [`RTCDataChannel`], i.e., not including headers or padding. - /// - /// [`RTCDataChannel`]: - /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel - bytes_received: Option, -} - -pub type DataChannelState = NonExhaustive; - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "kebab-case")] -pub enum KnownDataChannelState { - Connecting, - Open, - Closing, - Closed, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RtcPeerConnectionStat { - /// Represents the number of unique `DataChannel`s that have entered the - /// "open" state during their lifetime. - data_channels_opened: Option, - - /// Represents the number of unique `DataChannel`s that have left the - /// "open" state during their lifetime (due to being closed by either - /// end or the underlying transport being closed). `DataChannel`s that - /// transition from "connecting" to "closing" or "closed" without ever - /// being "open" are not counted in this number. - data_channels_closed: Option, - - /// Represents the number of unique `DataChannel`s returned from a - /// successful `createDataChannel()` call on the `RTCPeerConnection`. - /// If the underlying data transport is not established, these may be - /// in the "connecting" state. - data_channels_requested: Option, - - /// Represents the number of unique `DataChannel`s signaled in a - /// "datachannel" event on the `RTCPeerConnection`. - data_channels_accepted: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RtpContributingSourceStat { - /// The SSRC identifier of the contributing source represented by this - /// stats object, as defined by [RFC3550]. It is a 32-bit unsigned integer - /// that appears in the CSRC list of any packets the relevant source - /// contributed to. - /// - /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 - contributor_ssrc: Option, - - /// The ID of the [`RTCInboundRtpStreamStats`] object representing the - /// inbound RTP stream that this contributing source is contributing to. - /// - /// [`RTCInboundRtpStreamStats`]: - /// https://www.w3.org/TR/webrtc-stats/#dom-rtcinboundrtpstreamstats - inbound_rtp_stream_id: Option, - - /// The total number of RTP packets that this contributing source - /// contributed to. This value is incremented each time a packet is counted - /// by [`RTCInboundRtpStreamStats.packetsReceived`], and the packet's CSRC - /// list (as defined by [RFC3550] section 5.1) contains the SSRC identifier - /// of this contributing source, [`contributorSsrc`]. - /// - /// [`RTCInboundRtpStreamStats.packetsReceived`]: - /// https://tinyurl.com/rreuf49 - /// [`contributorSsrc`]: https://tinyurl.com/tf8c7j4 - packets_contributed_to: Option, - - /// Present if the last received RTP packet that this source contributed to - /// contained an [RFC6465] mixer-to-client audio level header extension. - /// The value of `audioLevel` is between `0..1` (linear), where `1.0` - /// represents `0 dBov`, `0` represents silence, and `0.5` represents - /// approximately `6 dBSPL` change in the sound pressure level from 0 - /// dBov. The [RFC6465] header extension contains values in the range - /// `0..127`, in units of `-dBov`, where `127` represents silence. To - /// convert these values to the linear `0..1` range of `audioLevel`, a - /// value of `127` is converted to `0`, and all other values are - /// converted using the equation: `f(rfc6465_level) = - /// 10^(-rfc6465_level/20)`. - /// - /// [RFC6465]: https://www.w3.org/TR/webrtc-stats/#bib-rfc6465 - audio_level: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RemoteOutboundRtpStreamStat { - /// The `localId` is used for looking up the local - /// [`RTCInboundRtpStreamStats`] object for the same SSRC. - /// - /// [`RTCInboundRtpStreamStats`]: - /// https://www.w3.org/TR/webrtc-stats/#dom-rtcinboundrtpstreamstats - local_id: Option, - - /// `remoteTimestamp`, of type `DOMHighResTimeStamp` [HIGHRES-TIME], - /// represents the remote timestamp at which these statistics were sent by - /// the remote endpoint. This differs from timestamp, which represents the - /// time at which the statistics were generated or received by the local - /// endpoint. The remoteTimestamp, if present, is derived from the NTP - /// timestamp in an RTCP Sender Report (SR) block, which reflects the - /// remote endpoint's clock. That clock may not be synchronized with the - /// local clock. - /// - /// [HIGRES-TIME]: https://www.w3.org/TR/webrtc-stats/#bib-highres-time - // TODO: test that this is correct. - remote_timestamp: Option, - - /// Represents the total number of RTCP SR blocks sent for this SSRC. - reports_sent: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RemoteInboundRtpStreamStat { - /// The `localId` is used for looking up the local - /// [`RTCOutboundRtpStreamStats`] object for the same SSRC. - /// - /// [`RTCOutBoundRtpStreamStats`]: - /// https://www.w3.org/TR/webrtc-stats/#dom-rtcoutboundrtpstreamstats - local_id: Option, - - /// Estimated round trip time for this SSRC based on the RTCP timestamps in - /// the RTCP Receiver Report (RR) and measured in seconds. Calculated as - /// defined in section 6.4.1. of [RFC3550]. If no RTCP Receiver Report is - /// received with a DLSR value other than 0, the round trip time is left - /// undefined. - /// - /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 - round_trip_time: Option, - - /// The fraction packet loss reported for this SSRC. Calculated as defined - /// in [RFC3550] section 6.4.1 and Appendix A.3. - /// - /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 - fraction_lost: Option, - - /// Represents the total number of RTCP RR blocks received for this SSRC. - reports_received: Option, - - /// Represents the total number of RTCP RR blocks received for this SSRC - /// that contain a valid round trip time. This counter will increment if - /// the roundTripTime is undefined. - round_trip_time_measurements: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RtpTransceiverStat { - sender_id: Option, - receiver_id: Option, - mid: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SctpTransport { - smoothed_round_trip_time: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct TransportStat { - /// Represents the total number of packets sent over this transport. - packets_sent: Option, - - /// Represents the total number of packets received on this transport. - packets_received: Option, - - /// Represents the total number of payload bytes sent on this - /// `PeerConnection`, i.e., not including headers or padding. - bytes_sent: Option, - - /// Represents the total number of bytes received on this PeerConnection, - /// i.e., not including headers or padding. - bytes_received: Option, - - /// Set to the current value of the "role" attribute of the underlying - /// RTCDtlsTransport's "transport". - ice_role: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum IceRole { - Unknown, - Controlling, - Controlled, -} - -#[derive(Debug, Deserialize)] -#[serde(tag = "kind")] -#[serde(rename_all = "camelCase")] -pub enum SenderStatsKind { - Audio { media_source_id: Option }, - Video { media_source_id: Option }, -} - -#[derive(Debug, Deserialize)] -#[serde(tag = "kind")] -#[serde(rename_all = "camelCase")] -pub enum ReceiverStatsKind { - Audio {}, - Video {}, -} - -type RtcStatsType = NonExhaustive; - -impl TryFrom<&SysRtcStats> for RtcStatsType { - type Error = serde_json::Error; - - fn try_from(val: &SysRtcStats) -> Result { - JsValue::from(val).into_serde() - } -} - -// https://www.w3.org/TR/webrtc-stats/#candidatepair-dict* -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -struct RtcIceCandidatePairStats { - state: IceCandidatePairState, - nominated: bool, - writable: bool, - bytes_sent: u64, - bytes_received: u64, - total_round_trip_time: Option, - current_round_trip_time: Option, - available_outgoing_bitrate: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(untagged)] -pub enum NonExhaustive { - Known(T), - Unknown(String), -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "kebab-case")] -enum KnownIceCandidatePairState { - Frozen, - Waiting, - InProgress, - Failed, - Succeeded, -} - -type IceCandidatePairState = NonExhaustive; - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "lowercase")] -enum KnownProtocol { - Udp, - Tcp, -} - -type Protocol = NonExhaustive; - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "lowercase")] -enum KnownCandidateType { - Prflx, - Host, -} - -type CandidateType = NonExhaustive; - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "lowercase")] -enum KnownMediaType { - Audio, - Video, -} - -type MediaType = NonExhaustive; - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -#[serde(tag = "mediaType")] -enum RtcInboundRtpStreamMediaType { - Audio { - voice_activity_flag: Option, - total_samples_received: Option, - concealed_samples: Option, - silent_concealed_samples: Option, - audio_level: Option, - total_audio_energy: Option, - total_samples_duration: Option, - }, - Video { - frames_decoded: Option, - key_frames_decoded: Option, - frame_width: Option, - frame_height: Option, - total_inter_frame_delay: Option, - #[serde(rename = "framesPerSecond")] - fps: Option, - frame_bit_depth: Option, - fir_count: Option, - pli_count: Option, - sli_count: Option, - concealment_events: Option, - frames_received: Option, - }, -} - -// https://www.w3.org/TR/webrtc-stats/#inboundrtpstats-dict* -#[derive(Debug, Deserialize)] -struct RtcInboundRtpStreamStats { - track_id: Option, - #[serde(flatten)] - media_type: RtcInboundRtpStreamMediaType, - bytes_received: Option, - packets_received: Option, - packets_lost: Option, - jitter: Option, - total_decode_time: Option, - jitter_buffer_emitted_count: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -struct TrackStat { - #[serde(rename = "trackIdentifier")] - track_id: Option, - remote_source: Option, - ended: Option, - detached: Option, - kind: Option, - media_source_id: Option, - jitter_buffer_delay: Option, - jitter_buffer_emitted_count: Option, - frame_width: Option, - frames_received: Option, - frames_decoded: Option, - frames_dropped: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -struct InboundRtpStats { - kind: Option, - media_type: MediaType, - jitter: Option, - nack_count: Option, - packets_loss: Option, - packets_received: Option, - remote_id: Option, - ssrc: Option, - transport_id: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -struct OutboundRtpStats { - bitrate_mean: Option, - bitrate_std_dev: Option, - bytes_sent: Option, - dropped_frames: Option, - fir_count: Option, - framerate_mean: Option, - framedrate_std_dev: Option, - framed_encoded: Option, - kind: Option, - framed_decoded: Option, - media_type: Option, - nack_count: Option, - packets_sent: Option, - pli_count: Option, - qp_sum: Option, - remote_id: Option, - ssrc: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct LocalCandidateStat { - network_type: Option, - address: Option, - transport_id: Option, - port: Option, - protocol: Option, - candidate_type: Option, - priority: Option, - url: Option, - relay_protocol: Option, - deleted: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RemoteCandidateStat { - transport_id: Option, - network_type: Option, - address: Option, - port: Option, - protocol: Option, - candidate_type: Option, - priority: Option, - url: Option, - relay_protocol: Option, - deleted: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -#[serde(tag = "kind")] -pub enum MediaSourceKind { - Video { - width: Option, - height: Option, - #[serde(rename = "framesPerSecond")] - fps: Option, - }, - Audio { - audio_level: Option, - total_audio_energy: Option, - total_samples_duration: Option, - }, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct MediaSourceStat { - #[serde(rename = "trackIdentifier")] - track_id: Option, - #[serde(flatten)] - kind: MediaSourceKind, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CodecStat { - payload_type: Option, - // TODO: Parse it as MIME. - mime_type: Option, - clock_rate: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -// TODO: Maybe extract this data somehow? -pub struct CertificateStat { - fingerprint: Option, - // TODO: enum - fingerprint_algorithm: Option, - base64_certificate: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct IceServerStat { - url: String, - port: u16, - protocol: Protocol, - total_requests_sent: Option, - total_responses_received: Option, - total_round_trip_time: Option, -} diff --git a/proto/client-api/src/lib.rs b/proto/client-api/src/lib.rs index a19cfaaee..b2324fe6a 100644 --- a/proto/client-api/src/lib.rs +++ b/proto/client-api/src/lib.rs @@ -1,7 +1,10 @@ //! Client API protocol implementation for Medea media server. +pub mod stats; + use std::collections::HashMap; +use crate::stats::RtcStatsType; use derive_more::{Constructor, Display}; use medea_macro::dispatchable; use serde::{de::Deserializer, ser::Serializer, Deserialize, Serialize}; @@ -136,6 +139,10 @@ pub enum Command { peer_id: PeerId, tracks_patches: Vec, }, + AddPeerConnectionStats { + peer_id: PeerId, + stats: Vec, + }, } /// Web Client's Peer Connection metrics. diff --git a/proto/client-api/src/stats.rs b/proto/client-api/src/stats.rs new file mode 100644 index 000000000..e24451313 --- /dev/null +++ b/proto/client-api/src/stats.rs @@ -0,0 +1,569 @@ +//! [Spec][] is quite new atm, and is poorly adopted by UA's. +//! +//! [RTCStatsReport][2] allows [maplike][3] operations. [entries()][4] operation +//! returns array of arrays, where first value is [RTCStats.id][5] and second is +//! actual [RTCStats][6]. +//! +//! [1]: https://www.w3.org/TR/webrtc-stats/ +//! [2]: https://www.w3.org/TR/webrtc/#rtcstatsreport-object +//! [3]: https://heycam.github.io/webidl/#idl-maplike +//! [4]: https://heycam.github.io/webidl/#es-map-entries +//! [5]: https://www.w3.org/TR/webrtc/#dom-rtcstats-id +//! [6]: https://www.w3.org/TR/webrtc/#dom-rtcstats + +use std::convert::TryFrom; + +use serde::{Deserialize, Serialize}; + +use std::{collections::HashMap, time::Duration}; + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +pub struct RtcStat { + id: String, + timestamp: f32, + #[serde(flatten)] + kind: T, +} + +/// https://www.w3.org/TR/webrtc-stats/#rtctatstype-* +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(tag = "type")] +#[serde(rename_all = "kebab-case")] +pub enum KnownRtcStatsType { + Codec(RtcStat), + InboundRtp(RtcStat), + OutboundRtp(RtcStat), + RemoteInboundRtp(RtcStat), + RemoteOutboundRtp(RtcStat), + Csrc(RtcStat), + PeerConnection(RtcStat), + DataChannel(RtcStat), + Stream(RtcStat), + Track(RtcStat), + Transceiver(RtcStat), + Sender(RtcStat), + Receiver(RtcStat), + Transport(RtcStat), + SctpTransport(RtcStat), + CandidatePair(RtcStat), + LocalCandidate(RtcStat), + RemoteCandidate(RtcStat), + Certificate(RtcStat), + IceServer(RtcStat), + MediaSource(RtcStat), +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct MediaStreamStat { + /// `stream.id` property. + #[serde(rename = "streamIdentifier")] + stream_id: String, + + /// This is the id of the stats object, not the `track.id`. + track_ids: Vec, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct DataChannelStat { + /// The "label" value of the [`RTCDataChannel`] object. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + label: Option, + + /// The "protocol" value of the [`RTCDataChannel`] object. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + protocol: Option, + + /// The "id" attribute of the [`RTCDataChannel`] object. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + #[serde(rename = "dataChannelIdentifier")] + data_channel_id: Option, + + /// A [stats object reference] for the transport used to carry this + /// datachannel. + /// + /// [stats object reference]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-stats-object-reference + transport_id: Option, + + /// The "readyState" value of the [`RTCDataChannel`] object. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + state: Option, + + /// Represents the total number of API "message" events sent. + messages_sent: Option, + + /// Represents the total number of payload bytes sent on this + /// [`RTCDataChannel`], i.e., not including headers or padding. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + bytes_sent: Option, + + /// Represents the total number of API "message" events received. + messages_received: Option, + + /// Represents the total number of bytes received on this + /// [`RTCDataChannel`], i.e., not including headers or padding. + /// + /// [`RTCDataChannel`]: + /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel + bytes_received: Option, +} + +pub type DataChannelState = NonExhaustive; + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "kebab-case")] +pub enum KnownDataChannelState { + Connecting, + Open, + Closing, + Closed, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct RtcPeerConnectionStat { + /// Represents the number of unique `DataChannel`s that have entered the + /// "open" state during their lifetime. + data_channels_opened: Option, + + /// Represents the number of unique `DataChannel`s that have left the + /// "open" state during their lifetime (due to being closed by either + /// end or the underlying transport being closed). `DataChannel`s that + /// transition from "connecting" to "closing" or "closed" without ever + /// being "open" are not counted in this number. + data_channels_closed: Option, + + /// Represents the number of unique `DataChannel`s returned from a + /// successful `createDataChannel()` call on the `RTCPeerConnection`. + /// If the underlying data transport is not established, these may be + /// in the "connecting" state. + data_channels_requested: Option, + + /// Represents the number of unique `DataChannel`s signaled in a + /// "datachannel" event on the `RTCPeerConnection`. + data_channels_accepted: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct RtpContributingSourceStat { + /// The SSRC identifier of the contributing source represented by this + /// stats object, as defined by [RFC3550]. It is a 32-bit unsigned integer + /// that appears in the CSRC list of any packets the relevant source + /// contributed to. + /// + /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 + contributor_ssrc: Option, + + /// The ID of the [`RTCInboundRtpStreamStats`] object representing the + /// inbound RTP stream that this contributing source is contributing to. + /// + /// [`RTCInboundRtpStreamStats`]: + /// https://www.w3.org/TR/webrtc-stats/#dom-rtcinboundrtpstreamstats + inbound_rtp_stream_id: Option, + + /// The total number of RTP packets that this contributing source + /// contributed to. This value is incremented each time a packet is counted + /// by [`RTCInboundRtpStreamStats.packetsReceived`], and the packet's CSRC + /// list (as defined by [RFC3550] section 5.1) contains the SSRC identifier + /// of this contributing source, [`contributorSsrc`]. + /// + /// [`RTCInboundRtpStreamStats.packetsReceived`]: + /// https://tinyurl.com/rreuf49 + /// [`contributorSsrc`]: https://tinyurl.com/tf8c7j4 + packets_contributed_to: Option, + + /// Present if the last received RTP packet that this source contributed to + /// contained an [RFC6465] mixer-to-client audio level header extension. + /// The value of `audioLevel` is between `0..1` (linear), where `1.0` + /// represents `0 dBov`, `0` represents silence, and `0.5` represents + /// approximately `6 dBSPL` change in the sound pressure level from 0 + /// dBov. The [RFC6465] header extension contains values in the range + /// `0..127`, in units of `-dBov`, where `127` represents silence. To + /// convert these values to the linear `0..1` range of `audioLevel`, a + /// value of `127` is converted to `0`, and all other values are + /// converted using the equation: `f(rfc6465_level) = + /// 10^(-rfc6465_level/20)`. + /// + /// [RFC6465]: https://www.w3.org/TR/webrtc-stats/#bib-rfc6465 + audio_level: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct RemoteOutboundRtpStreamStat { + /// The `localId` is used for looking up the local + /// [`RTCInboundRtpStreamStats`] object for the same SSRC. + /// + /// [`RTCInboundRtpStreamStats`]: + /// https://www.w3.org/TR/webrtc-stats/#dom-rtcinboundrtpstreamstats + local_id: Option, + + /// `remoteTimestamp`, of type `DOMHighResTimeStamp` [HIGHRES-TIME], + /// represents the remote timestamp at which these statistics were sent by + /// the remote endpoint. This differs from timestamp, which represents the + /// time at which the statistics were generated or received by the local + /// endpoint. The remoteTimestamp, if present, is derived from the NTP + /// timestamp in an RTCP Sender Report (SR) block, which reflects the + /// remote endpoint's clock. That clock may not be synchronized with the + /// local clock. + /// + /// [HIGRES-TIME]: https://www.w3.org/TR/webrtc-stats/#bib-highres-time + // TODO: test that this is correct. + remote_timestamp: Option, + + /// Represents the total number of RTCP SR blocks sent for this SSRC. + reports_sent: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct RemoteInboundRtpStreamStat { + /// The `localId` is used for looking up the local + /// [`RTCOutboundRtpStreamStats`] object for the same SSRC. + /// + /// [`RTCOutBoundRtpStreamStats`]: + /// https://www.w3.org/TR/webrtc-stats/#dom-rtcoutboundrtpstreamstats + local_id: Option, + + /// Estimated round trip time for this SSRC based on the RTCP timestamps in + /// the RTCP Receiver Report (RR) and measured in seconds. Calculated as + /// defined in section 6.4.1. of [RFC3550]. If no RTCP Receiver Report is + /// received with a DLSR value other than 0, the round trip time is left + /// undefined. + /// + /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 + round_trip_time: Option, + + /// The fraction packet loss reported for this SSRC. Calculated as defined + /// in [RFC3550] section 6.4.1 and Appendix A.3. + /// + /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 + fraction_lost: Option, + + /// Represents the total number of RTCP RR blocks received for this SSRC. + reports_received: Option, + + /// Represents the total number of RTCP RR blocks received for this SSRC + /// that contain a valid round trip time. This counter will increment if + /// the roundTripTime is undefined. + round_trip_time_measurements: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct RtpTransceiverStat { + sender_id: Option, + receiver_id: Option, + mid: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct SctpTransport { + smoothed_round_trip_time: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct TransportStat { + /// Represents the total number of packets sent over this transport. + packets_sent: Option, + + /// Represents the total number of packets received on this transport. + packets_received: Option, + + /// Represents the total number of payload bytes sent on this + /// `PeerConnection`, i.e., not including headers or padding. + bytes_sent: Option, + + /// Represents the total number of bytes received on this PeerConnection, + /// i.e., not including headers or padding. + bytes_received: Option, + + /// Set to the current value of the "role" attribute of the underlying + /// RTCDtlsTransport's "transport". + ice_role: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub enum IceRole { + Unknown, + Controlling, + Controlled, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(tag = "kind")] +#[serde(rename_all = "camelCase")] +pub enum SenderStatsKind { + Audio { media_source_id: Option }, + Video { media_source_id: Option }, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(tag = "kind")] +#[serde(rename_all = "camelCase")] +pub enum ReceiverStatsKind { + Audio {}, + Video {}, +} + +pub type RtcStatsType = NonExhaustive; + +// https://www.w3.org/TR/webrtc-stats/#candidatepair-dict* +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct RtcIceCandidatePairStats { + state: IceCandidatePairState, + nominated: bool, + writable: bool, + bytes_sent: u64, + bytes_received: u64, + total_round_trip_time: Option, + current_round_trip_time: Option, + available_outgoing_bitrate: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(untagged)] +pub enum NonExhaustive { + Known(T), + Unknown(String), +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "kebab-case")] +pub enum KnownIceCandidatePairState { + Frozen, + Waiting, + InProgress, + Failed, + Succeeded, +} + +pub type IceCandidatePairState = NonExhaustive; + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "lowercase")] +pub enum KnownProtocol { + Udp, + Tcp, +} + +pub type Protocol = NonExhaustive; + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "lowercase")] +pub enum KnownCandidateType { + Prflx, + Host, +} + +pub type CandidateType = NonExhaustive; + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "lowercase")] +pub enum KnownMediaType { + Audio, + Video, +} + +pub type MediaType = NonExhaustive; + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +#[serde(tag = "mediaType")] +pub enum RtcInboundRtpStreamMediaType { + Audio { + voice_activity_flag: Option, + total_samples_received: Option, + concealed_samples: Option, + silent_concealed_samples: Option, + audio_level: Option, + total_audio_energy: Option, + total_samples_duration: Option, + }, + Video { + frames_decoded: Option, + key_frames_decoded: Option, + frame_width: Option, + frame_height: Option, + total_inter_frame_delay: Option, + #[serde(rename = "framesPerSecond")] + fps: Option, + frame_bit_depth: Option, + fir_count: Option, + pli_count: Option, + sli_count: Option, + concealment_events: Option, + frames_received: Option, + }, +} + +// https://www.w3.org/TR/webrtc-stats/#inboundrtpstats-dict* +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +pub struct RtcInboundRtpStreamStats { + track_id: Option, + #[serde(flatten)] + media_type: RtcInboundRtpStreamMediaType, + bytes_received: Option, + packets_received: Option, + packets_lost: Option, + jitter: Option, + total_decode_time: Option, + jitter_buffer_emitted_count: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct TrackStat { + #[serde(rename = "trackIdentifier")] + track_id: Option, + remote_source: Option, + ended: Option, + detached: Option, + kind: Option, + media_source_id: Option, + jitter_buffer_delay: Option, + jitter_buffer_emitted_count: Option, + frame_width: Option, + frames_received: Option, + frames_decoded: Option, + frames_dropped: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct InboundRtpStats { + kind: Option, + media_type: MediaType, + jitter: Option, + nack_count: Option, + packets_loss: Option, + packets_received: Option, + remote_id: Option, + ssrc: Option, + transport_id: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct OutboundRtpStats { + bitrate_mean: Option, + bitrate_std_dev: Option, + bytes_sent: Option, + dropped_frames: Option, + fir_count: Option, + framerate_mean: Option, + framedrate_std_dev: Option, + framed_encoded: Option, + kind: Option, + framed_decoded: Option, + media_type: Option, + nack_count: Option, + packets_sent: Option, + pli_count: Option, + qp_sum: Option, + remote_id: Option, + ssrc: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct LocalCandidateStat { + network_type: Option, + address: Option, + transport_id: Option, + port: Option, + protocol: Option, + candidate_type: Option, + priority: Option, + url: Option, + relay_protocol: Option, + deleted: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct RemoteCandidateStat { + transport_id: Option, + network_type: Option, + address: Option, + port: Option, + protocol: Option, + candidate_type: Option, + priority: Option, + url: Option, + relay_protocol: Option, + deleted: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +#[serde(tag = "kind")] +pub enum MediaSourceKind { + Video { + width: Option, + height: Option, + #[serde(rename = "framesPerSecond")] + fps: Option, + }, + Audio { + audio_level: Option, + total_audio_energy: Option, + total_samples_duration: Option, + }, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct MediaSourceStat { + #[serde(rename = "trackIdentifier")] + track_id: Option, + #[serde(flatten)] + kind: MediaSourceKind, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct CodecStat { + payload_type: Option, + // TODO: Parse it as MIME. + mime_type: Option, + clock_rate: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +// TODO: Maybe extract this data somehow? +pub struct CertificateStat { + fingerprint: Option, + // TODO: enum + fingerprint_algorithm: Option, + base64_certificate: Option, +} + +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct IceServerStat { + url: String, + port: u16, + protocol: Protocol, + total_requests_sent: Option, + total_responses_received: Option, + total_round_trip_time: Option, +} diff --git a/src/signalling/room.rs b/src/signalling/room.rs index 15cee2980..cb60b3678 100644 --- a/src/signalling/room.rs +++ b/src/signalling/room.rs @@ -58,6 +58,7 @@ use crate::{ utils::ResponseActAnyFuture, AppContext, }; +use medea_client_api_proto::stats::RtcStatsType; /// Ergonomic type alias for using [`ActorFuture`] for [`Room`]. pub type ActFuture = Box>; @@ -768,6 +769,7 @@ impl Room { | MakeSdpAnswer { peer_id, .. } | SetIceCandidate { peer_id, .. } | AddPeerConnectionMetrics { peer_id, .. } + | AddPeerConnectionStats { peer_id, .. } | UpdateTracks { peer_id, .. } => peer_id, }; @@ -1004,6 +1006,15 @@ impl CommandHandler for Room { Ok(Box::new(actix::fut::ok(()))) } } + + fn on_add_peer_connection_stats( + &mut self, + peer_id: PeerId, + stats: Vec, + ) -> Self::Output { + println!("{:#?}", stats); + Ok(Box::new(actix::fut::ok(()))) + } } /// [`Actor`] implementation that provides an ergonomic way From 822e861ba8cf499e8561a77877d914139dc4043a Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Wed, 4 Mar 2020 15:16:37 +0300 Subject: [PATCH 066/224] Extend docs, and reduce Options count --- proto/client-api/src/stats.rs | 567 ++++++++++++++++++++++++++++------ 1 file changed, 474 insertions(+), 93 deletions(-) diff --git a/proto/client-api/src/stats.rs b/proto/client-api/src/stats.rs index e24451313..198a13eb1 100644 --- a/proto/client-api/src/stats.rs +++ b/proto/client-api/src/stats.rs @@ -17,6 +17,13 @@ use serde::{Deserialize, Serialize}; use std::{collections::HashMap, time::Duration}; +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[serde(untagged)] +pub enum NonExhaustive { + Known(T), + Unknown(String), +} + #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] pub struct RtcStat { id: String, @@ -30,27 +37,121 @@ pub struct RtcStat { #[serde(tag = "type")] #[serde(rename_all = "kebab-case")] pub enum KnownRtcStatsType { - Codec(RtcStat), + /// Statistics for a codec that is currently being used by RTP streams + /// being sent or received by this `RTCPeerConnection` object. It is + /// accessed by the [`RtcCodecStats`]. + Codec(RtcStat), + + /// Statistics for an inbound RTP stream that is currently received with + /// this RTCPeerConnection object. It is accessed by the + /// [`RtcInboundRtpStreamStats`]. InboundRtp(RtcStat), - OutboundRtp(RtcStat), + + /// Statistics for an outbound RTP stream that is currently sent with this + /// `RTCPeerConnection` object. It is accessed by the + /// [`RtcOutboundRtpStreamStats`]. + /// + /// When there are multiple RTP streams connected to the same sender, such + /// as when using simulcast or RTX, there will be one + /// [`RtcOutboundRtpStreamStats`] per RTP stream, with distinct values of + /// the "ssrc" attribute, and all these senders will have a reference to + /// the same "sender" object (of type `RTCAudioSenderStats` or + /// `RTCVideoSenderStats`) and "track" object (of type + /// `RTCSenderAudioTrackAttachmentStats` or + /// `RTCSenderVideoTrackAttachmentStats`). + OutboundRtp(RtcStat), + + /// Statistics for the remote endpoint's inbound RTP stream corresponding + /// to an outbound stream that is currently sent with this + /// `RTCPeerConnection` object. It is measured at the remote endpoint and + /// reported in an RTCP Receiver Report (RR) or RTCP Extended Report (XR). RemoteInboundRtp(RtcStat), + + /// Statistics for the remote endpoint's outbound RTP stream corresponding + /// to an inbound stream that is currently received with this + /// `RTCPeerConnection` object. It is measured at the remote endpoint and + /// reported in an RTCP Sender Report (SR). RemoteOutboundRtp(RtcStat), + + /// Statistics for the media produced by a `MediaStreamTrack`that is + /// currently attached to an `RTCRtpSender`. This reflects the media that + /// is fed to the encoder; after `getUserMedia()` constraints have been + /// applied (i.e. not the raw media produced by the camera). + MediaSource(RtcStat), + + /// Statistics for a contributing source (CSRC) that contributed to an + /// inbound RTP stream. Csrc(RtcStat), + + /// Statistics related to the `RTCPeerConnection` object. PeerConnection(RtcStat), + + /// Statistics related to each RTCDataChannel id. DataChannel(RtcStat), + + /// This is now obsolete. Contains statistics related to a specific + /// MediaStream. Stream(RtcStat), + + /// Statistics related to a specific MediaStreamTrack's attachment to an + /// RTCRtpSender and the corresponding media-level metrics. Track(RtcStat), - Transceiver(RtcStat), + + /// Statistics related to a specific `RTCRtpTransceiver`. + Transceiver(RtcStat), + + /// Statistics related to a specific `RTCRtpSender` and the corresponding + /// media-level metrics. Sender(RtcStat), + + /// Statistics related to a specific receiver and the corresponding + /// media-level metrics. Receiver(RtcStat), - Transport(RtcStat), - SctpTransport(RtcStat), + + /// Transport statistics related to the `RTCPeerConnection` object. + Transport(RtcStat), + + /// SCTP transport statistics related to an `RTCSctpTransport` object. + SctpTransport(RtcStat), + + /// ICE candidate pair statistics related to the `RTCIceTransport` objects. + /// + /// A candidate pair that is not the current pair for a transport is + /// [deleted] when the `RTCIceTransport` does an ICE restart, at the time + /// the state changes to "new". The candidate pair that is the current + /// pair for a transport is deleted after an ICE restart when the + /// `RTCIceTransport` switches to using a candidate pair generated from + /// the new candidates; this time doesn't correspond to any other + /// externally observable event. + /// + /// [deleted]: https://www.w3.org/TR/webrtc-stats/#dfn-deleted CandidatePair(RtcStat), - LocalCandidate(RtcStat), - RemoteCandidate(RtcStat), - Certificate(RtcStat), - IceServer(RtcStat), - MediaSource(RtcStat), + + /// ICE local candidate statistics related to the `RTCIceTransport` + /// objects. + /// + /// A local candidate is [deleted] when the `RTCIceTransport` does an ICE + /// restart, and the candidate is no longer a member of any non-deleted + /// candidate pair. + /// + /// [deleted]: https://www.w3.org/TR/webrtc-stats/#dfn-deleted + LocalCandidate(RtcStat), + + /// ICE remote candidate statistics related to the `RTCIceTransport` + /// objects. + /// + /// A remote candidate is [deleted] when the `RTCIceTransport` does an ICE + /// restart, and the candidate is no longer a member of any non-deleted + /// candidate pair. + /// + /// [deleted]: https://www.w3.org/TR/webrtc-stats/#dfn-deleted + RemoteCandidate(RtcStat), + + /// Information about a certificate used by an `RTCIceTransport`. + Certificate(RtcStat), + + /// Information about the connection to an ICE server (e.g. STUN or TURN). + IceServer(RtcStat), } #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] @@ -262,23 +363,70 @@ pub struct RemoteInboundRtpStreamStat { round_trip_time_measurements: Option, } +/// An RTCRtpTransceiverStats stats object represents an RTCRtpTransceiver of +/// an RTCPeerConnection. +/// +/// It appears as soon as the monitored RTCRtpTransceiver object is created, +/// such as by invoking addTransceiver, addTrack or setRemoteDescription. +/// RTCRtpTransceiverStats objects can only be deleted if the corresponding +/// RTCRtpTransceiver is removed - this can only happen if a remote description +/// is rolled back. #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] -pub struct RtpTransceiverStat { +pub struct RtcRtpTransceiverStats { + /// The identifier of the stats object representing the RTCRtpSender + /// [associated with the `RTCRtpTransceiver`][1] represented by this stats + /// object. + /// + /// [1]: https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-sender sender_id: Option, + + /// The identifier of the stats object representing the RTCRtpReceiver + /// [associated with the `RTCRtpTransceiver`][1] represented by this stats + /// object. + /// + /// [1]: https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-receiver receiver_id: Option, + + /// If the RTCRtpTransceiver that this stats object represents has a `mid` + /// value that is not null, this is that value, otherwise this value is + /// undefined. mid: Option, } +/// An [`RtcSctpTransportStats`] object represents the stats corresponding to an +/// `RTCSctpTransport`. #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] -pub struct SctpTransport { +pub struct RtcSctpTransportStats { + /// The latest smoothed round-trip time value, corresponding to + /// `spinfo_srtt` defined in [RFC6458] but converted to seconds. If + /// there has been no round-trip time measurements yet, this value is + /// undefined. + /// + /// [RFC6458]: https://www.w3.org/TR/webrtc-stats/#bib-rfc6458 smoothed_round_trip_time: Option, } +/// An [`RtcTransportStats`] object represents the stats corresponding to an +/// [`RTCDtlsTransport`] and its underlying [`RTCIceTransport`]. When RTCP +/// multiplexing is used, one transport is used for both RTP and RTCP. +/// Otherwise, RTP and RTCP will be sent on separate transports, and +/// `rtcpTransportStatsId` can be used to pair the resulting +/// [`RtcTransportStats`] objects. Additionally, when bundling is used, a single +/// transport will be used for all [`MediaStreamTrack`]s in the bundle group. If +/// bundling is not used, different [`MediaStreamTrack`] will use different +/// transports. RTCP multiplexing and bundling are described in [WEBRTC]. +/// +/// [`RTCDtlsTransport`]: +/// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdtlstransport +/// [`RTCIceTransport`]: https://www.w3.org/TR/webrtc-stats/#dfn-rtcicetransport +/// [`MediaStreamTrack`]: +/// https://www.w3.org/TR/webrtc-stats/#dfn-mediastreamtrack +/// [WEBRTC]: https://www.w3.org/TR/webrtc-stats/#bib-webrtc #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] -pub struct TransportStat { +pub struct RtcTransportStats { /// Represents the total number of packets sent over this transport. packets_sent: Option, @@ -301,8 +449,20 @@ pub struct TransportStat { #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] pub enum IceRole { + /// An agent whose role as defined by [ICE], Section 3, has not yet been + /// determined. + /// + /// [ICE]: https://www.w3.org/TR/webrtc/#bib-ice Unknown, + + /// A controlling agent as defined by [ICE], Section 3. + /// + /// [ICE]: https://www.w3.org/TR/webrtc/#bib-ice Controlling, + + /// A controlled agent as defined by [ICE], Section 3. + /// + /// [ICE]: https://www.w3.org/TR/webrtc/#bib-ice Controlled, } @@ -322,37 +482,98 @@ pub enum ReceiverStatsKind { Video {}, } -pub type RtcStatsType = NonExhaustive; +pub type RtcStatsType = KnownRtcStatsType; // https://www.w3.org/TR/webrtc-stats/#candidatepair-dict* #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] pub struct RtcIceCandidatePairStats { state: IceCandidatePairState, + /// Related to updating the nominated flag described in Section 7.1.3.2.4 + /// of [RFC5245]. + /// + /// [RFC5245]: https://www.w3.org/TR/webrtc-stats/#bib-rfc5245 nominated: bool, + + // TODO: check that this field exists. writable: bool, + + /// Represents the total number of payload bytes sent on this candidate + /// pair, i.e., not including headers or padding. bytes_sent: u64, + + /// Represents the total number of payload bytes received on this candidate + /// pair, i.e., not including headers or padding. bytes_received: u64, + + /// Represents the sum of all round trip time measurements in seconds since + /// the beginning of the session, based on STUN connectivity check + /// [STUN-PATH-CHAR] responses (responsesReceived), including those that + /// reply to requests that are sent in order to verify consent [RFC7675]. + /// The average round trip time can be computed from `totalRoundTripTime` + /// by dividing it by `responsesReceived`. + /// + /// [STUN-PATH-CHAR]: https://www.w3.org/TR/webrtc-stats/#bib-stun-path-char + /// [RFC7675]: https://www.w3.org/TR/webrtc-stats/#bib-rfc7675 total_round_trip_time: Option, + + /// Represents the latest round trip time measured in seconds, computed + /// from both STUN connectivity checks [STUN-PATH-CHAR], including those + /// that are sent for consent verification [RFC7675]. + /// + /// [STUN-PATH-CHAR]: https://www.w3.org/TR/webrtc-stats/#bib-stun-path-char + /// [RFC7675]: https://www.w3.org/TR/webrtc-stats/#bib-rfc7675 current_round_trip_time: Option, - available_outgoing_bitrate: Option, -} -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] -#[serde(untagged)] -pub enum NonExhaustive { - Known(T), - Unknown(String), + /// It is calculated by the underlying congestion control by combining the + /// available bitrate for all the outgoing RTP streams using this candidate + /// pair. The bitrate measurement does not count the size of the IP or + /// other transport layers like TCP or UDP. It is similar to the TIAS + /// defined in [RFC3890], i.e., it is measured in bits per second and the + /// bitrate is calculated over a 1 second window. + /// + /// Implementations that do not calculate a sender-side estimate MUST leave + /// this undefined. Additionally, the value MUST be undefined for candidate + /// pairs that were never used. For pairs in use, the estimate is normally + /// no lower than the bitrate for the packets sent at + /// `lastPacketSentTimestamp`, but might be higher. For candidate pairs + /// that are not currently in use but were used before, implementations + /// MUST return undefined. + /// + /// [RFC3890]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3890 + available_outgoing_bitrate: Option, } +/// Each candidate pair in the check list has a foundation and a state. +/// The foundation is the combination of the foundations of the local and +/// remote candidates in the pair. The state is assigned once the check +/// list for each media stream has been computed. There are five +/// potential values that the state can have: #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "kebab-case")] pub enum KnownIceCandidatePairState { - Frozen, + /// A check has not been performed for this pair, and can be + /// performed as soon as it is the highest-priority Waiting pair on + /// the check list. Waiting, + + /// A check has been sent for this pair, but the transaction + /// is in progress. InProgress, - Failed, + + /// A check for this pair was already done and produced a + /// successful result. Succeeded, + + /// A check for this pair was already done and failed, either never + /// producing any response or producing an unrecoverable failure + /// response. + Failed, + + /// A check for this pair hasn't been performed, and it can't + /// yet be performed until some other check succeeds, allowing this + /// pair to unfreeze and move into the Waiting state. + Frozen, } pub type IceCandidatePairState = NonExhaustive; @@ -366,11 +587,32 @@ pub enum KnownProtocol { pub type Protocol = NonExhaustive; +/// The `RTCIceCandidateType` represents the type of the ICE candidate, as +/// defined in [ICE] section 15.1. +/// +/// [ICE]: https://www.w3.org/TR/webrtc/#bib-ice #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "lowercase")] pub enum KnownCandidateType { - Prflx, + /// A host candidate, as defined in Section 4.1.1.1 of [ICE]. + /// + /// [ICE]: https://www.w3.org/TR/webrtc/#bib-ice Host, + + /// A server reflexive candidate, as defined in Section 4.1.1.2 of [ICE]. + /// + /// [ICE]: https://www.w3.org/TR/webrtc/#bib-ice + Srlfx, + + /// A peer reflexive candidate, as defined in Section 4.1.1.2 of [ICE]. + /// + /// [ICE]: https://www.w3.org/TR/webrtc/#bib-ice + Prflx, + + /// A relay candidate, as defined in Section 7.1.3.2.1 of [ICE]. + /// + /// [ICE]: https://www.w3.org/TR/webrtc/#bib-ice + Relay, } pub type CandidateType = NonExhaustive; @@ -389,127 +631,226 @@ pub type MediaType = NonExhaustive; #[serde(tag = "mediaType")] pub enum RtcInboundRtpStreamMediaType { Audio { + /// Whether the last RTP packet whose frame was delivered to the + /// `RTCRtpReceiver`'s `MediaStreamTrack` for playout contained voice + /// activity or not based on the presence of the V bit in the extension + /// header, as defined in [RFC6464]. + /// + /// [RFC6464]: https://www.w3.org/TR/webrtc-stats/#bib-rfc6464 voice_activity_flag: Option, + + /// The total number of samples that have been received on this RTP + /// stream. This includes `concealedSamples`. total_samples_received: Option, + + /// The total number of samples that are concealed samples. A concealed + /// sample is a sample that was replaced with synthesized samples + /// generated locally before being played out. Examples of samples that + /// have to be concealed are samples from lost packets (reported in + /// `packetsLost`) or samples from packets that arrive too late to be + /// played out (reported in `packetsDiscarded`). concealed_samples: Option, + + /// The total number of concealed samples inserted that are "silent". + /// Playing out silent samples results in silence or comfort noise. + /// This is a subset of `concealedSamples`. silent_concealed_samples: Option, + + /// Represents the audio level of the receiving track. audio_level: Option, + + /// Represents the audio energy of the receiving track. total_audio_energy: Option, + + /// Represents the audio duration of the receiving track. For audio + /// durations of tracks attached locally, see RTCAudioSourceStats + /// instead. total_samples_duration: Option, }, Video { + /// It represents the total number of frames correctly decoded for this + /// RTP stream, i.e., frames that would be displayed if no frames are + /// dropped. frames_decoded: Option, + + /// It represents the total number of key frames, such as key frames in + /// VP8 [RFC6386] or IDR-frames in H.264 [RFC6184], successfully + /// decoded for this RTP media stream. This is a subset of + /// framesDecoded. `framesDecoded - keyFramesDecoded` gives you the + /// number of delta frames decoded. + /// + /// [RFC6385]: https://www.w3.org/TR/webrtc-stats/#bib-rfc6386 + /// [RFC6184]: https://www.w3.org/TR/webrtc-stats/#bib-rfc6184 key_frames_decoded: Option, + + /// Represents the width of the last decoded frame. Before the first + /// frame is decoded this attribute is missing. frame_width: Option, + + /// Represents the height of the last decoded frame. Before the first + /// frame is decoded this attribute is missing. frame_height: Option, + + /// Sum of the interframe delays in seconds between consecutively + /// decoded frames, recorded just after a frame has been decoded. total_inter_frame_delay: Option, + + /// The number of decoded frames in the last second. #[serde(rename = "framesPerSecond")] fps: Option, + + /// Represents the bit depth per pixel of the last decoded frame. + /// Typical values are 24, 30, or 36 bits. Before the first frame is + /// decoded this attribute is missing. frame_bit_depth: Option, + + /// Count the total number of Full Intra Request (FIR) packets sent by + /// this receiver. fir_count: Option, + + /// Count the total number of Picture Loss Indication (PLI) packets + /// sent by this receiver. pli_count: Option, + + /// Count the total number of Slice Loss Indication (SLI) packets sent + /// by this receiver. sli_count: Option, + + /// The number of concealment events. This counter increases every + /// time a concealed sample is synthesized after a non-concealed + /// sample. That is, multiple consecutive concealed samples will + /// increase the `concealedSamples` count multiple times but is a + /// single concealment event. concealment_events: Option, + + /// Represents the total number of complete frames received on this RTP + /// stream. This metric is incremented when the complete frame is + /// received. Represents the total number of complete frames received + /// on this RTP stream. This metric is incremented when the complete + /// frame is received. frames_received: Option, }, } -// https://www.w3.org/TR/webrtc-stats/#inboundrtpstats-dict* +/// The [`RtcInboundRtpStreamStats`] dictionary represents the measurement +/// metrics for the incoming RTP media stream. The timestamp reported in the +/// statistics object is the time at which the data was sampled. +/// +/// [W3C doc]: https://www.w3.org/TR/webrtc-stats/#inboundrtpstats-dict* #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] pub struct RtcInboundRtpStreamStats { + /// The identifier of the stats object representing the receiving track. track_id: Option, + + // TODO: docs #[serde(flatten)] media_type: RtcInboundRtpStreamMediaType, + + /// Total number of bytes received for this SSRC. bytes_received: Option, + + // TODO: check that this field exists. packets_received: Option, + + // TODO: check that this field exists. packets_lost: Option, + + // TODO: check that this field exists. jitter: Option, + + /// Total number of seconds that have been spent decoding the + /// `framesDecoded` frames of this stream. The average decode time can + /// be calculated by dividing this value with `framesDecoded`. The time + /// it takes to decode one frame is the time passed between feeding the + /// decoder a frame and the decoder returning decoded data for that + /// frame. total_decode_time: Option, + + /// The total number of audio samples or video frames that have come out of + /// the jitter buffer (increasing jitterBufferDelay). jitter_buffer_emitted_count: Option, } #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] pub struct TrackStat { + /// Represents the `id` property of the track. #[serde(rename = "trackIdentifier")] - track_id: Option, + track_id: String, + + /// True if the source is remote, for instance if it is sourced from + /// another host via an RTCPeerConnection. False otherwise. remote_source: Option, + + /// Reflects the "ended" state of the track. ended: Option, + + // TODO: doc detached: Option, + + // TODO: enum, doc kind: Option, + + // TODO: doc media_source_id: Option, - jitter_buffer_delay: Option, - jitter_buffer_emitted_count: Option, - frame_width: Option, - frames_received: Option, - frames_decoded: Option, - frames_dropped: Option, } #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] -pub struct InboundRtpStats { - kind: Option, - media_type: MediaType, - jitter: Option, - nack_count: Option, - packets_loss: Option, - packets_received: Option, - remote_id: Option, - ssrc: Option, - transport_id: Option, -} +pub struct RtcOutboundRtpStreamStats { + /// The identifier of the stats object representing the current track + /// attachment to the sender of this stream. + track_id: Option, -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] -#[serde(rename_all = "camelCase")] -pub struct OutboundRtpStats { - bitrate_mean: Option, - bitrate_std_dev: Option, - bytes_sent: Option, - dropped_frames: Option, - fir_count: Option, - framerate_mean: Option, - framedrate_std_dev: Option, - framed_encoded: Option, - kind: Option, - framed_decoded: Option, - media_type: Option, - nack_count: Option, - packets_sent: Option, - pli_count: Option, - qp_sum: Option, - remote_id: Option, - ssrc: Option, + /// The identifier of the stats object representing the track currently + /// attached to the sender of this stream. + media_source_id: Option, } #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] -pub struct LocalCandidateStat { - network_type: Option, - address: Option, - transport_id: Option, - port: Option, - protocol: Option, - candidate_type: Option, - priority: Option, - url: Option, - relay_protocol: Option, - deleted: Option, -} +pub struct RtcIceCandidateStats { + /// It is a unique identifier that is associated to the object that was + /// inspected to produce the `RTCTransportStats` associated with this + /// candidate. + transport_id: String, -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] -#[serde(rename_all = "camelCase")] -pub struct RemoteCandidateStat { - transport_id: Option, + // TODO: doc, enum network_type: Option, + + /// It is the address of the candidate, allowing for IPv4 addresses, IPv6 + /// addresses, and fully qualified domain names (FQDNs). address: Option, - port: Option, - protocol: Option, - candidate_type: Option, - priority: Option, + + /// It is the port number of the candidate. + port: u16, + + /// Valid values for transport is one of `udp` and `tcp`. + protocol: Protocol, + + // TODO: doc + candidate_type: CandidateType, + + /// Calculated as defined in [RFC5245] section 15.1. + /// + /// [RFC5245]: https://www.w3.org/TR/webrtc-stats/#bib-rfc5245 + priority: u32, + + /// For local candidates this is the URL of the ICE server from which the + /// candidate was obtained. It is the same as the [url surfaced in the + /// `RTCPeerConnectionIceEvent`][1]. + /// + /// `None` for remote candidates. + /// + /// [1]: https://w3c.github.io/webrtc-pc/#rtcpeerconnectioniceevent url: Option, + + /// It is the protocol used by the endpoint to communicate with the TURN + /// server. This is only present for local candidates. relay_protocol: Option, - deleted: Option, + + // TODO: doc + deleted: bool, } #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] @@ -517,14 +858,28 @@ pub struct RemoteCandidateStat { #[serde(tag = "kind")] pub enum MediaSourceKind { Video { + /// The width, in pixels, of the last frame originating from this + /// source. Before a frame has been produced this attribute is missing. width: Option, + + /// The height, in pixels, of the last frame originating from this + /// source. Before a frame has been produced this attribute is missing. height: Option, + + /// The number of frames originating from this source, measured during + /// the last second. For the first second of this object's lifetime + /// this attribute is missing. #[serde(rename = "framesPerSecond")] fps: Option, }, Audio { + /// Represents the audio level of the media source. audio_level: Option, + + /// Represents the audio energy of the media source. total_audio_energy: Option, + + /// Represents the audio duration of the media source. total_samples_duration: Option, }, } @@ -540,30 +895,56 @@ pub struct MediaSourceStat { #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] -pub struct CodecStat { - payload_type: Option, +pub struct RtcCodecStats { + /// Payload type as used in RTP encoding or decoding. + payload_type: u32, + + /// The codec MIME media type/subtype. e.g., video/vp8 or equivalent. // TODO: Parse it as MIME. - mime_type: Option, - clock_rate: Option, + mime_type: String, + + /// Represents the media sampling rate. + clock_rate: u32, } #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] // TODO: Maybe extract this data somehow? -pub struct CertificateStat { - fingerprint: Option, +pub struct RtcCertificateStats { + /// The fingerprint of the certificate. Only use the fingerprint value as + /// defined in Section 5 of [RFC4572]. + /// + /// [RFC4572]: https://www.w3.org/TR/webrtc-stats/#bib-rfc4572 + fingerprint: String, + + /// The hash function used to compute the certificate fingerprint. For + /// instance, "sha-256". // TODO: enum - fingerprint_algorithm: Option, - base64_certificate: Option, + fingerprint_algorithm: String, + + /// The DER-encoded base-64 representation of the certificate. + base64_certificate: String, } #[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] #[serde(rename_all = "camelCase")] -pub struct IceServerStat { +pub struct RtcIceServerStats { + /// The URL of the ICE server (e.g. TURN or STUN server). url: String, + + /// It is the port number used by the client. port: u16, + + /// Valid values for transport is one of udp and tcp. protocol: Protocol, + + /// The total amount of requests that have been sent to this server. total_requests_sent: Option, + + /// The total amount of responses received from this server. total_responses_received: Option, + + /// The sum of RTTs for all requests that have been sent where a response + /// has been received. total_round_trip_time: Option, } From 52b69129b71fd2fd5a77b47303fd9aafae9cb9f4 Mon Sep 17 00:00:00 2001 From: Semen Evdokimov Date: Wed, 4 Mar 2020 17:15:12 +0300 Subject: [PATCH 067/224] Add stats update caching --- jason/src/peer/conn.rs | 1 + jason/src/peer/mod.rs | 32 +++++++- proto/client-api/src/stats.rs | 149 ++++++++++++++++++++-------------- 3 files changed, 118 insertions(+), 64 deletions(-) diff --git a/jason/src/peer/conn.rs b/jason/src/peer/conn.rs index a99a93e08..7f5c837bc 100644 --- a/jason/src/peer/conn.rs +++ b/jason/src/peer/conn.rs @@ -23,6 +23,7 @@ use crate::{ }; use super::ice_server::RtcIceServers; +use std::{collections::hash_map::DefaultHasher, hash::Hash}; /// [RTCIceCandidate][1] representation. /// diff --git a/jason/src/peer/mod.rs b/jason/src/peer/mod.rs index 5d83f5e9c..45ce7c352 100644 --- a/jason/src/peer/mod.rs +++ b/jason/src/peer/mod.rs @@ -50,7 +50,12 @@ pub use self::{ }; pub use crate::peer::stats::RtcStats; use crate::utils::delay_for; -use std::time::Duration; +use medea_client_api_proto::stats::RtcStatsType; +use std::{ + collections::{hash_map::DefaultHasher, HashSet}, + hash::{Hash, Hasher}, + time::Duration, +}; use wasm_bindgen_futures::spawn_local; /// Errors that may occur in [RTCPeerConnection][1]. @@ -181,6 +186,12 @@ pub struct PeerConnection { ice_candidates_buffer: RefCell>, } +fn calculate_hash(t: &T) -> u64 { + let mut s = DefaultHasher::new(); + t.hash(&mut s); + s.finish() +} + impl PeerConnection { /// Creates new [`PeerConnection`]. /// @@ -223,10 +234,29 @@ impl PeerConnection { let id = peer.id; let sender = peer.peer_events_sender.clone(); let peer_clone = peer.peer.clone(); + // TODO: stop this loop on PeerConnection drop. spawn_local(async move { + let mut cache = HashSet::new(); loop { delay_for(Duration::from_secs(5).into()).await; let stats = peer_clone.get_stats().await; + + let stats = RtcStats( + stats + .0 + .into_iter() + .filter(|stat| { + let stat_hash = calculate_hash(stat); + + let is_already_in_cache = + cache.contains(&stat_hash); + cache.insert(stat_hash); + + !is_already_in_cache + }) + .collect(), + ); + let _ = sender.unbounded_send(PeerEvent::StatsUpdate { peer_id: id, stats, diff --git a/proto/client-api/src/stats.rs b/proto/client-api/src/stats.rs index 198a13eb1..17ce2dcc2 100644 --- a/proto/client-api/src/stats.rs +++ b/proto/client-api/src/stats.rs @@ -15,25 +15,29 @@ use std::convert::TryFrom; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, time::Duration}; +use std::{ + collections::HashMap, + hash::{Hash, Hasher}, + time::Duration, +}; -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] #[serde(untagged)] pub enum NonExhaustive { Known(T), Unknown(String), } -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] pub struct RtcStat { id: String, - timestamp: f32, + timestamp: Time, #[serde(flatten)] kind: T, } /// https://www.w3.org/TR/webrtc-stats/#rtctatstype-* -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] #[serde(tag = "type")] #[serde(rename_all = "kebab-case")] pub enum KnownRtcStatsType { @@ -154,7 +158,7 @@ pub enum KnownRtcStatsType { IceServer(RtcStat), } -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] #[serde(rename_all = "camelCase")] pub struct MediaStreamStat { /// `stream.id` property. @@ -165,7 +169,7 @@ pub struct MediaStreamStat { track_ids: Vec, } -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] #[serde(rename_all = "camelCase")] pub struct DataChannelStat { /// The "label" value of the [`RTCDataChannel`] object. @@ -185,7 +189,7 @@ pub struct DataChannelStat { /// [`RTCDataChannel`]: /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel #[serde(rename = "dataChannelIdentifier")] - data_channel_id: Option, + data_channel_id: Option, /// A [stats object reference] for the transport used to carry this /// datachannel. @@ -201,29 +205,29 @@ pub struct DataChannelStat { state: Option, /// Represents the total number of API "message" events sent. - messages_sent: Option, + messages_sent: Option, /// Represents the total number of payload bytes sent on this /// [`RTCDataChannel`], i.e., not including headers or padding. /// /// [`RTCDataChannel`]: /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel - bytes_sent: Option, + bytes_sent: Option, /// Represents the total number of API "message" events received. - messages_received: Option, + messages_received: Option, /// Represents the total number of bytes received on this /// [`RTCDataChannel`], i.e., not including headers or padding. /// /// [`RTCDataChannel`]: /// https://www.w3.org/TR/webrtc-stats/#dfn-rtcdatachannel - bytes_received: Option, + bytes_received: Option, } pub type DataChannelState = NonExhaustive; -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] #[serde(rename_all = "kebab-case")] pub enum KnownDataChannelState { Connecting, @@ -232,32 +236,32 @@ pub enum KnownDataChannelState { Closed, } -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] #[serde(rename_all = "camelCase")] pub struct RtcPeerConnectionStat { /// Represents the number of unique `DataChannel`s that have entered the /// "open" state during their lifetime. - data_channels_opened: Option, + data_channels_opened: Option, /// Represents the number of unique `DataChannel`s that have left the /// "open" state during their lifetime (due to being closed by either /// end or the underlying transport being closed). `DataChannel`s that /// transition from "connecting" to "closing" or "closed" without ever /// being "open" are not counted in this number. - data_channels_closed: Option, + data_channels_closed: Option, /// Represents the number of unique `DataChannel`s returned from a /// successful `createDataChannel()` call on the `RTCPeerConnection`. /// If the underlying data transport is not established, these may be /// in the "connecting" state. - data_channels_requested: Option, + data_channels_requested: Option, /// Represents the number of unique `DataChannel`s signaled in a /// "datachannel" event on the `RTCPeerConnection`. - data_channels_accepted: Option, + data_channels_accepted: Option, } -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] #[serde(rename_all = "camelCase")] pub struct RtpContributingSourceStat { /// The SSRC identifier of the contributing source represented by this @@ -266,7 +270,7 @@ pub struct RtpContributingSourceStat { /// contributed to. /// /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 - contributor_ssrc: Option, + contributor_ssrc: Option, /// The ID of the [`RTCInboundRtpStreamStats`] object representing the /// inbound RTP stream that this contributing source is contributing to. @@ -284,7 +288,7 @@ pub struct RtpContributingSourceStat { /// [`RTCInboundRtpStreamStats.packetsReceived`]: /// https://tinyurl.com/rreuf49 /// [`contributorSsrc`]: https://tinyurl.com/tf8c7j4 - packets_contributed_to: Option, + packets_contributed_to: Option, /// Present if the last received RTP packet that this source contributed to /// contained an [RFC6465] mixer-to-client audio level header extension. @@ -299,10 +303,10 @@ pub struct RtpContributingSourceStat { /// 10^(-rfc6465_level/20)`. /// /// [RFC6465]: https://www.w3.org/TR/webrtc-stats/#bib-rfc6465 - audio_level: Option, + audio_level: Option, } -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] #[serde(rename_all = "camelCase")] pub struct RemoteOutboundRtpStreamStat { /// The `localId` is used for looking up the local @@ -326,10 +330,10 @@ pub struct RemoteOutboundRtpStreamStat { remote_timestamp: Option, /// Represents the total number of RTCP SR blocks sent for this SSRC. - reports_sent: Option, + reports_sent: Option, } -#[derive(Debug, Deserialize, Serialize, PartialEq, Clone)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Clone, Hash)] #[serde(rename_all = "camelCase")] pub struct RemoteInboundRtpStreamStat { /// The `localId` is used for looking up the local @@ -346,21 +350,21 @@ pub struct RemoteInboundRtpStreamStat { /// undefined. /// /// [RFC3550]: https://www.w3.org/TR/webrtc-stats/#bib-rfc3550 - round_trip_time: Option, + round_trip_time: Option