Skip to content

Commit

Permalink
Add timeout when waiting for processing
Browse files Browse the repository at this point in the history
  • Loading branch information
dscottboggs committed Jan 28, 2023
1 parent 49cce67 commit 651388b
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 5 deletions.
2 changes: 1 addition & 1 deletion examples/upload_photo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ async fn run() -> Result<()> {

let media = mastodon.media(input, description).await?;
let media = mastodon
.wait_for_processing(media, Default::default())
.wait_for_processing(media, Default::default(), Default::default())
.await?;
println!("media upload available at: {}", media.url);
let status = StatusBuilder::new()
Expand Down
3 changes: 3 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ pub enum Error {
/// Error from mastodon-async-entities
#[error(transparent)]
Entities(#[from] mastodon_async_entities::error::Error),
/// Error when a timeout limit has been hit
#[error("giving up after {0:?}")]
Timeout(crate::timeout::Timeout),
/// Other errors
#[error("other error: {0:?}")]
Other(String),
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ pub mod status_builder;
mod macros;
/// How much time to wait before checking an endpoint again.
pub mod polling_time;
/// A defaultable duration to wait before giving up
pub mod timeout;
/// Automatically import the things you need
pub mod prelude {
pub use crate::{
Expand Down
33 changes: 29 additions & 4 deletions src/mastodon.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{borrow::Cow, ops::Deref, path::Path, sync::Arc};
use std::{borrow::Cow, ops::Deref, path::Path, sync::Arc, time::Instant};

use crate::{
entities::{
Expand All @@ -13,6 +13,7 @@ use crate::{
helpers::read_response::read_response,
log_serde,
polling_time::PollingTime,
timeout::Timeout,
AddFilterRequest, AddPushRequest, Data, NewStatus, Page, StatusesRequest, UpdateCredsRequest,
UpdatePushRequest,
};
Expand Down Expand Up @@ -332,24 +333,46 @@ impl Mastodon {

/// Wait for the media to be done processing and return it with the URL.
///
/// `Default::default()` may be passed as the polling time to select a
/// polling time of 500ms.
/// `Default::default()` may be passed to select a polling time of 500ms and
/// a timeout of 90 seconds.
///
/// ## Example
/// ```rust,no_run
/// use mastodon_async::prelude::*;
/// let mastodon = Mastodon::from(Data::default());
/// tokio_test::block_on(async {
/// let attachment = mastodon.media("/path/to/some/file.jpg", None).await.expect("upload");
/// let attachment = mastodon.wait_for_processing(attachment, Default::default()).await.expect("processing");
/// let attachment = mastodon.wait_for_processing(
/// attachment,
/// Default::default(),
/// Default::default(),
/// ).await.expect("processing");
/// println!("{}", attachment.url);
/// });
/// ```
///
/// For a different timeout or polling time, use `.into()` on `std::time::Duration`s.
/// ```rust,no_run
/// use mastodon_async::prelude::*;
/// use std::time::Duration;
/// let mastodon = Mastodon::from(Data::default());
/// tokio_test::block_on(async {
/// let attachment = mastodon.media("/path/to/some/file.jpg", None).await.expect("upload");
/// let attachment = mastodon.wait_for_processing(
/// attachment,
/// Duration::from_secs(1).into(),
/// Duration::from_secs(10).into(),
/// ).await.expect("processing");
/// println!("{}", attachment.url);
/// });
/// ```
pub async fn wait_for_processing(
&self,
mut attachment: Attachment,
polling_time: PollingTime,
timeout: Timeout,
) -> Result<ProcessedAttachment> {
let start_time = Instant::now();
let id = attachment.id;
loop {
if let Some(url) = attachment.url {
Expand All @@ -363,6 +386,8 @@ impl Mastodon {
meta: attachment.meta,
description: attachment.description,
});
} else if (Instant::now() - start_time) >= *timeout {
return Err(Error::Timeout(timeout));
} else {
attachment = self.attachment(&id).await?;
tokio::time::sleep(*polling_time).await;
Expand Down
18 changes: 18 additions & 0 deletions src/timeout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use derive_deref::Deref;
use std::time::Duration;

/// A duration with 90 second default
#[derive(Debug, Deref, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Timeout(Duration);

impl Default for Timeout {
fn default() -> Self {
Self(Duration::from_secs(90))
}
}

impl From<Duration> for Timeout {
fn from(value: Duration) -> Self {
Self(value)
}
}

0 comments on commit 651388b

Please sign in to comment.