mirror of
https://github.com/teloxide/teloxide.git
synced 2025-01-24 09:16:12 +01:00
Cleanup update_listeners
docs
This commit is contained in:
parent
818a493a4a
commit
755ec44aea
4 changed files with 106 additions and 109 deletions
|
@ -87,6 +87,7 @@ redis = { version = "0.20", features = ["tokio-comp"], optional = true }
|
||||||
serde_cbor = { version = "0.11", optional = true }
|
serde_cbor = { version = "0.11", optional = true }
|
||||||
bincode = { version = "1.3", optional = true }
|
bincode = { version = "1.3", optional = true }
|
||||||
frunk = { version = "0.4", optional = true }
|
frunk = { version = "0.4", optional = true }
|
||||||
|
aquamarine = "0.1.11"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
smart-default = "0.6.0"
|
smart-default = "0.6.0"
|
||||||
|
|
|
@ -1,107 +1,27 @@
|
||||||
//! Receiving updates from Telegram.
|
//! Receiving updates from Telegram.
|
||||||
//!
|
//!
|
||||||
//! The key trait here is [`UpdateListener`]. You can get it by these functions:
|
//! The key trait here is [`UpdateListener`]. You can get its implementation
|
||||||
|
//! using one these functions:
|
||||||
//!
|
//!
|
||||||
//! - [`polling_default`], which returns a default long polling listener.
|
//! - [`polling_default`], which returns a default long polling listener.
|
||||||
//! - [`polling`], which returns a long/short polling listener with your
|
//! - [`polling`], which returns a long polling listener with your
|
||||||
//! configuration.
|
//! configuration.
|
||||||
//!
|
//!
|
||||||
//! And then you can extract updates from it and pass them directly to a
|
//! And then you can extract updates from it or pass them directly to a
|
||||||
//! dispatcher.
|
//! [`Dispatcher`].
|
||||||
//!
|
//!
|
||||||
//! Telegram supports two ways of [getting updates]: [long]/[short] polling and
|
//! Telegram supports two ways of [getting updates]: [long polling] and
|
||||||
//! [webhook].
|
//! [webhooks]. Currently, only the former one is implemented (see [`polling()`]
|
||||||
//!
|
//! and [`polling_default`]). See also [README FAQ about webhooks](https://github.com/teloxide/teloxide/blob/master/README.md#faq).
|
||||||
//! # Long Polling
|
|
||||||
//!
|
|
||||||
//! In long polling, you just call [`Box::get_updates`] every N seconds.
|
|
||||||
//!
|
|
||||||
//! ## Example
|
|
||||||
//!
|
|
||||||
//! <pre>
|
|
||||||
//! tg bot
|
|
||||||
//! | |
|
|
||||||
//! |<---------------------------| Updates? (Bot::get_updates call)
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | timeout<a id="1b" href="#1">^1</a> |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! Nope |--------------------------->|
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | delay between Bot::get_updates<a id="2b" href="#2">^2</a> |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! |<---------------------------| Updates?
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | timeout<a id="3b" href="#3">^3</a> |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! Yes |-------[updates 0, 1]------>|
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | delay |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! |<-------[offset = 1]--------| Updates?<a id="4b" href="#4">^4</a>
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | timeout |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! Yes |---------[update 2]-------->|
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | delay |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! |<-------[offset = 2]--------| Updates?
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | timeout |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! Nope |--------------------------->|
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | delay |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! |<-------[offset = 2]--------| Updates?
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | timeout |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! Nope |--------------------------->|
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | delay |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! |<-------[offset = 2]--------| Updates?
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | timeout |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! Yes |-------[updates 2..5]------>|
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | delay |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! |<-------[offset = 5]--------| Updates?
|
|
||||||
//! ↑ ↑
|
|
||||||
//! | timeout |
|
|
||||||
//! ↓ ↓
|
|
||||||
//! Nope |--------------------------->|
|
|
||||||
//! | |
|
|
||||||
//! ~ and so on, and so on ~
|
|
||||||
//! </pre>
|
|
||||||
//!
|
|
||||||
//! <a id="1" href="#1b">^1</a> A timeout can be even 0
|
|
||||||
//! (this is also called short polling),
|
|
||||||
//! but you should use it **only** for testing purposes.
|
|
||||||
//!
|
|
||||||
//! <a id="2" href="#2b">^2</a> Large delays will cause in bot lags,
|
|
||||||
//! so delay shouldn't exceed second.
|
|
||||||
//!
|
|
||||||
//! <a id="3" href="#3b">^3</a> Note that if Telegram already have updates for
|
|
||||||
//! you it will answer you **without** waiting for a timeout.
|
|
||||||
//!
|
|
||||||
//! <a id="4" href="#4b">^4</a> `offset = N` means that we've already received
|
|
||||||
//! updates `0..=N`.
|
|
||||||
//!
|
|
||||||
//! # Webhooks
|
|
||||||
//! See the [README FAQ about webhooks](https://github.com/teloxide/teloxide/blob/master/README.md#faq).
|
|
||||||
//!
|
//!
|
||||||
//! [`UpdateListener`]: UpdateListener
|
//! [`UpdateListener`]: UpdateListener
|
||||||
//! [`polling_default`]: polling_default
|
//! [`polling_default`]: polling_default
|
||||||
//! [`polling`]: polling()
|
//! [`polling`]: polling()
|
||||||
|
//! [`Dispatcher`]: crate::dispatching::Dispatcher
|
||||||
//! [`Box::get_updates`]: crate::requests::Requester::get_updates
|
//! [`Box::get_updates`]: crate::requests::Requester::get_updates
|
||||||
//! [getting updates]: https://core.telegram.org/bots/api#getting-updates
|
//! [getting updates]: https://core.telegram.org/bots/api#getting-updates
|
||||||
//! [long]: https://en.wikipedia.org/wiki/Push_technology#Long_polling
|
//! [long polling]: https://en.wikipedia.org/wiki/Push_technology#Long_polling
|
||||||
//! [short]: https://en.wikipedia.org/wiki/Polling_(computer_science)
|
//! [webhooks]: https://en.wikipedia.org/wiki/Webhook
|
||||||
//! [webhook]: https://en.wikipedia.org/wiki/Webhook
|
|
||||||
|
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
|
|
||||||
|
@ -122,19 +42,15 @@ pub use self::{
|
||||||
|
|
||||||
/// An update listener.
|
/// An update listener.
|
||||||
///
|
///
|
||||||
/// Implementors of this trait allow getting updates from Telegram.
|
/// Implementors of this trait allow getting updates from Telegram. See
|
||||||
///
|
/// [module-level documentation] for more.
|
||||||
/// Currently Telegram has 2 ways of getting updates -- [polling] and
|
|
||||||
/// [webhooks]. Currently, only the former one is implemented (see [`polling()`]
|
|
||||||
/// and [`polling_default`])
|
|
||||||
///
|
///
|
||||||
/// Some functions of this trait are located in the supertrait
|
/// Some functions of this trait are located in the supertrait
|
||||||
/// ([`AsUpdateStream`]), see also:
|
/// ([`AsUpdateStream`]), see also:
|
||||||
/// - [`AsUpdateStream::Stream`]
|
/// - [`AsUpdateStream::Stream`]
|
||||||
/// - [`AsUpdateStream::as_stream`]
|
/// - [`AsUpdateStream::as_stream`]
|
||||||
///
|
///
|
||||||
/// [polling]: self#long-polling
|
/// [module-level documentation]: mod@self
|
||||||
/// [webhooks]: self#webhooks
|
|
||||||
pub trait UpdateListener<E>: for<'a> AsUpdateStream<'a, E> {
|
pub trait UpdateListener<E>: for<'a> AsUpdateStream<'a, E> {
|
||||||
/// The type of token which allows to stop this listener.
|
/// The type of token which allows to stop this listener.
|
||||||
type StopToken: StopToken;
|
type StopToken: StopToken;
|
||||||
|
@ -150,8 +66,8 @@ pub trait UpdateListener<E>: for<'a> AsUpdateStream<'a, E> {
|
||||||
/// Implementors of this function are encouraged to stop listening for
|
/// Implementors of this function are encouraged to stop listening for
|
||||||
/// updates as soon as possible and return `None` from the update stream as
|
/// updates as soon as possible and return `None` from the update stream as
|
||||||
/// soon as all cached updates are returned.
|
/// soon as all cached updates are returned.
|
||||||
#[must_use = "This function doesn't stop listening, to stop listening you need to call stop on \
|
#[must_use = "This function doesn't stop listening, to stop listening you need to call `stop` \
|
||||||
the returned token"]
|
on the returned token"]
|
||||||
fn stop_token(&mut self) -> Self::StopToken;
|
fn stop_token(&mut self) -> Self::StopToken;
|
||||||
|
|
||||||
/// Hint which updates should the listener listen for.
|
/// Hint which updates should the listener listen for.
|
||||||
|
|
|
@ -31,20 +31,99 @@ where
|
||||||
polling(requester, Some(Duration::from_secs(10)), None, None)
|
polling(requester, Some(Duration::from_secs(10)), None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a long/short polling update listener with some additional options.
|
#[cfg_attr(doc, aquamarine::aquamarine)]
|
||||||
|
/// Returns a long polling update listener with some additional options.
|
||||||
///
|
///
|
||||||
/// - `bot`: Using this bot, the returned update listener will receive updates.
|
/// - `bot`: Using this bot, the returned update listener will receive updates.
|
||||||
/// - `timeout`: A timeout for polling.
|
/// - `timeout`: A timeout in seconds for polling.
|
||||||
/// - `limit`: Limits the number of updates to be retrieved at once. Values
|
/// - `limit`: Limits the number of updates to be retrieved at once. Values
|
||||||
/// between 1—100 are accepted.
|
/// between 1—100 are accepted.
|
||||||
/// - `allowed_updates`: A list the types of updates you want to receive.
|
/// - `allowed_updates`: A list the types of updates you want to receive.
|
||||||
|
///
|
||||||
/// See [`GetUpdates`] for defaults.
|
/// See [`GetUpdates`] for defaults.
|
||||||
///
|
///
|
||||||
/// See also: [`polling_default`](polling_default).
|
/// See also: [`polling_default`](polling_default).
|
||||||
///
|
///
|
||||||
/// [`GetUpdates`]: crate::payloads::GetUpdates
|
/// ## Notes
|
||||||
|
///
|
||||||
|
/// - `timeout` should not be bigger than http client timeout, see
|
||||||
|
/// [`default_reqwest_settings`] for default http client settings.
|
||||||
|
/// - [`repl`]s and [`Dispatcher`] use [`hint_allowed_updates`] to set
|
||||||
|
/// `allowed_updates`, so you rarely need to pass `allowed_updates`
|
||||||
|
/// explicitly.
|
||||||
|
///
|
||||||
|
/// [`default_reqwest_settings`]: teloxide::net::default_reqwest_settings
|
||||||
|
/// [`repl`]: fn@crate::repl
|
||||||
|
/// [`Dispatcher`]: crate::dispatching::Dispatcher
|
||||||
|
/// [`hint_allowed_updates`]: crate::dispatching::update_listeners::UpdateListener::hint_allowed_updates
|
||||||
|
///
|
||||||
|
/// ## How it works
|
||||||
|
///
|
||||||
|
/// Long polling works by repeatedly calling [`Bot::get_updates`][get_updates].
|
||||||
|
/// If telegram has any updates, it returns them immediately, otherwise it waits
|
||||||
|
/// until either it has any updates or `timeout` expires.
|
||||||
|
///
|
||||||
|
/// Each [`get_updates`][get_updates] call includes an `offset` parameter equal
|
||||||
|
/// to the latest update id + one, that allows to only receive updates that has
|
||||||
|
/// not been received before.
|
||||||
|
///
|
||||||
|
/// When telegram receives a [`get_updates`][get_updates] request with `offset =
|
||||||
|
/// N` it forgets any updates with id < `N`. When `polling` listener is stopped,
|
||||||
|
/// it sends [`get_updates`][get_updates] with `timeout = 0, limit = 1` and
|
||||||
|
/// appropriate `offset`, so future bot restarts won't see updates that were
|
||||||
|
/// already seen.
|
||||||
|
///
|
||||||
|
/// Consumers of a `polling` update listener then need to repeatedly call
|
||||||
|
/// [`futures::StreamExt::next`] to get the updates.
|
||||||
|
///
|
||||||
|
/// Here is an example diagram that shows these interactions between consumers
|
||||||
|
/// like [`Dispatcher`], `polling` update listener and telegram.
|
||||||
|
///
|
||||||
|
/// ```mermaid
|
||||||
|
/// sequenceDiagram
|
||||||
|
/// participant C as Consumer
|
||||||
|
/// participant P as polling
|
||||||
|
/// participant T as Telegram
|
||||||
|
///
|
||||||
|
/// link C: Dispatcher @ ../struct.Dispatcher.html
|
||||||
|
/// link C: repl @ ../../fn.repl.html
|
||||||
|
///
|
||||||
|
/// C->>P: next
|
||||||
|
///
|
||||||
|
/// P->>+T: Updates? (offset = 0)
|
||||||
|
/// Note right of T: timeout
|
||||||
|
/// T->>-P: None
|
||||||
|
///
|
||||||
|
/// P->>+T: Updates? (offset = 0)
|
||||||
|
/// Note right of T: <= timeout
|
||||||
|
/// T->>-P: updates with ids [3, 4]
|
||||||
|
///
|
||||||
|
/// P->>C: update(3)
|
||||||
|
///
|
||||||
|
/// C->>P: next
|
||||||
|
/// P->>C: update(4)
|
||||||
|
///
|
||||||
|
/// C->>P: next
|
||||||
|
///
|
||||||
|
/// P->>+T: Updates? (offset = 5)
|
||||||
|
/// Note right of T: <= timeout
|
||||||
|
/// T->>-P: updates with ids [5]
|
||||||
|
///
|
||||||
|
/// C->>P: stop signal
|
||||||
|
///
|
||||||
|
/// P->>C: update(5)
|
||||||
|
///
|
||||||
|
/// C->>P: next
|
||||||
|
///
|
||||||
|
/// P->>T: *Acknolegment of update(5)*
|
||||||
|
/// T->>P: ok
|
||||||
|
///
|
||||||
|
/// P->>C: None
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [get_updates]: crate::requests::Requester::get_updates
|
||||||
pub fn polling<R>(
|
pub fn polling<R>(
|
||||||
requester: R,
|
bot: R,
|
||||||
timeout: Option<Duration>,
|
timeout: Option<Duration>,
|
||||||
limit: Option<u8>,
|
limit: Option<u8>,
|
||||||
allowed_updates: Option<Vec<AllowedUpdate>>,
|
allowed_updates: Option<Vec<AllowedUpdate>>,
|
||||||
|
@ -119,7 +198,7 @@ where
|
||||||
let (token, flag) = AsyncStopToken::new_pair();
|
let (token, flag) = AsyncStopToken::new_pair();
|
||||||
|
|
||||||
let state = State {
|
let state = State {
|
||||||
bot: requester,
|
bot,
|
||||||
timeout: timeout.map(|t| t.as_secs().try_into().expect("timeout is too big")),
|
timeout: timeout.map(|t| t.as_secs().try_into().expect("timeout is too big")),
|
||||||
limit,
|
limit,
|
||||||
allowed_updates,
|
allowed_updates,
|
||||||
|
|
|
@ -44,8 +44,6 @@
|
||||||
html_logo_url = "https://github.com/teloxide/teloxide/raw/master/ICON.png",
|
html_logo_url = "https://github.com/teloxide/teloxide/raw/master/ICON.png",
|
||||||
html_favicon_url = "https://github.com/teloxide/teloxide/raw/master/ICON.png"
|
html_favicon_url = "https://github.com/teloxide/teloxide/raw/master/ICON.png"
|
||||||
)]
|
)]
|
||||||
#![allow(clippy::match_bool)]
|
|
||||||
#![forbid(unsafe_code)]
|
|
||||||
// We pass "--cfg docsrs" when building docs to add `This is supported on
|
// We pass "--cfg docsrs" when building docs to add `This is supported on
|
||||||
// feature="..." only.`
|
// feature="..." only.`
|
||||||
//
|
//
|
||||||
|
@ -56,6 +54,9 @@
|
||||||
// $ RUSTFLAGS="--cfg dep_docsrs" RUSTDOCFLAGS="--cfg docsrs -Znormalize-docs" cargo +nightly doc --open --all-features
|
// $ RUSTFLAGS="--cfg dep_docsrs" RUSTDOCFLAGS="--cfg docsrs -Znormalize-docs" cargo +nightly doc --open --all-features
|
||||||
// ```
|
// ```
|
||||||
#![cfg_attr(all(docsrs, feature = "nightly"), feature(doc_cfg))]
|
#![cfg_attr(all(docsrs, feature = "nightly"), feature(doc_cfg))]
|
||||||
|
#![forbid(unsafe_code)]
|
||||||
|
#![warn(rustdoc::broken_intra_doc_links)]
|
||||||
|
#![allow(clippy::match_bool)]
|
||||||
#![allow(clippy::redundant_pattern_matching)]
|
#![allow(clippy::redundant_pattern_matching)]
|
||||||
// https://github.com/rust-lang/rust-clippy/issues/7422
|
// https://github.com/rust-lang/rust-clippy/issues/7422
|
||||||
#![allow(clippy::nonstandard_macro_braces)]
|
#![allow(clippy::nonstandard_macro_braces)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue