Use a thread pool
This commit is contained in:
parent
f4447a2648
commit
3ccf7daff6
|
@ -325,10 +325,12 @@ dependencies = [
|
|||
"gdk-pixbuf 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glib 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gtk 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reqwest 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"workerpool 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1468,6 +1470,14 @@ name = "winapi-x86_64-pc-windows-gnu"
|
|||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "workerpool"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ws2_32-sys"
|
||||
version = "0.2.1"
|
||||
|
@ -1637,4 +1647,5 @@ dependencies = [
|
|||
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum workerpool 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4f49756646617bde19ff95b370cfa5c0f7ead17a90c90d7cb62dc31dfaa8c625"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
|
|
|
@ -14,4 +14,6 @@ gtk = { version = "0.5", features = [ "v3_22" ] }
|
|||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
reqwest = "0.9"
|
||||
reqwest = "0.9"
|
||||
workerpool = "1.1.1"
|
||||
lazy_static = "1.2"
|
84
src/api.rs
84
src/api.rs
|
@ -1,4 +1,88 @@
|
|||
use serde_derive::*;
|
||||
use lazy_static::*;
|
||||
use workerpool::Worker;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
sync::{
|
||||
Arc,
|
||||
mpsc::{channel, Receiver},
|
||||
Mutex, MutexGuard
|
||||
},
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
pub static ref API: Arc<Mutex<Option<RequestContext>>>
|
||||
= Arc::new(Mutex::new(None));
|
||||
|
||||
static ref JOBS: workerpool::Pool<Req>
|
||||
= workerpool::Pool::new(5);
|
||||
}
|
||||
|
||||
pub fn execute(req: reqwest::RequestBuilder) -> Receiver<reqwest::Response> {
|
||||
let (tx, rx) = channel();
|
||||
JOBS.execute_to(tx, req);
|
||||
rx
|
||||
}
|
||||
|
||||
pub struct RequestContext {
|
||||
token: String,
|
||||
instance: String,
|
||||
client: reqwest::Client,
|
||||
}
|
||||
|
||||
impl RequestContext {
|
||||
pub fn new(instance: String) -> Self {
|
||||
RequestContext {
|
||||
token: String::new(),
|
||||
instance: instance.clone(),
|
||||
client: reqwest::Client::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn auth(&mut self, token: String) {
|
||||
self.token = token.clone();
|
||||
}
|
||||
|
||||
pub fn get<S: AsRef<str>>(&self, url: S) -> reqwest::RequestBuilder {
|
||||
self.client
|
||||
.get(&format!("https://{}{}", self.instance, url.as_ref()))
|
||||
.header(reqwest::header::AUTHORIZATION, format!("JWT {}", self.token))
|
||||
}
|
||||
|
||||
/// Warning: no authentication, since it is only used for login
|
||||
pub fn post<S: AsRef<str>>(&self, url: S) -> reqwest::RequestBuilder {
|
||||
self.client
|
||||
.post(&format!("https://{}{}", self.instance, url.as_ref()))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Req;
|
||||
|
||||
impl Worker for Req {
|
||||
type Input = reqwest::RequestBuilder;
|
||||
type Output = reqwest::Response;
|
||||
|
||||
fn execute(&mut self, req: Self::Input) -> Self::Output {
|
||||
req.send().expect("Error while sending request")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ApiResult<T> {
|
||||
Ok(T),
|
||||
Err
|
||||
}
|
||||
|
||||
impl<T> Into<Result<T, ()>> for ApiResult<T> {
|
||||
fn into(self) -> Result<T, ()> {
|
||||
match self {
|
||||
ApiResult::Ok(t) => Ok(t),
|
||||
ApiResult::Err => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct LoginData {
|
||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -25,6 +25,21 @@ macro_rules! clone {
|
|||
);
|
||||
}
|
||||
|
||||
macro_rules! wait {
|
||||
($exp:expr => | $res:ident | $then:block) => {
|
||||
let rx = $exp;
|
||||
gtk::idle_add(move || {
|
||||
match rx.try_recv() {
|
||||
Err(_) => glib::Continue(true),
|
||||
Ok(mut $res) => {
|
||||
$then;
|
||||
glib::Continue(false)
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
mod api;
|
||||
mod ui;
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@ use gtk::*;
|
|||
use std::{
|
||||
rc::Rc,
|
||||
cell::RefCell,
|
||||
ops::Deref
|
||||
};
|
||||
use crate::{State, api, ui::title};
|
||||
|
||||
use crate::{State, api::*, ui::title};
|
||||
|
||||
pub fn render(state: State) -> gtk::Box {
|
||||
let cont = gtk::Box::new(Orientation::Vertical, 24);
|
||||
|
@ -27,27 +27,26 @@ pub fn render(state: State) -> gtk::Box {
|
|||
instance, username, password
|
||||
)));
|
||||
login_bt.connect_clicked(clone!(state, widgets => move |_| {
|
||||
state.borrow_mut().instance = widgets.borrow().0.get_text();
|
||||
state.borrow_mut().username = widgets.borrow().1.get_text();
|
||||
state.borrow_mut().password = widgets.borrow().2.get_text();
|
||||
let mut api_ctx = crate::api::API.lock().expect("1");
|
||||
*api_ctx = Some(RequestContext::new(
|
||||
widgets.borrow().0.get_text().unwrap()
|
||||
));
|
||||
|
||||
let res: api::LoginInfo = reqwest::Client::new()
|
||||
.post(&format!("https://{}/api/v1/token/", state.borrow().instance.clone().unwrap()))
|
||||
.json(&api::LoginData {
|
||||
username: state.borrow().username.clone().unwrap(),
|
||||
password: state.borrow().password.clone().unwrap(),
|
||||
})
|
||||
.send()
|
||||
.unwrap()
|
||||
.json()
|
||||
.unwrap();
|
||||
let state = state.clone();
|
||||
wait!(execute(api_ctx.as_ref().unwrap().post("/api/v1/token/").json(&LoginData {
|
||||
username: widgets.borrow().1.get_text().clone().unwrap(),
|
||||
password: widgets.borrow().2.get_text().clone().unwrap(),
|
||||
})) => |res| {
|
||||
let res: Result<_, _> = res.json::<ApiResult<LoginInfo>>().unwrap().into();
|
||||
|
||||
state.borrow_mut().token = Some(res.token);
|
||||
let main_page = crate::ui::main_page::render(state.clone());
|
||||
main_page.show_all();
|
||||
state.borrow_mut().stack.add_named(&main_page, "main");
|
||||
state.borrow_mut().stack.set_visible_child(&main_page);
|
||||
state.borrow_mut().stack.show_all();
|
||||
if let Some(ref mut api) = *crate::api::API.lock().expect("3") {
|
||||
api.auth(res.unwrap().token.clone());
|
||||
}
|
||||
|
||||
state.borrow_mut().stack.add_named(&crate::ui::main_page::render(state.clone()), "main");
|
||||
state.borrow_mut().stack.set_visible_child_name("main");
|
||||
state.borrow_mut().stack.show_all();
|
||||
});
|
||||
}));
|
||||
|
||||
cont.add(&title);
|
||||
|
|
|
@ -17,7 +17,7 @@ pub fn render(state: State) -> gtk::Box {
|
|||
cont.set_margin_end(96);
|
||||
|
||||
let avatar_path = dirs::cache_dir().unwrap().join("funkload-avatar.png");
|
||||
let user: api::UserInfo = reqwest::Client::new()
|
||||
/*let user: api::UserInfo = reqwest::Client::new()
|
||||
.get(&format!("https://{}/api/v1/users/users/me/", state.borrow().instance.clone().unwrap()))
|
||||
.header(reqwest::header::AUTHORIZATION, format!("JWT {}", state.borrow().token.clone().unwrap_or_default()))
|
||||
.send()
|
||||
|
@ -75,7 +75,7 @@ pub fn render(state: State) -> gtk::Box {
|
|||
cont.add(&avatar);
|
||||
let lbl = Label::new(format!("Welcome {}.", user.username).as_ref());
|
||||
lbl.get_style_context().map(|c| c.add_class("h1"));
|
||||
cont.add(&lbl);
|
||||
cont.add(&lbl);*/
|
||||
|
||||
let search = SearchEntry::new();
|
||||
search.set_placeholder_text("Search");
|
||||
|
|
Loading…
Reference in New Issue