Upgrading to actix 2.0

This commit is contained in:
Dessalines 2020-01-09 11:31:30 -05:00
parent 2b6b179300
commit 4c7236be86
4 changed files with 561 additions and 646 deletions

2
docker/dev/docker_update.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
docker-compose up -d --build --remove-orphans --no-deps

1097
server/service/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,18 +2,24 @@
name = "torrents-csv-service" name = "torrents-csv-service"
version = "0.1.0" version = "0.1.0"
authors = ["Dessalines <happydooby@gmail.com>"] authors = ["Dessalines <happydooby@gmail.com>"]
edition = "2018"
[dependencies] [dependencies]
actix-web = "1.0" actix-rt = "1.0.0"
actix-files = "0.1.7" actix-web = "2.0.0"
actix-files = "0.2.1"
env_logger = "0.7.1"
serde = "*" serde = "*"
serde_json = "*" serde_json = "1.0.44"
serde_derive = "*" serde_derive = "*"
time = "*"
futures = "0.3.1"
failure = "*" failure = "*"
r2d2 = "0.8.6"
r2d2_sqlite = "0.12.0" r2d2 = "0.8"
r2d2_sqlite = "0.13"
[dependencies.rusqlite] [dependencies.rusqlite]
version = "0.20.0" version = "0.21.0"
features = ["bundled"] features = ["bundled"]

View File

@ -5,7 +5,6 @@ extern crate serde_json;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate rusqlite; extern crate rusqlite;
extern crate time;
#[macro_use] #[macro_use]
extern crate failure; extern crate failure;
extern crate r2d2; extern crate r2d2;
@ -13,33 +12,40 @@ extern crate r2d2_sqlite;
use actix_files as fs; use actix_files as fs;
use actix_files::NamedFile; use actix_files::NamedFile;
use actix_web::{web, App, HttpResponse, HttpServer}; use actix_web::{middleware, web, App, HttpResponse, HttpServer};
use failure::Error; use failure::Error;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
use rusqlite::params; use rusqlite::params;
use std::env; use std::env;
use std::ops::Deref; use std::ops::Deref;
use std::cmp;
use std::io;
use serde_json::Value;
fn main() { #[actix_rt::main]
async fn main() -> io::Result<()> {
println!("Access me at {}", endpoint()); println!("Access me at {}", endpoint());
std::env::set_var("RUST_LOG", "actix_web=debug");
env_logger::init();
let manager = SqliteConnectionManager::file(torrents_db_file()); let manager = SqliteConnectionManager::file(torrents_db_file());
let pool = r2d2::Pool::builder().max_size(15).build(manager).unwrap(); let pool = r2d2::Pool::builder().max_size(15).build(manager).unwrap();
HttpServer::new(move || { HttpServer::new(move || {
App::new() App::new()
.route("/", web::get().to(index))
.service(fs::Files::new("/static", front_end_dir()))
.data(pool.clone()) .data(pool.clone())
.route("/service/search", web::get().to_async(search)) .wrap(middleware::Logger::default())
.service(fs::Files::new("/static", front_end_dir()))
.route("/", web::get().to(index))
.route("/service/search", web::get().to(search))
}) })
.bind(endpoint()) .keep_alive(None)
.unwrap() .bind(endpoint())?
.run() .run()
.unwrap() .await
} }
fn index() -> Result<NamedFile, actix_web::error::Error> { async fn index() -> Result<NamedFile, actix_web::error::Error> {
Ok(NamedFile::open(front_end_dir() + "/index.html")?) Ok(NamedFile::open(front_end_dir() + "/index.html")?)
} }
@ -63,32 +69,35 @@ struct SearchQuery {
type_: Option<String>, type_: Option<String>,
} }
fn search( async fn search(
db: web::Data<r2d2::Pool<SqliteConnectionManager>>, db: web::Data<r2d2::Pool<SqliteConnectionManager>>,
query: web::Query<SearchQuery>, query: web::Query<SearchQuery>,
) -> HttpResponse { ) -> Result<HttpResponse, actix_web::Error> {
if query.q.is_empty() {
return HttpResponse::BadRequest()
.header("Access-Control-Allow-Origin", "*")
.content_type("application/json")
.body(format!("{{\"error\": \"{}\"}}", "Empty query".to_string()));
}
let res = web::block(move || {
let conn = db.get().unwrap(); let conn = db.get().unwrap();
search_query(query, conn)
HttpResponse::Ok() })
.await
.map(|body| HttpResponse::Ok()
.header("Access-Control-Allow-Origin", "*") .header("Access-Control-Allow-Origin", "*")
.content_type("application/json") .json(body))
.body(search_query(query, conn).unwrap()) .map_err(|e|
actix_web::error::ErrorBadRequest(e))?;
Ok(res)
} }
fn search_query( fn search_query(
query: web::Query<SearchQuery>, query: web::Query<SearchQuery>,
conn: r2d2::PooledConnection<SqliteConnectionManager>, conn: r2d2::PooledConnection<SqliteConnectionManager>,
) -> Result<String, serde_json::Error> { ) -> Result<Value, Error> {
if query.q.is_empty() || query.q.trim() == "*" {
return Err(format_err!("{{\"error\": \"{}\"}}", "Empty query".to_string()));
}
let page = query.page.unwrap_or(1); let page = query.page.unwrap_or(1);
let size = query.size.unwrap_or(10); let size = cmp::min(100, query.size.unwrap_or(10));
let type_ = query.type_.as_ref().map_or("torrent", String::deref); let type_ = query.type_.as_ref().map_or("torrent", String::deref);
let offset = size * (page - 1); let offset = size * (page - 1);
@ -97,13 +106,15 @@ fn search_query(
query.q, type_, page, size query.q, type_, page, size
); );
if type_ == "file" { let res = if type_ == "file" {
let results = torrent_file_search(conn, &query.q, size, offset).unwrap(); let results = torrent_file_search(conn, &query.q, size, offset)?;
serde_json::to_string(&results) serde_json::to_value(&results).unwrap()
} else { } else {
let results = torrent_search(conn, &query.q, size, offset).unwrap(); let results = torrent_search(conn, &query.q, size, offset)?;
serde_json::to_string(&results) serde_json::to_value(&results).unwrap()
} };
Ok(res)
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@ -204,14 +215,15 @@ fn torrent_file_search(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use time::PreciseTime; use r2d2_sqlite::SqliteConnectionManager;
#[test] #[test]
fn test() { fn test() {
let start = PreciseTime::now(); let manager = SqliteConnectionManager::file(super::torrents_db_file());
let results = super::torrent_search("sherlock", 10, 0); let pool = r2d2::Pool::builder().max_size(15).build(manager).unwrap();
assert!(results.len() > 2); let conn = pool.get().unwrap();
let end = PreciseTime::now(); let results = super::torrent_search(conn, "sherlock", 10, 0);
println!("Query took {} seconds.", start.to(end)); assert!(results.unwrap().len() > 2);
// println!("Query took {:?} seconds.", end - start);
} }
} }