Skip to content

Commit

Permalink
Add option to specify timeout for HTTP requests
Browse files Browse the repository at this point in the history
  • Loading branch information
DoumanAsh committed May 12, 2018
1 parent d09a03f commit 3517d66
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fie"
version = "0.7.0"
version = "0.7.1"
authors = ["Douman <[email protected]>"]
repository = "https://github.com/DoumanAsh/fie"
description = "Small and cute twitter app."
Expand Down
6 changes: 6 additions & 0 deletions fie.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,9 @@ password = "password"
minds = true
gab = true
twitter = true

[settings]
# Amount of seconds to wait for responses from API server.
# All request fails when it exceeds this time
# Default value is 5 seconds
timeout = 5
9 changes: 5 additions & 4 deletions src/actors/gab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use misc::{ClientRequestBuilderExt, ClientRequestExt};
/// Gab actor
pub struct Gab {
config: config::Gab,
settings: config::Settings
}

impl Actor for Gab {
Expand All @@ -26,8 +27,8 @@ impl Actor for Gab {
}

impl Gab {
pub fn new(config: config::Gab) -> Self {
Self { config }
pub fn new(config: config::Gab, settings: config::Settings) -> Self {
Self { config, settings }
}
}

Expand All @@ -53,7 +54,7 @@ impl Handler<UploadImage> for Gab {
Err(error) => return Box::new(future::err(error)),
};

let req = req.send_ext()
let req = req.send_with_timeout(self.settings.timeout)
.map_err(|error| format!("Gab upload error: {}", error))
.and_then(|response| match response.status().is_success() {
true => Ok(response),
Expand Down Expand Up @@ -134,7 +135,7 @@ impl Handler<PostMessage> for Gab {
Err(error) => return Box::new(future::err(format!("Gab post actix error: {}", error))),
};

let req = req.send_ext()
let req = req.send_with_timeout(self.settings.timeout)
.map_err(|error| format!("Gab post error: {}", error))
.and_then(|response| match response.status().is_success() {
true => Ok(response),
Expand Down
41 changes: 24 additions & 17 deletions src/actors/minds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,31 @@ mod payload {
}
}

pub enum Minds {
enum State {
NotStarted(config::Minds),
Started(payload::Oauth2),
}
pub struct Minds {
state: State,
settings: config::Settings
}

impl Minds {
pub fn new(config: config::Minds, settings: config::Settings) -> Self {
Self {
state: State::NotStarted(config),
settings
}
}
}

impl Actor for Minds {
type Context = Context<Self>;

fn started(&mut self, ctx: &mut Context<Self>) {
const OAUTH2_URL: &'static str = "https://www.minds.com/oauth2/token";
let config = match self {
&mut Minds::NotStarted(ref config) => config,
let config = match &self.state {
&State::NotStarted(ref config) => config,
_ => {
eprintln!("Minds: internal error. Actor in a started state already");
return ctx.stop();
Expand All @@ -112,7 +125,7 @@ impl Actor for Minds {
},
};

req.send_ext()
req.send_with_timeout(self.settings.timeout)
.into_actor(self)
.map_err(|error, _act, ctx| {
eprintln!("Minds oauth2 error: {}", error);
Expand All @@ -121,7 +134,7 @@ impl Actor for Minds {
.and_then(|rsp, act, _ctx| {
rsp.json()
.into_actor(act)
.map(|oauth2, act, _ctx| *act = Minds::Started(oauth2))
.map(|oauth2, act, _ctx| (*act).state = State::Started(oauth2))
.map_err(|error, _act, ctx| {
eprintln!("Minds oauth2 parse error: {}", error);
ctx.stop()
Expand All @@ -131,20 +144,14 @@ impl Actor for Minds {
}
}

impl Minds {
pub fn new(config: config::Minds) -> Self {
Minds::NotStarted(config)
}
}

impl Handler<UploadImage> for Minds {
type Result = ResponseFuture<ResultImage, String>;

fn handle(&mut self, msg: UploadImage, _: &mut Self::Context) -> Self::Result {
const IMAGES_URL: &'static str = "https://www.minds.com/api/v1/media";

let access_token = match self {
&mut Minds::Started(ref oauth2) => &oauth2.access_token,
let access_token = match &self.state {
&State::Started(ref oauth2) => &oauth2.access_token,
_ => return Box::new(future::err("Unable to send Minds request".to_string())),
};

Expand All @@ -159,7 +166,7 @@ impl Handler<UploadImage> for Minds {
Err(error) => return Box::new(future::err(error)),
};

let req = req.send_ext()
let req = req.send_with_timeout(self.settings.timeout)
.map_err(|error| format!("Minds upload error: {}", error))
.and_then(|response| match response.status().is_success() {
true => Ok(response),
Expand All @@ -183,8 +190,8 @@ impl Handler<PostMessage> for Minds {
fn handle(&mut self, msg: PostMessage, _: &mut Self::Context) -> Self::Result {
const POST_URL: &'static str = "https://www.minds.com/api/v1/newsfeed";

let access_token = match self {
&mut Minds::Started(ref oauth2) => &oauth2.access_token,
let access_token = match &self.state {
&State::Started(ref oauth2) => &oauth2.access_token,
_ => return Box::new(future::err("Unable to send Minds request".to_string())),
};

Expand All @@ -204,7 +211,7 @@ impl Handler<PostMessage> for Minds {
Err(error) => return Box::new(future::err(format!("Minds post actix error: {}", error))),
};

let req = req.send_ext()
let req = req.send_with_timeout(self.settings.timeout)
.map_err(|error| format!("Minds post error: {}", error))
.and_then(|response| match response.status().is_success() {
true => Ok(response),
Expand Down
6 changes: 4 additions & 2 deletions src/actors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct API {
pub twitter: Option<Addr<Unsync, Twitter>>,
pub gab: Option<Addr<Unsync, Gab>>,
pub minds: Option<Addr<Unsync, Minds>>,
settings: config::Settings
}

impl API {
Expand All @@ -33,20 +34,21 @@ impl API {
twitter: None,
gab: None,
minds: None,
settings: config::Settings::default()
}
}

pub fn start_minds_if(mut self, cond: bool, minds: config::Minds) -> Self {
if cond {
self.minds = Some(Minds::new(minds).start());
self.minds = Some(Minds::new(minds, self.settings.clone()).start());
}

self
}

pub fn start_gab_if(mut self, cond: bool, gab: config::Gab) -> Self {
if cond {
self.gab = Some(Gab::new(gab).start());
self.gab = Some(Gab::new(gab, self.settings.clone()).start());
}

self
Expand Down
20 changes: 20 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,39 @@ pub struct Gab {
/// You can get it after logging into gab.io and examining your HTTP requests.
pub token: String,
}

#[derive(Deserialize, Debug)]
pub struct Minds {
pub username: String,
pub password: String,
}

fn default_timeout() -> u64 { 5 }

#[derive(Deserialize, Debug, Clone)]
pub struct Settings {
#[serde(default = "default_timeout")]
///Amount of settings to wait for all HTTP responses
pub timeout: u64,
}

impl Default for Settings {
fn default() -> Self {
Self {
timeout: 5
}
}
}

#[derive(Deserialize, Debug)]
pub struct Config {
#[serde(default)]
pub platforms: Platforms,
pub gab: Gab,
pub twitter: Twitter,
pub minds: Minds,
#[serde(default)]
pub settings: Settings
}

impl Config {
Expand Down
10 changes: 4 additions & 6 deletions src/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,16 @@ impl<T, E: fmt::Display> ResultExt<T, E> for Result<T, E> {

///Number of seconds to wait for connection
const CONN_TIMEOUT_S: u64 = 5;
///Number of seconds to wait for response
const WAIT_TIMEOUT_S: u64 = 300;

pub trait ClientRequestExt {
fn send_ext(self) -> SendRequest;
fn send_with_timeout(self, timeout: u64) -> SendRequest;
}
impl ClientRequestExt for ClientRequest {
fn send_ext(self) -> SendRequest {
fn send_with_timeout(self, timeout: u64) -> SendRequest {
self.send()
.timeout(time::Duration::new(WAIT_TIMEOUT_S, 0))
.timeout(time::Duration::new(timeout, 0))
.conn_timeout(time::Duration::new(CONN_TIMEOUT_S, 0))
.wait_timeout(time::Duration::new(WAIT_TIMEOUT_S, 0))
.wait_timeout(time::Duration::new(timeout, 0))
}
}

Expand Down

0 comments on commit 3517d66

Please sign in to comment.