diff --git a/CHANGELOG.md b/CHANGELOG.md index c9c852c4..643575ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All changes in this project will be noted in this file. +## Version 0.5.3 [2021-05-13] + +> No breaking changes + +Fix persistence (see [#150](https://github.com/skytable/skytable/issues/150)) + ## Version 0.5.2 [2021-05-07] > No breaking changes diff --git a/server/src/coredb/mod.rs b/server/src/coredb/mod.rs index 4370a6ee..ce63b186 100644 --- a/server/src/coredb/mod.rs +++ b/server/src/coredb/mod.rs @@ -287,7 +287,7 @@ impl CoreDB { bgsave: BGSave, snapshot_cfg: SnapshotConfig, restore_file: Option, - ) -> TResult<(Self, Option, flock::FileLock)> { + ) -> TResult<(Self, Option)> { let coretable = diskstore::get_saved(restore_file)?; let mut background_tasks: usize = 0; if !bgsave.is_disabled() { @@ -325,13 +325,12 @@ impl CoreDB { )); let lock = flock::FileLock::lock(&*PERSIST_FILE) .map_err(|e| format!("Failed to acquire lock on data file with error '{}'", e))?; - let cloned_descriptor = lock.try_clone()?; if bgsave.is_disabled() { - Ok((db, Some(lock), cloned_descriptor)) + Ok((db, Some(lock))) } else { // Spawn the BGSAVE service in a separate task tokio::spawn(diskstore::bgsave_scheduler(db.clone(), bgsave, lock)); - Ok((db, None, cloned_descriptor)) + Ok((db, None)) } } /// Create an empty in-memory table diff --git a/server/src/dbnet/mod.rs b/server/src/dbnet/mod.rs index b3eef1b6..6c7bb3be 100644 --- a/server/src/dbnet/mod.rs +++ b/server/src/dbnet/mod.rs @@ -44,8 +44,7 @@ use crate::config::PortConfig; use crate::config::SnapshotConfig; use crate::config::SslOpts; use crate::dbnet::tcp::Listener; -use crate::diskstore::{self, snapshot::DIR_REMOTE_SNAPSHOT}; -use diskstore::flock; +use crate::diskstore::snapshot::DIR_REMOTE_SNAPSHOT; mod tcp; use crate::CoreDB; use libsky::TResult; @@ -315,7 +314,7 @@ pub async fn run( snapshot_cfg: SnapshotConfig, sig: impl Future, restore_filepath: Option, -) -> (CoreDB, flock::FileLock) { +) -> CoreDB { let (signal, _) = broadcast::channel(1); let (terminate_tx, terminate_rx) = mpsc::channel(1); match fs::create_dir_all(&*DIR_REMOTE_SNAPSHOT) { @@ -328,14 +327,13 @@ pub async fn run( } }, } - let (db, lock, cloned_descriptor) = - match CoreDB::new(bgsave_cfg, snapshot_cfg, restore_filepath) { - Ok((db, lock, cloned_descriptor)) => (db, lock, cloned_descriptor), - Err(e) => { - log::error!("ERROR: {}", e); - process::exit(0x100); - } - }; + let (db, lock) = match CoreDB::new(bgsave_cfg, snapshot_cfg, restore_filepath) { + Ok((db, lock)) => (db, lock), + Err(e) => { + log::error!("ERROR: {}", e); + process::exit(0x100); + } + }; let climit = Arc::new(Semaphore::new(50000)); let mut server = match ports { PortConfig::InsecureOnly { host, port } => { @@ -392,5 +390,5 @@ pub async fn run( log::error!("Failed to release lock on data file with '{}'", e); process::exit(0x100); } - (db, cloned_descriptor) + db } diff --git a/server/src/diskstore/flock.rs b/server/src/diskstore/flock.rs index b099620b..f9bd8306 100644 --- a/server/src/diskstore/flock.rs +++ b/server/src/diskstore/flock.rs @@ -98,18 +98,6 @@ impl FileLock { // Now write to the file self.file.write_all(bytes) } - pub fn try_clone(&self) -> Result { - Ok(Self { - file: self.file.try_clone()?, - unlocked: false, - }) - } - /// Reacquire a lock - pub fn reacquire(&mut self) -> Result<()> { - Self::_lock(&self.file)?; - self.unlocked = false; - Ok(()) - } } impl Drop for FileLock { diff --git a/server/src/main.rs b/server/src/main.rs index 6bd74170..2d4f474d 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -33,6 +33,7 @@ use crate::config::BGSave; use crate::config::PortConfig; use crate::config::SnapshotConfig; +use crate::diskstore::PERSIST_FILE; use std::io::{self, prelude::*}; mod config; use std::env; @@ -77,10 +78,10 @@ fn main() { .enable_all() .build() .unwrap(); - let (db, mut descriptor) = runtime.block_on(async { + let db = runtime.block_on(async { let (tcplistener, bgsave_config, snapshot_config, restore_filepath) = check_args_and_get_cfg().await; - let (db, descriptor) = run( + let db = run( tcplistener, bgsave_config, snapshot_config, @@ -88,7 +89,7 @@ fn main() { restore_filepath, ) .await; - (db, descriptor) + db }); // Make sure all background workers terminate drop(runtime); @@ -98,18 +99,21 @@ fn main() { "Maybe the compiler reordered the drop causing more than one instance of CoreDB to live at this point" ); // Try to acquire lock almost immediately - if let Err(e) = descriptor.reacquire() { - log::error!("Failed to reacquire lock on data file with error: '{}'", e); - panic!("FATAL: data file relocking failure"); - } - if let Err(e) = flush_db!(db, descriptor) { + let mut lock = match diskstore::flock::FileLock::lock(&*PERSIST_FILE) { + Ok(lck) => lck, + Err(e) => { + log::error!("Failed to reacquire lock on data file with '{}'", e); + std::process::exit(0x100); + } + }; + if let Err(e) = flush_db!(db, lock) { log::error!("Failed to flush data to disk with '{}'", e); loop { // Keep looping until we successfully write the in-memory table to disk log::warn!("Press enter to try again..."); io::stdout().flush().unwrap(); io::stdin().read(&mut [0]).unwrap(); - if let Ok(_) = flush_db!(db, descriptor) { + if let Ok(_) = flush_db!(db, lock) { log::info!("Successfully saved data to disk"); break; } else { @@ -124,12 +128,7 @@ fn main() { /// This function checks the command line arguments and either returns a config object /// or prints an error to `stderr` and terminates the server -async fn check_args_and_get_cfg() -> ( - PortConfig, - BGSave, - SnapshotConfig, - Option, -) { +async fn check_args_and_get_cfg() -> (PortConfig, BGSave, SnapshotConfig, Option) { let cfg = config::get_config_file_or_return_cfg(); let binding_and_cfg = match cfg { Ok(config::ConfigType::Custom(cfg, file)) => {