From 7fd2233098578294e2259665afbc4e513cd9a8a5 Mon Sep 17 00:00:00 2001 From: Geoffrey Allott Date: Sat, 6 Mar 2021 22:24:02 +0000 Subject: [PATCH] implement command line and config parsing --- Cargo.lock | 241 +++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 +- pokerwave.toml | 12 +++ src/config.rs | 75 +++++++++++++++ src/dealer.rs | 56 +++++++++++- src/main.rs | 126 +++++++++++++++++++------- src/pubsub.rs | 6 +- 7 files changed, 478 insertions(+), 42 deletions(-) create mode 100644 pokerwave.toml create mode 100644 src/config.rs diff --git a/Cargo.lock b/Cargo.lock index e575ad0..37301c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,6 +63,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" version = "1.0.38" @@ -186,6 +195,18 @@ dependencies = [ "event-listener", ] +[[package]] +name = "async-native-tls" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33" +dependencies = [ + "async-std", + "native-tls", + "thiserror", + "url", +] + [[package]] name = "async-process" version = "1.0.2" @@ -329,6 +350,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + [[package]] name = "block-buffer" version = "0.9.0" @@ -419,6 +446,21 @@ dependencies = [ "generic-array", ] +[[package]] +name = "clap" +version = "2.33.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "combine" version = "4.5.2" @@ -464,6 +506,22 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" + [[package]] name = "cpuid-bool" version = "0.1.2" @@ -615,6 +673,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.0.1" @@ -991,6 +1064,24 @@ version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +[[package]] +name = "native-tls" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nb-connect" version = "1.0.3" @@ -1023,6 +1114,39 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70" +dependencies = [ + "bitflags", + "cfg-if 1.0.0", + "foreign-types", + "lazy_static", + "libc", + "openssl-sys", +] + +[[package]] +name = "openssl-probe" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" + +[[package]] +name = "openssl-sys" +version = "0.9.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking" version = "2.0.0" @@ -1073,11 +1197,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + [[package]] name = "pokerwave" version = "0.1.0" dependencies = [ "async-std", + "clap", "env_logger", "futures", "getrandom 0.2.2", @@ -1096,6 +1227,7 @@ dependencies = [ "tide", "tide-rustls", "tide-websockets", + "toml", ] [[package]] @@ -1245,6 +1377,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eeb8f8d059ead7805e171fc22de8348a3d611c0f985aaa4f5cf6c0dfc7645407" dependencies = [ + "async-native-tls", "async-std", "async-trait", "bytes 1.0.1", @@ -1252,6 +1385,7 @@ dependencies = [ "dtoa", "futures-util", "itoa", + "native-tls", "percent-encoding", "pin-project-lite 0.2.6", "sha1", @@ -1260,6 +1394,15 @@ dependencies = [ "url", ] +[[package]] +name = "redox_syscall" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" version = "1.4.3" @@ -1278,6 +1421,15 @@ version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "ring" version = "0.16.20" @@ -1327,6 +1479,16 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "schannel" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi", +] + [[package]] name = "sct" version = "0.6.0" @@ -1337,6 +1499,29 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfd318104249865096c8da1dfabf09ddbb6d0330ea176812a62ec75e40c4166" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee48cdde5ed250b0d3252818f646e174ab414036edb884dde62d80a3ac6082d" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "0.9.0" @@ -1566,6 +1751,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "subtle" version = "2.4.0" @@ -1589,6 +1780,20 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand 0.8.3", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "termcolor" version = "1.1.2" @@ -1598,6 +1803,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.24" @@ -1759,6 +1973,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + [[package]] name = "tungstenite" version = "0.11.1" @@ -1802,6 +2025,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unicode-xid" version = "0.2.1" @@ -1853,12 +2082,24 @@ dependencies = [ "sval", ] +[[package]] +name = "vcpkg" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" + [[package]] name = "vec-arena" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.2" diff --git a/Cargo.toml b/Cargo.toml index 6b29ef5..37eda43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] async-std = { version = "1", features = ["attributes"] } +clap = "2" env_logger = "0.8" log = "0.4" futures = "0.3" @@ -15,7 +16,7 @@ itertools = "0.10" pin-project = "1.0" rand = "0.8" rand_chacha = "0.3" -redis = { version = "0.20", features = ["async-std-comp"] } +redis = { version = "0.20", features = ["async-std-tls-comp"] } serde = "1" serde_derive = "1" serde_json = "1" @@ -24,3 +25,4 @@ signal-hook-async-std = "0.2" tide = { version = "0.16.0", default-features = false, features = ["h1-server"] } tide-rustls = "0.2" tide-websockets = "0.3" +toml = "0.5" diff --git a/pokerwave.toml b/pokerwave.toml new file mode 100644 index 0000000..c6e98ba --- /dev/null +++ b/pokerwave.toml @@ -0,0 +1,12 @@ +[log] +filter = "info" +style = "auto" + +[redis] +#addr = "redis://pokerwave:59f278cd2a96756d67884976f54c1e490d00cb4f7ff62c24a380680e5f5098a3@localhost/0" + +[server] +bind = ["localhost:4343"] +site = "site" +cert = "cert/cert.pem" +key = "cert/key.pem" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..86604fe --- /dev/null +++ b/src/config.rs @@ -0,0 +1,75 @@ +use std::path::PathBuf; + +#[derive(Clone, Debug, Default, Deserialize)] +pub struct Config { + #[serde(default)] + pub log: LogConfig, + #[serde(default)] + pub redis: RedisConfig, + #[serde(default)] + pub server: ServerConfig, +} + +fn default_filter() -> String { + "warn".to_string() +} + +fn default_style() -> String { + "auto".to_string() +} + +#[derive(Clone, Debug, Deserialize)] +pub struct LogConfig { + #[serde(default = "default_filter")] + pub filter: String, + #[serde(default = "default_style")] + pub style: String, +} + +impl Default for LogConfig { + fn default() -> Self { + Self { filter: default_filter(), style: default_style() } + } +} + +fn default_redis_addr() -> String { + "redis://localhost".to_string() +} + +#[derive(Clone, Debug, Deserialize)] +pub struct RedisConfig { + #[serde(default = "default_redis_addr")] + pub addr: String, +} + +impl Default for RedisConfig { + fn default() -> Self { + Self { addr: default_redis_addr() } + } +} + +fn default_bind_addr() -> Vec { + vec!["localhost:8080".to_string()] +} + +fn default_site_path() -> PathBuf { + PathBuf::from("site") +} + +#[derive(Clone, Debug, Deserialize)] +pub struct ServerConfig { + #[serde(default = "default_bind_addr")] + pub bind: Vec, + #[serde(default = "default_site_path")] + pub site: PathBuf, + #[serde(default)] + pub cert: Option, + #[serde(default)] + pub key: Option, +} + +impl Default for ServerConfig { + fn default() -> Self { + Self { bind: default_bind_addr(), site: default_site_path(), cert: None, key: None } + } +} diff --git a/src/dealer.rs b/src/dealer.rs index e43997e..61ba1ca 100644 --- a/src/dealer.rs +++ b/src/dealer.rs @@ -1,4 +1,6 @@ use std::collections::HashSet; +use std::fmt::{self, Display}; +use std::str::FromStr; use async_std::task::spawn; use futures::{channel::mpsc::Receiver, StreamExt}; @@ -19,6 +21,46 @@ struct DealerState { game: Box, } +#[derive(Copy, Clone, Debug)] +pub struct Partition { + n: i64, + m: i64, +} + +impl Partition { + fn start_dealer_for(&self, id: i64) -> bool { + id.rem_euclid(self.m) == self.n - 1 + } +} + +impl FromStr for Partition { + type Err = String; + fn from_str(str: &str) -> Result { + if let [n, m] = *str.split('/').collect::>() { + match (n.parse::(), m.parse::()) { + (Ok(n), Ok(m)) if n >= 1 && m >= n => Ok(Partition { n, m }), + (Ok(n), Ok(m)) if n < 1 => Err(format!("The partition number N must be >= 1; got {}/{}", n, m)), + (Ok(n), Ok(m)) => Err(format!("The partition number N must be <= total partitions M; got {}/{}", n, m)), + _ => Err(format!("The partition must be expressed as two integers N/M; got {:?}", str)), + } + } else { + Err(format!("The partition must be expressed in the form N/M; got {:?}", str)) + } + } +} + +impl Display for Partition { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}/{}", self.n, self.m) + } +} + +impl Default for Partition { + fn default() -> Self { + Partition { n: 1, m: 1 } + } +} + enum Termination { Continue, Break, @@ -104,7 +146,7 @@ impl Dealer { } } -pub async fn spawn_dealers(server: Server) -> Result<(), std::io::Error> { +pub async fn spawn_dealers(server: Server, partition: Partition) -> Result<(), std::io::Error> { let (mut server_state, mut update_stream) = server.new_state().await; let mut interests = HashSet::new(); interests.insert(ClientInterest::GameList); @@ -118,10 +160,14 @@ pub async fn spawn_dealers(server: Server) -> Result<(), std::io::Error> { info!("Starting new game {:?}", game); let id = game.id(); game_list.push(game); - let (server_state, update_stream) = server.new_state().await; - if let Ok(dealer) = Dealer::new(server_state, id).await { - info!("Spawning new dealer for game {}", id); - spawn(dealer.start(update_stream)); + if partition.start_dealer_for(id) { + let (server_state, update_stream) = server.new_state().await; + if let Ok(dealer) = Dealer::new(server_state, id).await { + info!("Spawning new dealer for game {}", id); + spawn(dealer.start(update_stream)); + } + } else { + debug!("Not spawning new dealer for game {} for partition {}", id, partition); } } } diff --git a/src/main.rs b/src/main.rs index e251ad8..6ddfbc2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,19 +3,28 @@ extern crate log; #[macro_use] extern crate serde_derive; -use futures::{channel::mpsc::channel, future::select, pin_mut, FutureExt, StreamExt}; +use std::fs::read_to_string; +use std::future::Future; +use std::pin::Pin; + +use clap::{app_from_crate, crate_authors, crate_description, crate_name, crate_version, AppSettings, Arg, SubCommand}; +use futures::{channel::mpsc::channel, future::pending, select, FutureExt, StreamExt}; use redis::Client; use signal_hook::consts::signal::*; use signal_hook_async_std::Signals; use tide::utils::After; -use tide::{Body, Error, Response, StatusCode}; -//use tide_rustls::TlsListener; +use tide::{ + listener::{ConcurrentListener, ToListener}, + Body, Response, StatusCode, +}; +use tide_rustls::TlsListener; use tide_websockets::WebSocket; mod api; mod auth; mod card; mod client; +mod config; mod dealer; mod game; mod pubsub; @@ -26,17 +35,17 @@ mod username; mod util; use crate::client::new_client; -use crate::dealer::spawn_dealers; +use crate::config::Config; +use crate::dealer::{spawn_dealers, Partition}; use crate::pubsub::handle_client_interest_subscriptions; use crate::server::Server; -async fn handle_signals(mut signals: Signals) -> Result<(), std::io::Error> { +async fn handle_signals(mut signals: Signals) { signals.next().await; info!("Shutting down..."); - Ok(()) } -async fn serve_404(response: Response) -> Result { +async fn serve_404(response: Response) -> Result { match response.status() { StatusCode::NotFound => Ok(Response::builder(404).body(Body::from_file("site/404.html").await?).content_type("text/html").build()), _ => Ok(response), @@ -44,41 +53,92 @@ async fn serve_404(response: Response) -> Result { } #[async_std::main] -async fn main() -> Result<(), Error> { +async fn main() -> Result<(), tide::Error> { env_logger::init(); + let matches = app_from_crate!() + .arg( + Arg::with_name("config") + .short("c") + .long("config") + .value_name("FILE") + .takes_value(true) + .global(true) + .help("Path to configuration file in TOML format"), + ) + .setting(AppSettings::VersionlessSubcommands) + .subcommand(SubCommand::with_name("server").about("Serve the website and websocket connections")) + .subcommand( + SubCommand::with_name("dealer").about("Start a dealer for each game").arg( + Arg::with_name("partition") + .value_name("N/M") + .default_value("1/1") + .validator(|partition| partition.parse::().map(drop)) + .help("Partition all games into M groups and run dealer N of M"), + ), + ) + .subcommand(SubCommand::with_name("all").about("Serve the website, websocket connections and start a dealer for each game (default)")) + .get_matches(); + let config = match matches.value_of_os("config") { + Some(path) => toml::from_str(&read_to_string(path)?)?, + None => Config::default(), + }; + + let mut run_server = true; + let mut run_dealer = true; + let mut partition = Partition::default(); + + match matches.subcommand() { + ("server", _) => run_dealer = false, + ("dealer", Some(args)) => { + run_server = false; + partition = args.value_of("partition").unwrap().parse().unwrap(); + } + _ => {} + } + + let signals = Signals::new(&[SIGINT])?; + let signal_handler = handle_signals(signals); const REGISTER_UPDATE_STREAM_CHANNEL_BUFFER: usize = 128; let (register_update_stream_tx, register_update_stream_rx) = channel(REGISTER_UPDATE_STREAM_CHANNEL_BUFFER); - let client = Client::open("redis://localhost/")?; + let client = Client::open(config.redis.addr)?; let connection = client.get_multiplexed_async_std_connection().await?; let pubsub = client.get_async_std_connection().await?.into_pubsub(); - let mut app = tide::with_state(Server::new(connection, register_update_stream_tx)); - - app.at("/").serve_dir("site/")?; - app.at("/").serve_file("site/index.html")?; - app.at("/api").get(WebSocket::new(new_client)); - app.with(After(serve_404)); - - let signals = Signals::new(&[SIGINT])?; - let signal_handler = handle_signals(signals); - + let server = Server::new(connection, register_update_stream_tx); let handle_client_interest = handle_client_interest_subscriptions(pubsub, register_update_stream_rx); - let handle_new_games = spawn_dealers(app.state().clone()); - - /*let listener = TlsListener::build() - .addrs("localhost:4433") - .cert("cert/cert.pem") - .key("cert/key.pem"); - - let app = app.listen(listener);*/ - let app = app.listen("0.0.0.0:8080"); - pin_mut!(app, handle_client_interest, handle_new_games, signal_handler); - select(select(app, select(handle_client_interest, handle_new_games).map(|f| f.factor_first().0)).map(|f| f.factor_first().0), signal_handler) - .await - .factor_first() - .0?; + let dealer: Pin>>> = + if run_dealer { Box::pin(spawn_dealers(server.clone(), partition)) } else { Box::pin(pending()) }; + + let server: Pin>>> = if run_server { + let mut app = tide::with_state(server); + + app.at("/").serve_dir(&config.server.site)?; + app.at("/").serve_file(config.server.site.join("index.html"))?; + app.at("/api").get(WebSocket::new(new_client)); + app.with(After(serve_404)); + + let mut listener = ConcurrentListener::new(); + for addrs in config.server.bind { + if let (Some(cert), Some(key)) = (&config.server.cert, &config.server.key) { + listener.add(TlsListener::build().addrs(addrs).cert(&cert).key(&key))?; + } else { + listener.add(addrs.to_listener()?)?; + } + } + + Box::pin(app.listen(listener)) + } else { + Box::pin(pending()) + }; + + select! { + _ = signal_handler.fuse() => {}, + _ = handle_client_interest.fuse() => {}, + server = server.fuse() => server?, + dealer = dealer.fuse() => dealer?, + }; info!("Pokerwave shut down gracefully."); diff --git a/src/pubsub.rs b/src/pubsub.rs index 196d614..342e313 100644 --- a/src/pubsub.rs +++ b/src/pubsub.rs @@ -102,7 +102,7 @@ impl ToRedisArgs for ClientInterest { } } -pub async fn handle_client_interest_subscriptions(mut connection: PubSub, mut new_clients: Receiver) -> Result<(), std::io::Error> { +pub async fn handle_client_interest_subscriptions(mut connection: PubSub, mut new_clients: Receiver) { debug!("handle_client_interest: init"); let mut clients: Vec = Vec::new(); loop { @@ -212,12 +212,12 @@ pub async fn handle_client_interest_subscriptions(mut connection: PubSub, mut ne Action::NoNewClients => { debug!("handle_client_interest: Action::NoNewClients - current clients: {:?}", clients); if clients.is_empty() { - return Ok(()); + return; } } Action::ConnectionClosed => { debug!("handle_client_interest: Action::ConnectionClosed - current clients: {:?}", clients); - return Ok(()); + return; } } } -- 2.34.1