grammers_client/client/client.rs
1// Copyright 2020 - developers of the `grammers` project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::sync::Arc;
10
11use grammers_mtsender::SenderPoolHandle;
12use grammers_session::Session;
13
14pub(crate) struct ClientInner {
15 pub(crate) session: Arc<dyn Session>,
16 pub(crate) api_id: i32,
17 pub(crate) handle: SenderPoolHandle,
18 pub(crate) configuration: ClientConfiguration,
19 pub(crate) auth_copied_to_dcs: tokio::sync::Mutex<Vec<i32>>,
20}
21
22/// Wrapper around [`SenderPool`] to facilitate interaction with Telegram's API.
23///
24/// This structure is the "entry point" of the library, from which you can start using the rest.
25///
26/// This structure owns all the necessary connections to Telegram, and has implementations for the
27/// most basic methods, such as connecting, signing in, or processing network events.
28///
29/// On drop, all state is synchronized to the session. The [`Session`] must be explicitly saved
30/// to disk with its corresponding save method for persistence.
31///
32/// [`SenderPool`]: grammers_mtsender::SenderPool
33/// [`Session`]: grammers_session::Session
34#[derive(Clone)]
35pub struct Client(pub(crate) Arc<ClientInner>);
36
37use std::time::Duration;
38
39/// Configuration that controls the [`Client`] behaviour when making requests.
40pub struct ClientConfiguration {
41 /// The retry policy to use when encountering errors after invoking a request.
42 pub retry_policy: Box<dyn super::RetryPolicy>,
43
44 /// Whether to call [`Session::cache_peer`] on all peer information that
45 /// the high-level methods receive as a response (e.g. [`Client::iter_dialogs`]).
46 ///
47 /// The cached peers are then usable by other methods such as [`Client::resolve_peer`]
48 /// for as long as the same persisted session is used.
49 pub auto_cache_peers: bool,
50}
51
52/// Configuration that controls [`Client::stream_updates`].
53pub struct UpdatesConfiguration {
54 /// Should the client catch-up on updates sent to it while it was offline?
55 ///
56 /// By default, updates sent while the client was offline are ignored.
57 pub catch_up: bool,
58
59 /// How many updates may be buffered by the client at any given time.
60 ///
61 /// Telegram passively sends updates to the client through the open connection, so they must
62 /// be buffered until the application has the capacity to consume them.
63 ///
64 /// Upon reaching this limit, updates will be dropped, and a warning log message will be
65 /// emitted (but not too often, to avoid spamming the log), in order to let the developer
66 /// know that they should either change how they handle updates or increase the limit.
67 ///
68 /// A limit of zero (`Some(0)`) indicates that updates should not be buffered.
69 /// They will be immediately dropped, and no warning will ever be emitted.
70 ///
71 /// A limit of `None` disables the upper bound for the buffer. This is not recommended, as it
72 /// could eventually lead to memory exhaustion. This option will also not emit any warnings.
73 ///
74 /// The default limit, which may change at any time, should be enough for user accounts,
75 /// although bot accounts may need to increase the limit depending on their capacity.
76 ///
77 /// When the limit is `Some`, a buffer to hold that many updates will be pre-allocated.
78 pub update_queue_limit: Option<usize>,
79}
80
81impl Default for ClientConfiguration {
82 /// Returns an instance that with an [`AutoSleep::default`] retry policy,
83 /// where encountered peers are automatically passed to [`Session::cache_peer`].
84 ///
85 /// [`AutoSleep::default`]: super::AutoSleep::default
86 fn default() -> Self {
87 Self {
88 retry_policy: Box::new(super::AutoSleep {
89 threshold: Duration::from_secs(60),
90 io_errors_as_flood_of: Some(Duration::from_secs(1)),
91 }),
92 auto_cache_peers: true,
93 }
94 }
95}
96
97impl Default for UpdatesConfiguration {
98 /// Returns an instance that will not catch up, with a queue limit of 100 updates.
99 fn default() -> Self {
100 Self {
101 catch_up: false,
102 update_queue_limit: Some(100),
103 }
104 }
105}