LRU cache for dapps (#2006)
Conflicts: dapps/Cargo.toml dapps/src/lib.rs
This commit is contained in:
committed by
Arkadiy Paronyan
parent
6da60afaba
commit
6f321d9849
@@ -18,7 +18,8 @@
|
||||
|
||||
use std::{fs, fmt};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc;
|
||||
use std::sync::{mpsc, Arc};
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::time::{Instant, Duration};
|
||||
|
||||
use hyper::{header, server, Decoder, Encoder, Next, Method, Control, Client};
|
||||
@@ -38,19 +39,20 @@ enum FetchState {
|
||||
Error(ContentHandler),
|
||||
InProgress {
|
||||
deadline: Instant,
|
||||
receiver: mpsc::Receiver<FetchResult>
|
||||
receiver: mpsc::Receiver<FetchResult>,
|
||||
},
|
||||
Done(Manifest),
|
||||
}
|
||||
|
||||
pub trait DappHandler {
|
||||
pub trait ContentValidator {
|
||||
type Error: fmt::Debug;
|
||||
|
||||
fn validate_and_install(&self, app: PathBuf) -> Result<Manifest, Self::Error>;
|
||||
fn done(&self, Option<&Manifest>);
|
||||
}
|
||||
|
||||
pub struct AppFetcherHandler<H: DappHandler> {
|
||||
pub struct ContentFetcherHandler<H: ContentValidator> {
|
||||
abort: Arc<AtomicBool>,
|
||||
control: Option<Control>,
|
||||
status: FetchState,
|
||||
client: Option<Client<Fetch>>,
|
||||
@@ -58,7 +60,7 @@ pub struct AppFetcherHandler<H: DappHandler> {
|
||||
dapp: H,
|
||||
}
|
||||
|
||||
impl<H: DappHandler> Drop for AppFetcherHandler<H> {
|
||||
impl<H: ContentValidator> Drop for ContentFetcherHandler<H> {
|
||||
fn drop(&mut self) {
|
||||
let manifest = match self.status {
|
||||
FetchState::Done(ref manifest) => Some(manifest),
|
||||
@@ -68,16 +70,18 @@ impl<H: DappHandler> Drop for AppFetcherHandler<H> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<H: DappHandler> AppFetcherHandler<H> {
|
||||
impl<H: ContentValidator> ContentFetcherHandler<H> {
|
||||
|
||||
pub fn new(
|
||||
app: GithubApp,
|
||||
abort: Arc<AtomicBool>,
|
||||
control: Control,
|
||||
using_dapps_domains: bool,
|
||||
handler: H) -> Self {
|
||||
|
||||
let client = Client::new().expect("Failed to create a Client");
|
||||
AppFetcherHandler {
|
||||
ContentFetcherHandler {
|
||||
abort: abort,
|
||||
control: Some(control),
|
||||
client: Some(client),
|
||||
status: FetchState::NotStarted(app),
|
||||
@@ -94,12 +98,12 @@ impl<H: DappHandler> AppFetcherHandler<H> {
|
||||
|
||||
|
||||
// TODO [todr] https support
|
||||
fn fetch_app(client: &mut Client<Fetch>, app: &GithubApp, control: Control) -> Result<mpsc::Receiver<FetchResult>, String> {
|
||||
fn fetch_app(client: &mut Client<Fetch>, app: &GithubApp, abort: Arc<AtomicBool>, control: Control) -> Result<mpsc::Receiver<FetchResult>, String> {
|
||||
let url = try!(app.url().parse().map_err(|e| format!("{:?}", e)));
|
||||
trace!(target: "dapps", "Fetching from: {:?}", url);
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let res = client.request(url, Fetch::new(tx, Box::new(move || {
|
||||
let res = client.request(url, Fetch::new(tx, abort, Box::new(move || {
|
||||
trace!(target: "dapps", "Fetching finished.");
|
||||
// Ignoring control errors
|
||||
let _ = control.ready(Next::read());
|
||||
@@ -111,7 +115,7 @@ impl<H: DappHandler> AppFetcherHandler<H> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<H: DappHandler> server::Handler<HttpStream> for AppFetcherHandler<H> {
|
||||
impl<H: ContentValidator> server::Handler<HttpStream> for ContentFetcherHandler<H> {
|
||||
fn on_request(&mut self, request: server::Request<HttpStream>) -> Next {
|
||||
let status = if let FetchState::NotStarted(ref app) = self.status {
|
||||
Some(match *request.method() {
|
||||
@@ -120,7 +124,7 @@ impl<H: DappHandler> server::Handler<HttpStream> for AppFetcherHandler<H> {
|
||||
trace!(target: "dapps", "Fetching dapp: {:?}", app);
|
||||
let control = self.control.take().expect("on_request is called only once, thus control is always Some");
|
||||
let client = self.client.as_mut().expect("on_request is called before client is closed.");
|
||||
let fetch = Self::fetch_app(client, app, control);
|
||||
let fetch = Self::fetch_app(client, app, self.abort.clone(), control);
|
||||
match fetch {
|
||||
Ok(receiver) => FetchState::InProgress {
|
||||
deadline: Instant::now() + Duration::from_secs(FETCH_TIMEOUT),
|
||||
|
||||
Reference in New Issue
Block a user