From a09f2dba73c8754edef5e56735cf91b9d27296e5 Mon Sep 17 00:00:00 2001 From: dkos Date: Thu, 3 Sep 2020 18:29:02 +0200 Subject: [PATCH] first it --- README.md | 6 ++++-- src/config.rs | 2 +- src/db.rs | 11 +++++++--- src/main.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 72 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3c9f59e..1d095bf 100644 --- a/README.md +++ b/README.md @@ -67,14 +67,16 @@ For service performance tuning check example service_config.toml and yes - ```wo Example configuration is provided under ```project_root/config``` ### TODO + - [ ] IT - [ ] impl From for errors - [ ] support for more rocksDb options in config (bloom, block cache..) - [ ] db iterator for on startup init - [ ] channel for expire - - [ ] IT - [ ] test compaction - [ ] code coverage - - [ ] performance ? + - [ ] docker + - [ ] range scan + - [ ] performance ## Licence diff --git a/src/config.rs b/src/config.rs index f2cfdc7..80b5346 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,7 +11,7 @@ pub struct ServiceConfig { } #[derive(Debug)] -pub struct DbConfig(RocksDbConfig); +pub struct DbConfig(pub RocksDbConfig); impl DbConfig { fn new(rocks_cfg: RocksDbConfig) -> Self { diff --git a/src/db.rs b/src/db.rs index d0d3755..6766ff0 100644 --- a/src/db.rs +++ b/src/db.rs @@ -92,16 +92,19 @@ impl DbManager { .set_compaction_filter("expiration-filter", compaction_filter); let root_db = open_root_db(&db_cfg)?; - Ok(DbManager { + let db_manager = DbManager { db_cfg, root_db, dbs: Arc::new(ShardedLock::new(HashMap::new())), executor: Mutex::new(ThreadPoolExecutor::new(1)), - }) + }; + db_manager.init(); + + Ok(db_manager) } // will panic in main thread and prevent startup - pub fn init(&self) { + fn init(&self) { info!("Initializing dbs from root ..."); //TODO db iterator self.root_db @@ -150,6 +153,8 @@ impl DbManager { } else { if let Some(db) = self.w_lock().remove(&db_name) { info!("Closing db = {} ...", &db_name); + self.root_db.w_lock().delete(&db_name)?; + //possible expensive call moved to separate thread TODO channels self.tp_mutex().execute(move || match db.close(&db_name) { Ok(_) => info!("Db = {} closed", &db_name), Err(e) => error!("Error closing db = {}, e = {}", &db_name, e), diff --git a/src/main.rs b/src/main.rs index 60351d9..120d89d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -177,7 +177,6 @@ async fn main() -> std::io::Result<()> { info!("Loaded db configuration = {:#?}", &db_cfg); let db_manager = DbManager::new(db_cfg)?; - db_manager.init(); let db_manager = web::Data::new(db_manager); let prometheus = init_prometheus(); @@ -218,3 +217,62 @@ fn init_logger(log_path: &str, dev_mode: bool) { WriteLogger::init(LevelFilter::Info, cfg, log_file).expect("Failed to init file logger") } } + +#[cfg(test)] +mod tests { + + use actix_web::dev::ServiceResponse; + use actix_web::http::StatusCode; + use actix_web::{test, web, App, Error}; + + use crate::config::{DbConfig, RocksDbConfig}; + use crate::conversion::bytes_to_str; + + use super::*; + + impl DbConfig { + pub fn new_with_defaults() -> Self { + DbConfig(RocksDbConfig::default()) + } + } + + #[actix_rt::test] + async fn should_open_and_close_db() -> Result<(), Error> { + std::env::set_var("RUST_BACKTRACE", "full"); + + let db_manager = DbManager::new(DbConfig::new_with_defaults())?; + let mut app = test::init_service( + App::new() + .app_data(web::Data::new(db_manager)) + .service(open) + .service(close), + ) + .await; + + let req = test::TestRequest::post().uri("/test_db").to_request(); + let res = test::call_service(&mut app, req).await; + assert_eq!( + StatusCode::OK, + res.status(), + "Received payload:: {:?}", + response_as_str(res) + ); + + let req = test::TestRequest::delete().uri("/test_db").to_request(); + let res = test::call_service(&mut app, req).await; + assert_eq!( + StatusCode::OK, + res.status(), + "Received payload:: {:?}", + response_as_str(res) + ); + Ok(()) + } + + fn response_as_str(res: ServiceResponse) -> Conversion { + match res.response().body().as_ref() { + Some(Body::Bytes(bytes)) => bytes_to_str(bytes), + _ => Ok("empty".to_string()), + } + } +}