mirror of
https://github.com/teloxide/teloxide.git
synced 2025-03-14 11:44:04 +01:00
Merge pull request #180 from teloxide/payload_timeout_hint
Add a way for long-running requests to increase network timeout
This commit is contained in:
commit
6113bce6e5
6 changed files with 54 additions and 4 deletions
|
@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- `Payload::timeout_hint` method to properly handle long running requests like `GetUpdates` ([#180][pr180])
|
||||
|
||||
[pr180]: https://github.com/teloxide/teloxide-core/pull/180
|
||||
|
||||
## 0.4.1 - 2022-02-13
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -214,6 +214,7 @@ impl Bot {
|
|||
let token = Arc::clone(&self.token);
|
||||
let api_url = Arc::clone(&self.api_url);
|
||||
|
||||
let timeout_hint = payload.timeout_hint();
|
||||
let params = serde_json::to_vec(payload)
|
||||
// this `expect` should be ok since we don't write request those may trigger error here
|
||||
.expect("serialization of request to be infallible");
|
||||
|
@ -226,6 +227,7 @@ impl Bot {
|
|||
reqwest::Url::clone(&*api_url),
|
||||
P::NAME,
|
||||
params,
|
||||
timeout_hint,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
@ -243,6 +245,7 @@ impl Bot {
|
|||
let token = Arc::clone(&self.token);
|
||||
let api_url = Arc::clone(&self.api_url);
|
||||
|
||||
let timeout_hint = payload.timeout_hint();
|
||||
let params = serde_multipart::to_form(payload);
|
||||
|
||||
// async move to capture client&token&api_url¶ms
|
||||
|
@ -254,6 +257,7 @@ impl Bot {
|
|||
reqwest::Url::clone(&*api_url),
|
||||
P::NAME,
|
||||
params,
|
||||
timeout_hint,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
@ -271,6 +275,7 @@ impl Bot {
|
|||
let token = Arc::clone(&self.token);
|
||||
let api_url = self.api_url.clone();
|
||||
|
||||
let timeout_hint = payload.timeout_hint();
|
||||
let params = serde_multipart::to_form_ref(payload);
|
||||
|
||||
// async move to capture client&token&api_url¶ms
|
||||
|
@ -282,6 +287,7 @@ impl Bot {
|
|||
reqwest::Url::clone(&*api_url),
|
||||
P::NAME,
|
||||
params,
|
||||
timeout_hint,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -99,6 +99,9 @@ macro_rules! impl_payload {
|
|||
$(
|
||||
@[multipart = $($multipart_attr:ident),*]
|
||||
)?
|
||||
$(
|
||||
@[timeout_secs = $timeout_secs:ident]
|
||||
)?
|
||||
$(
|
||||
#[ $($method_meta:tt)* ]
|
||||
)*
|
||||
|
@ -179,6 +182,12 @@ macro_rules! impl_payload {
|
|||
type Output = $Ret;
|
||||
|
||||
const NAME: &'static str = stringify!($Method);
|
||||
|
||||
$(
|
||||
fn timeout_hint(&self) -> Option<std::time::Duration> {
|
||||
self.$timeout_secs.map(<_>::into).map(std::time::Duration::from_secs)
|
||||
}
|
||||
)?
|
||||
}
|
||||
|
||||
calculated_doc! {
|
||||
|
|
|
@ -16,6 +16,7 @@ pub async fn request_multipart<T>(
|
|||
api_url: reqwest::Url,
|
||||
method_name: &str,
|
||||
params: reqwest::multipart::Form,
|
||||
timeout_hint: Option<Duration>,
|
||||
) -> ResponseResult<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
|
@ -33,10 +34,18 @@ where
|
|||
// [#460]: https://github.com/teloxide/teloxide/issues/460
|
||||
let method_name = method_name.trim_end_matches("Inline");
|
||||
|
||||
let response = client
|
||||
let mut request = client
|
||||
.post(crate::net::method_url(api_url, token, method_name))
|
||||
.multipart(params)
|
||||
.send()
|
||||
.build()
|
||||
.map_err(RequestError::Network)?;
|
||||
|
||||
if let Some(timeout) = timeout_hint {
|
||||
*request.timeout_mut().get_or_insert(Duration::ZERO) += timeout;
|
||||
}
|
||||
|
||||
let response = client
|
||||
.execute(request)
|
||||
.await
|
||||
.map_err(RequestError::Network)?;
|
||||
|
||||
|
@ -49,6 +58,7 @@ pub async fn request_json<T>(
|
|||
api_url: reqwest::Url,
|
||||
method_name: &str,
|
||||
params: Vec<u8>,
|
||||
timeout_hint: Option<Duration>,
|
||||
) -> ResponseResult<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
|
@ -66,11 +76,19 @@ where
|
|||
// [#460]: https://github.com/teloxide/teloxide/issues/460
|
||||
let method_name = method_name.trim_end_matches("Inline");
|
||||
|
||||
let response = client
|
||||
let mut request = client
|
||||
.post(crate::net::method_url(api_url, token, method_name))
|
||||
.header(CONTENT_TYPE, HeaderValue::from_static("application/json"))
|
||||
.body(params)
|
||||
.send()
|
||||
.build()
|
||||
.map_err(RequestError::Network)?;
|
||||
|
||||
if let Some(timeout) = timeout_hint {
|
||||
*request.timeout_mut().get_or_insert(Duration::ZERO) += timeout;
|
||||
}
|
||||
|
||||
let response = client
|
||||
.execute(request)
|
||||
.await
|
||||
.map_err(RequestError::Network)?;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use serde::Serialize;
|
|||
use crate::types::{AllowedUpdate, Update};
|
||||
|
||||
impl_payload! {
|
||||
@[timeout_secs = timeout]
|
||||
/// Use this method to receive incoming updates using long polling ([wiki]). An Array of [`Update`] objects is returned.
|
||||
///
|
||||
/// [wiki]: https://en.wikipedia.org/wiki/Push_technology#Long_polling
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::time::Duration;
|
||||
|
||||
/// Payload of a request.
|
||||
///
|
||||
/// Simply speaking, structures implementing this trait represent arguments of
|
||||
|
@ -21,4 +23,12 @@ pub trait Payload {
|
|||
/// It is case insensitive, though must not include underscores. (e.g.
|
||||
/// `GetMe`, `GETME`, `getme`, `getMe` are ok, but `get_me` is not ok).
|
||||
const NAME: &'static str;
|
||||
|
||||
/// If this payload may take long time to execute (e.g. [`GetUpdates`] with
|
||||
/// big `timeout`), the **minimum** timeout that should be used.
|
||||
///
|
||||
/// [`GetUpdates`]: crate::payloads::GetUpdates
|
||||
fn timeout_hint(&self) -> Option<Duration> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue