From cec2a018ff7890f4ebc8a20a1ae3a593b5fec505 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 4 Oct 2023 19:37:18 +0400 Subject: [PATCH 1/4] Use `futures::future::select` instead of `tokio::select!` Pros: less macros, fixes the missing feature issue. Cons: a bit more code because `fututres` is an annoying crate which does not use `either::Either` and provides its own `Either` which does not have `map_either`, or basically anything for that matter. --- crates/teloxide-core/Cargo.toml | 2 +- .../src/adaptors/throttle/worker.rs | 34 ++++++++++++------ crates/teloxide/Cargo.toml | 1 + crates/teloxide/src/dispatching/dispatcher.rs | 35 ++++++++++++++----- 4 files changed, 52 insertions(+), 20 deletions(-) diff --git a/crates/teloxide-core/Cargo.toml b/crates/teloxide-core/Cargo.toml index aebd8a0d..1b6509ac 100644 --- a/crates/teloxide-core/Cargo.toml +++ b/crates/teloxide-core/Cargo.toml @@ -31,7 +31,7 @@ native-tls = ["reqwest/native-tls"] nightly = [] # Throttling bot adaptor -throttle = ["vecrem", "tokio/macros"] +throttle = ["vecrem"] # Trace bot adaptor trace_adaptor = [] diff --git a/crates/teloxide-core/src/adaptors/throttle/worker.rs b/crates/teloxide-core/src/adaptors/throttle/worker.rs index 67e7ecf3..5e1bc116 100644 --- a/crates/teloxide-core/src/adaptors/throttle/worker.rs +++ b/crates/teloxide-core/src/adaptors/throttle/worker.rs @@ -1,8 +1,11 @@ use std::{ collections::{hash_map::Entry, HashMap, VecDeque}, + pin::pin, time::{Duration, Instant}, }; +use either::Either; +use futures::{future, FutureExt as _}; use tokio::sync::{mpsc, mpsc::error::TryRecvError, oneshot::Sender}; use vecrem::VecExt; @@ -129,17 +132,19 @@ pub(super) async fn worker( answer_info(&mut info_rx, &mut limits); loop { - tokio::select! { - freeze_until = freeze_rx.recv() => { - freeze( - &mut freeze_rx, - slow_mode.as_mut(), - &bot, - freeze_until - ) - .await; - }, - () = read_from_rx(&mut rx, &mut queue, &mut rx_is_closed) => break, + let res = future::select( + pin!(freeze_rx.recv()), + pin!(read_from_rx(&mut rx, &mut queue, &mut rx_is_closed)), + ) + .map(either) + .await + .map_either(|l| l.0, |r| r.0); + + match res { + Either::Left(freeze_until) => { + freeze(&mut freeze_rx, slow_mode.as_mut(), &bot, freeze_until).await; + } + Either::Right(()) => break, } } //debug_assert_eq!(queue.capacity(), limits.messages_per_sec_overall as usize); @@ -372,6 +377,13 @@ async fn read_from_rx(rx: &mut mpsc::Receiver, queue: &mut Vec, rx_is_c } } +fn either(x: future::Either) -> Either { + match x { + future::Either::Left(l) => Either::Left(l), + future::Either::Right(r) => Either::Right(r), + } +} + #[cfg(test)] mod tests { #[tokio::test] diff --git a/crates/teloxide/Cargo.toml b/crates/teloxide/Cargo.toml index 77971857..d51e7e34 100644 --- a/crates/teloxide/Cargo.toml +++ b/crates/teloxide/Cargo.toml @@ -94,6 +94,7 @@ futures = "0.3.15" pin-project = "1.0" serde_with_macros = "1.4" aquamarine = "0.1.11" +either = "1.9.0" sqlx = { version = "0.6", optional = true, default-features = false, features = [ "macros", diff --git a/crates/teloxide/src/dispatching/dispatcher.rs b/crates/teloxide/src/dispatching/dispatcher.rs index 07e80cc9..4629c3fe 100644 --- a/crates/teloxide/src/dispatching/dispatcher.rs +++ b/crates/teloxide/src/dispatching/dispatcher.rs @@ -10,7 +10,12 @@ use crate::{ }; use dptree::di::{DependencyMap, DependencySupplier}; -use futures::{future::BoxFuture, stream::FuturesUnordered, StreamExt}; +use either::Either; +use futures::{ + future::{self, BoxFuture}, + stream::FuturesUnordered, + FutureExt as _, StreamExt as _, +}; use tokio_stream::wrappers::ReceiverStream; use std::{ @@ -19,6 +24,7 @@ use std::{ future::Future, hash::Hash, ops::{ControlFlow, Deref}, + pin::pin, sync::{ atomic::{AtomicBool, AtomicU32, Ordering}, Arc, @@ -321,15 +327,22 @@ where loop { self.remove_inactive_workers_if_needed().await; - tokio::select! { - upd = stream.next() => match upd { - None => break, + let res = future::select(stream.next(), pin!(self.state.wait_for_changes())) + .map(either) + .await + .map_either(|l| l.0, |r| r.0); + + match res { + Either::Left(upd) => match upd { Some(upd) => self.process_update(upd, &update_listener_error_handler).await, + None => break, }, - () = self.state.wait_for_changes() => if self.state.is_shutting_down() { - if let Some(token) = stop_token.take() { - log::debug!("Start shutting down dispatching..."); - token.stop(); + Either::Right(()) => { + if self.state.is_shutting_down() { + if let Some(token) = stop_token.take() { + log::debug!("Start shutting down dispatching..."); + token.stop(); + } } } } @@ -578,6 +591,12 @@ async fn handle_update( } } +fn either(x: future::Either) -> Either { + match x { + future::Either::Left(l) => Either::Left(l), + future::Either::Right(r) => Either::Right(r), + } +} #[cfg(test)] mod tests { use std::convert::Infallible; From e5503e6525e58ce8628ead080493ffc4cbbc8f82 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 4 Oct 2023 19:42:18 +0400 Subject: [PATCH 2/4] format cargo tomls --- crates/teloxide-core/Cargo.toml | 30 ++++++++++++++++++++++-------- crates/teloxide/Cargo.toml | 22 +++++++++++++++------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/crates/teloxide-core/Cargo.toml b/crates/teloxide-core/Cargo.toml index 1b6509ac..ab9addb7 100644 --- a/crates/teloxide-core/Cargo.toml +++ b/crates/teloxide-core/Cargo.toml @@ -55,15 +55,19 @@ tokio = { version = "1.12.0", features = ["fs"] } tokio-util = { version = "0.7.0", features = ["codec"] } pin-project = "1.0.12" bytes = "1.0.0" -reqwest = { version = "0.11.10", features = ["json", "stream", "multipart"], default-features = false } +reqwest = { version = "0.11.10", features = [ + "json", + "stream", + "multipart", +], default-features = false } url = { version = "2", features = ["serde"] } log = "0.4" serde = { version = "1.0.114", features = ["derive"] } serde_json = "1.0.55" serde_with_macros = "1.5.2" -uuid = { version = "1.1.0", features = ["v4"] } # for attaching input files - +uuid = { version = "1.1.0", features = ["v4"] } # for attaching input files + derive_more = "0.99.9" mime = "0.3.16" thiserror = "1.0.20" @@ -81,7 +85,12 @@ vecrem = { version = "0.1", optional = true } [dev-dependencies] pretty_env_logger = "0.4" -tokio = { version = "1.8.0", features = ["fs", "macros", "macros", "rt-multi-thread"] } +tokio = { version = "1.8.0", features = [ + "fs", + "macros", + "macros", + "rt-multi-thread", +] } cool_asserts = "2.0.3" xshell = "0.2" @@ -102,9 +111,9 @@ cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"] tag-prefix = "core-" enable-features = ["full"] pre-release-replacements = [ - {file="README.md", search="teloxide-core = \"[^\"]+\"", replace="teloxide-core = \"{{version}}\""}, - {file="src/lib.rs", search="teloxide-core = \"[^\"]+\"", replace="teloxide-core = \"{{version}}\""}, - {file="CHANGELOG.md", search="## unreleased", replace="## unreleased\n\n## {{version}} - {{date}}", exactly=1}, + { file = "README.md", search = "teloxide-core = \"[^\"]+\"", replace = "teloxide-core = \"{{version}}\"" }, + { file = "src/lib.rs", search = "teloxide-core = \"[^\"]+\"", replace = "teloxide-core = \"{{version}}\"" }, + { file = "CHANGELOG.md", search = "## unreleased", replace = "## unreleased\n\n## {{version}} - {{date}}", exactly = 1 }, ] [[example]] @@ -118,4 +127,9 @@ doc-scrape-examples = true [[example]] name = "erased" -required-features = ["tokio/macros", "tokio/rt-multi-thread", "erased", "trace_adaptor"] +required-features = [ + "tokio/macros", + "tokio/rt-multi-thread", + "erased", + "trace_adaptor", +] diff --git a/crates/teloxide/Cargo.toml b/crates/teloxide/Cargo.toml index d51e7e34..59c0fdb7 100644 --- a/crates/teloxide/Cargo.toml +++ b/crates/teloxide/Cargo.toml @@ -4,6 +4,7 @@ version = "0.12.2" description = "An elegant Telegram bots framework for Rust" rust-version.workspace = true + edition.workspace = true license.workspace = true homepage.workspace = true @@ -17,7 +18,7 @@ categories = ["web-programming", "api-bindings", "asynchronous"] [features] -default = ["native-tls", "ctrlc_handler", "teloxide-core/default", "auto-send"] +default = ["native-tls", "ctrlc_handler", "teloxide-core/default", "auto-send"] webhooks = ["rand"] webhooks-axum = ["webhooks", "axum", "tower", "tower-http"] @@ -37,7 +38,9 @@ native-tls = ["teloxide-core/native-tls"] rustls = ["teloxide-core/rustls"] auto-send = ["teloxide-core/auto_send"] throttle = ["teloxide-core/throttle"] -cache-me = ["teloxide-core/cache_me"] # FIXME: why teloxide and core use - _ differently? +cache-me = [ + "teloxide-core/cache_me", +] # FIXME: why teloxide and core use - _ differently? trace-adaptor = ["teloxide-core/trace_adaptor"] erased = ["teloxide-core/erased"] @@ -97,8 +100,8 @@ aquamarine = "0.1.11" either = "1.9.0" sqlx = { version = "0.6", optional = true, default-features = false, features = [ - "macros", - "sqlite", + "macros", + "sqlite", ] } redis = { version = "0.21", features = ["tokio-comp"], optional = true } serde_cbor = { version = "0.11", optional = true } @@ -132,8 +135,8 @@ cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"] tag-prefix = "" enable-features = ["full"] pre-release-replacements = [ - {file="../../README.md", search="teloxide = \\{ version = \"[^\"]+\"", replace="teloxide = { version = \"{{version}}\""}, - {file="../../CHANGELOG.md", search="## unreleased", replace="## unreleased\n\n## {{version}} - {{date}}", exactly=1}, + { file = "../../README.md", search = "teloxide = \\{ version = \"[^\"]+\"", replace = "teloxide = { version = \"{{version}}\"" }, + { file = "../../CHANGELOG.md", search = "## unreleased", replace = "## unreleased\n\n## {{version}} - {{date}}", exactly = 1 }, ] [[test]] @@ -166,7 +169,12 @@ required-features = ["macros", "ctrlc_handler"] [[example]] name = "db_remember" -required-features = ["sqlite-storage", "redis-storage", "bincode-serializer", "macros"] +required-features = [ + "sqlite-storage", + "redis-storage", + "bincode-serializer", + "macros", +] [[example]] name = "dialogue" From fbd5bf66cde766f168308651791a476a599b10a9 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 4 Oct 2023 20:01:46 +0400 Subject: [PATCH 3/4] bump msrv --- .github/workflows/ci.yml | 6 ++++-- CHANGELOG.md | 7 +++++++ Cargo.toml | 2 +- README.md | 2 +- crates/teloxide-core/CHANGELOG.md | 3 ++- crates/teloxide-core/README.md | 2 +- crates/teloxide-core/src/lib.rs | 2 +- crates/teloxide-macros/CHANGELOG.md | 8 +++++--- 8 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f6d1d79..de4ee898 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,9 @@ env: # - **/README.md # - **/src/lib.rs # - down below in a matrix - rust_msrv: 1.65.0 + # - `Cargo.toml` + # - **/CHANGELOG.md + rust_msrv: 1.68.0 CI: 1 @@ -87,7 +89,7 @@ jobs: toolchain: nightly-2023-09-27 features: "--features full nightly" - rust: msrv - toolchain: 1.65.0 + toolchain: 1.68.0 features: "--features full" steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index f0d94026..7dceb57f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## unreleased ### Added + - Add `MessageToCopyNotFound` error to `teloxide::errors::ApiError` ([PR 917](https://github.com/teloxide/teloxide/pull/917)) + ### Fixed + - Use `UserId` instead of `i64` for `user_id` in `html::user_mention` and `markdown::user_mention` ([PR 896](https://github.com/teloxide/teloxide/pull/896)) - Greatly improved the speed of graceful shutdown (`^C`) ([PR 938](https://github.com/teloxide/teloxide/pull/938)) +### Changed + +- MSRV (Minimal Supported Rust Version) was bumped from `1.64.0` to `1.68.0` ([PR 950][https://github.com/teloxide/teloxide/pull/950]) + ### Removed - `UpdateListener::timeout_hint` and related APIs ([PR 938](https://github.com/teloxide/teloxide/pull/938)) diff --git a/Cargo.toml b/Cargo.toml index 1c176a1f..803ed545 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ resolver = "2" # The settings below will be applied to all crates in the workspace [workspace.package] # MSRV (minimal supported Rust version). -rust-version = "1.65" +rust-version = "1.68" edition = "2021" license = "MIT" diff --git a/README.md b/README.md index b8598615..45153b31 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ $ set TELOXIDE_TOKEN= $ $env:TELOXIDE_TOKEN= ``` - 4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.65): + 4. Make sure that your Rust compiler is up to date (`teloxide` currently requires rustc at least version 1.68): ```bash # If you're using stable $ rustup update stable diff --git a/crates/teloxide-core/CHANGELOG.md b/crates/teloxide-core/CHANGELOG.md index 001f12c0..085e5995 100644 --- a/crates/teloxide-core/CHANGELOG.md +++ b/crates/teloxide-core/CHANGELOG.md @@ -54,7 +54,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `CallbackGame`, `ForumTopicClosed`, `ForumTopicReopened`, `GeneralForumTopicHidden`, `GeneralForumTopicUnhidden` and `WriteAccessAllowed` structures are now defined as named (`struct S {}`) instead of unit (`struct S;`) in order to fix their deserialization ([#876][pr876]) - `Download` now uses GAT feature on the `Fut` and `Err` associated types, instead of a lifetime on the whole trait ([#885][pr885]) -- MSRV (Minimal Supported Rust Version) was bumped from `1.64.0` to `1.65.0` - Renamed `ForumTopic::message_thread_id` into `thread_id` ([#887][pr887]) - `ForumTopic::thread_id` and `Message::thread_id` now use `ThreadId` instead of `i32` ([#887][pr887]) - `message_thread_id` method parameters now use `ThreadId` instead of `i32` ([#887][pr887]) @@ -67,12 +66,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Use `u32` for sizes and `Seconds` for timespans in `InlineQueryResult*` ([#887][pr887]) - `SendGame::reply_to_message_id`, `SendSticker::reply_to_message_id` and `SendInvoice::reply_to_message_id` now use `MessageId` instead of `i32` ([#887][pr887]) - Use `UpdateId` for `Update::id` ([#892][pr892]) +- MSRV (Minimal Supported Rust Version) was bumped from `1.64.0` to `1.68.0` ([#950][pr950]) [pr852]: https://github.com/teloxide/teloxide/pull/853 [pr859]: https://github.com/teloxide/teloxide/pull/859 [pr876]: https://github.com/teloxide/teloxide/pull/876 [pr885]: https://github.com/teloxide/teloxide/pull/885 [pr892]: https://github.com/teloxide/teloxide/pull/892 +[pr950]: https://github.com/teloxide/teloxide/pull/950 ### Deprecated diff --git a/crates/teloxide-core/README.md b/crates/teloxide-core/README.md index bee0e8f6..d059b7c1 100644 --- a/crates/teloxide-core/README.md +++ b/crates/teloxide-core/README.md @@ -27,7 +27,7 @@ ```toml teloxide-core = "0.9" ``` -_Compiler support: requires rustc 1.65+_. +_Compiler support: requires rustc 1.68+_. [`teloxide`]: https://docs.rs/teloxide [Telegram Bot API]: https://core.telegram.org/bots/api diff --git a/crates/teloxide-core/src/lib.rs b/crates/teloxide-core/src/lib.rs index 0a710774..679a4859 100644 --- a/crates/teloxide-core/src/lib.rs +++ b/crates/teloxide-core/src/lib.rs @@ -7,7 +7,7 @@ //!```toml //! teloxide-core = "0.9" //! ``` -//! _Compiler support: requires rustc 1.65+_. +//! _Compiler support: requires rustc 1.68+_. //! //! ``` //! # async { diff --git a/crates/teloxide-macros/CHANGELOG.md b/crates/teloxide-macros/CHANGELOG.md index 57b65163..e91ac50d 100644 --- a/crates/teloxide-macros/CHANGELOG.md +++ b/crates/teloxide-macros/CHANGELOG.md @@ -9,14 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Now you can use `#[command(command_separator="sep")]` (default is a whitespace character) to set the separator between command and its arguments ([issue #897](https://github.com/teloxide/teloxide/issues/897)) +- Now you can use `/// doc comment` for the command help message ([PR #861](https://github.com/teloxide/teloxide/pull/861)). +- Now you can use `#[command(hide)]` to hide a command from the help message ([PR #862](https://github.com/teloxide/teloxide/pull/862)) ### Fixed - Fix `split` parser for tuple variants with len < 2 ([issue #834](https://github.com/teloxide/teloxide/issues/834)) -### Added -- Now you can use `/// doc comment` for the command help message ([PR #861](https://github.com/teloxide/teloxide/pull/861)). -- Now you can use `#[command(hide)]` to hide a command from the help message ([PR #862](https://github.com/teloxide/teloxide/pull/862)) +### Changed + +- MSRV (Minimal Supported Rust Version) was bumped from `1.64.0` to `1.68.0` ([PR 950][https://github.com/teloxide/teloxide/pull/950]) ### Deprecated From 81b4c248a1bb04de261e648da9b6644fefbb3cfa Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 4 Oct 2023 22:01:56 +0400 Subject: [PATCH 4/4] Silence clippy --- crates/teloxide-core/src/adaptors/throttle/worker.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/teloxide-core/src/adaptors/throttle/worker.rs b/crates/teloxide-core/src/adaptors/throttle/worker.rs index 5e1bc116..26d08493 100644 --- a/crates/teloxide-core/src/adaptors/throttle/worker.rs +++ b/crates/teloxide-core/src/adaptors/throttle/worker.rs @@ -297,6 +297,8 @@ fn answer_info(rx: &mut mpsc::Receiver, limits: &mut Limits) { } } +// FIXME: https://github.com/rust-lang/rust-clippy/issues/11610 +#[allow(clippy::needless_pass_by_ref_mut)] async fn freeze( rx: &mut mpsc::Receiver, mut slow_mode: Option<&mut HashMap>,