about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2018-04-14T20·05+0200
committerVincent Ambo <github@tazj.in>2018-04-14T20·21+0200
commit39d1cd64bc5ffe250dc2a30d05d0b6312e7abbc1 (patch)
tree8b364010a51f01e1df06908f403162b5ffceddbf
parent3e5b1098c6ae2852ea2df37b7c292cb37d5b1e84 (diff)
feat(main/db): Schedule regular search view refresh
Schedules refreshes of the database view used for search at one-minute
intervals.
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--src/db.rs21
-rw-r--r--src/errors.rs10
-rw-r--r--src/main.rs19
5 files changed, 54 insertions, 0 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 70a490cf5622..34369e928cc5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -312,6 +312,8 @@ dependencies = [
  "serde_derive 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "tera 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-timer 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index e274ee5f5f18..735e65502801 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,3 +24,5 @@ hyper = "0.11"
 rand = "0.4"
 comrak = "0.2"
 md5 = "0.3.7"
+tokio = "0.1"
+tokio-timer = "0.2"
diff --git a/src/db.rs b/src/db.rs
index 416e3fdd0f52..a4f86977c5f4 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -177,3 +177,24 @@ impl Handler<SearchPosts> for DbExecutor {
         Ok(search_results)
     }
 }
+
+/// Message that triggers a refresh of the view used for full-text
+/// searching.
+pub struct RefreshSearchView;
+
+impl Message for RefreshSearchView {
+    type Result = Result<()>;
+}
+
+const REFRESH_QUERY: &'static str = "REFRESH MATERIALIZED VIEW search_index";
+
+impl Handler<RefreshSearchView> for DbExecutor {
+    type Result = Result<()>;
+
+    fn handle(&mut self, _: RefreshSearchView, _: &mut Self::Context) -> Self::Result {
+        let conn = self.0.get()?;
+        debug!("Refreshing search_index view in DB");
+        sql_query(REFRESH_QUERY).execute(&conn)?;
+        Ok(())
+    }
+}
diff --git a/src/errors.rs b/src/errors.rs
index c7c1e14f4312..9de907430d6e 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -30,6 +30,7 @@ use diesel;
 use r2d2;
 use reqwest;
 use tera;
+use tokio_timer;
 
 pub type Result<T> = result::Result<T, ConverseError>;
 
@@ -50,6 +51,9 @@ pub enum ConverseError {
     #[fail(display = "error occured during request handling: {}", error)]
     ActixWeb { error: actix_web::Error },
 
+    #[fail(display = "error occured running timer: {}", error)]
+    Timer { error: tokio_timer::Error },
+
     // This variant is used as a catch-all for wrapping
     // actix-web-compatible response errors, such as the errors it
     // throws itself.
@@ -99,6 +103,12 @@ impl From<reqwest::Error> for ConverseError {
     }
 }
 
+impl From<tokio_timer::Error> for ConverseError {
+    fn from(error: tokio_timer::Error) -> ConverseError {
+        ConverseError::Timer { error }
+    }
+}
+
 // Support conversion of error type into HTTP error responses:
 
 impl ResponseError for ConverseError {
diff --git a/src/main.rs b/src/main.rs
index 61969bcff92a..9f4eea03fa31 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -42,6 +42,8 @@ extern crate rand;
 extern crate reqwest;
 extern crate serde;
 extern crate serde_json;
+extern crate tokio;
+extern crate tokio_timer;
 extern crate url;
 extern crate url_serde;
 
@@ -86,6 +88,8 @@ fn main() {
 
     let db_addr = SyncArbiter::start(2, move || DbExecutor(pool.clone()));
 
+    schedule_search_refresh(db_addr.clone());
+
     info!("Initialising OIDC integration ...");
     let oidc_url = config("OIDC_DISCOVERY_URL");
     let oidc_config = oidc::load_oidc(&oidc_url)
@@ -162,3 +166,18 @@ fn main() {
 
     let _ = sys.run();
 }
+
+fn schedule_search_refresh(db: Addr<Syn, DbExecutor>) {
+    use tokio::prelude::*;
+    use tokio::timer::Interval;
+    use std::time::{Duration, Instant};
+    use std::thread;
+
+    let task = Interval::new(Instant::now(), Duration::from_secs(60))
+        .from_err()
+        .for_each(move |_| db.send(db::RefreshSearchView).flatten())
+        .map_err(|err| error!("Error while updating search view: {}", err));
+        //.and_then(|_| debug!("Refreshed search view in DB"));
+
+    thread::spawn(|| tokio::run(task));
+}