From 55aad67338c4eecdbc9a7b5f355caa83c49c555a Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Mon, 19 Jun 2023 15:03:55 +0200 Subject: [PATCH] Remove the sqlite-lock binary from the main repo Will move it to a personal repository of mine. Signed-off-by: Benjamin Bouvier --- Cargo.lock | 47 +------ labs/sqlite-lock/Cargo.toml | 15 --- labs/sqlite-lock/src/main.rs | 241 ----------------------------------- 3 files changed, 1 insertion(+), 302 deletions(-) delete mode 100644 labs/sqlite-lock/Cargo.toml delete mode 100644 labs/sqlite-lock/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index d22acd7e800..53908908420 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1075,7 +1075,7 @@ dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.8.0", + "memoffset", "scopeguard", ] @@ -2963,15 +2963,6 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.8.0" @@ -3150,8 +3141,6 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.7.1", - "pin-utils", "static_assertions", ] @@ -4692,27 +4681,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "speedy" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7642861d1a1569b105c57008df95fb12ba648f7f90358f46e99bdfbf26729b84" -dependencies = [ - "memoffset 0.8.0", - "speedy-derive", -] - -[[package]] -name = "speedy-derive" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d395866cb6778625150f77a430cc0af764ce0300f6a3d3413477785fa34b6c7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.16", -] - [[package]] name = "spin" version = "0.5.2" @@ -4728,19 +4696,6 @@ dependencies = [ "der", ] -[[package]] -name = "sqlite-lock" -version = "0.1.0" -dependencies = [ - "anyhow", - "futures", - "matrix-sdk-crypto", - "matrix-sdk-sqlite", - "nix", - "speedy", - "tokio", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" diff --git a/labs/sqlite-lock/Cargo.toml b/labs/sqlite-lock/Cargo.toml deleted file mode 100644 index 4da7bb60707..00000000000 --- a/labs/sqlite-lock/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "sqlite-lock" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -matrix-sdk-sqlite = { path = "../../crates/matrix-sdk-sqlite", features = ["crypto-store"] } -matrix-sdk-crypto = { path = "../../crates/matrix-sdk-crypto" } -nix = "0.26.2" -anyhow.workspace = true -speedy = "0.8.6" -futures = "0.3.28" -tokio = { workspace = true, features = ["rt", "rt-multi-thread"] } diff --git a/labs/sqlite-lock/src/main.rs b/labs/sqlite-lock/src/main.rs deleted file mode 100644 index 1143e387160..00000000000 --- a/labs/sqlite-lock/src/main.rs +++ /dev/null @@ -1,241 +0,0 @@ -use std::{env::temp_dir, path::Path, sync::Arc, time::Duration}; - -use anyhow::Result; -use matrix_sdk_crypto::store::{locks::CryptoStoreLock, DynCryptoStore, IntoCryptoStore as _}; -use matrix_sdk_sqlite::SqliteCryptoStore; -use nix::{ - libc::rand, - sys::wait::wait, - unistd::{close, fork, pipe, read, write}, -}; -use speedy::{Readable, Writable}; -use tokio::{runtime::Runtime, time::sleep}; - -#[derive(Clone, Debug, Writable, Readable)] -enum Command { - WriteValue(String), - ReadValue(String), - Quit, -} - -impl Command { - async fn assert(&self, store: &Arc) -> Result<()> { - match self { - Command::WriteValue(written) => { - // The child must have written the value. - let read = store.get_custom_value(KEY).await?; - assert_eq!(read, Some(written.as_bytes().to_vec())); - } - Command::ReadValue(_read) => { - // The child removes the value after validating it. - let read = store.get_custom_value(KEY).await?; - assert_eq!(read, None); - } - Command::Quit => {} - } - Ok(()) - } -} - -fn write_command(fd: i32, command: Command) -> Result<()> { - eprintln!("parent send: {command:?}"); - let serialized = command.write_to_vec()?; - let len = write(fd, &serialized)?; - assert_eq!(len, serialized.len()); - Ok(()) -} - -fn read_command(fd: i32) -> Result { - let mut buf = vec![0; 1024]; // 1024 bytes enough for anyone - read(fd, &mut buf)?; - let command = Command::read_from_buffer(&buf)?; - eprintln!("child received: {command:?}"); - Ok(command) -} - -const LOCK_KEY: &str = "lock_key"; -const KEY: &str = "custom_key"; -const GENERATION_KEY: &str = "generation"; - -struct CloseChildGuard { - write_pipe: i32, -} - -impl Drop for CloseChildGuard { - fn drop(&mut self) { - write_command(self.write_pipe, Command::Quit).unwrap(); - - let status = wait().unwrap(); - eprintln!("Child status: {status:?}"); - - let _ = close(self.write_pipe); - } -} - -async fn parent_main(path: &Path, write_pipe: i32) -> Result<()> { - let store = SqliteCryptoStore::open(path, None).await?.into_crypto_store(); - let lock_key = LOCK_KEY.to_string(); - - let _close_child_guard = CloseChildGuard { write_pipe }; - - let mut generation = 0; - - // Set initial generation to 0. - store.set_custom_value(GENERATION_KEY, vec![generation]).await?; - - let mut lock = CryptoStoreLock::new(store.clone(), lock_key.clone(), "parent".to_owned(), None); - - loop { - // Write a command. - let val = unsafe { rand() } % 2; - - let id = unsafe { rand() }; - let str = format!("hello {id}"); - - let cmd = match val { - 0 => { - // the child will write, so we remove the value - let cmd = Command::WriteValue(str); - - store.remove_custom_value(KEY).await?; - - write_command(write_pipe, cmd.clone())?; - cmd - } - - 1 => { - // the child will read, so we write the value - store.set_custom_value(KEY, str.as_bytes().to_vec()).await?; - - let cmd = Command::ReadValue(str); - write_command(write_pipe, cmd.clone())?; - cmd - } - - _ => unreachable!(), - }; - - loop { - // Compete with the child to take the lock! - lock.lock().await?; - - let read_generation = - store.get_custom_value(GENERATION_KEY).await?.expect("there's always a generation") - [0]; - - // Check that if we've seen the latest result, based on the generation number - // (any write to the generation indicates somebody else wrote to the - // database). - if generation != read_generation { - // Run assertions here. - cmd.assert(&store).await?; - - generation = read_generation; - - lock.unlock().await?; - break; - } - - println!("parent: waiting..."); - lock.unlock().await?; - - sleep(Duration::from_millis(1)).await; - } - } - - #[allow(unreachable_code)] - Ok(()) -} - -async fn child_main(path: &Path, read_pipe: i32) -> Result<()> { - let store = SqliteCryptoStore::open(path, None).await?.into_crypto_store(); - let lock_key = LOCK_KEY.to_string(); - - let mut lock = CryptoStoreLock::new(store.clone(), lock_key.clone(), "child".to_owned(), None); - - loop { - eprintln!("child waits for command"); - match read_command(read_pipe)? { - Command::WriteValue(val) => { - eprintln!("child received command: write {val}; waiting for lock"); - - lock.lock().await?; - - eprintln!("child got the lock"); - - store.set_custom_value(KEY, val.as_bytes().to_vec()).await?; - - let generation = store.get_custom_value(GENERATION_KEY).await?.unwrap()[0]; - let generation = generation.wrapping_add(1); - store.set_custom_value(GENERATION_KEY, vec![generation]).await?; - - lock.unlock().await?; - } - - Command::ReadValue(expected) => { - eprintln!("child received command: read {expected}; waiting for lock"); - - lock.lock().await?; - - eprintln!("child got the lock"); - - let val = store.get_custom_value(KEY).await?.expect("missing value in child"); - assert_eq!(val, expected.as_bytes()); - - store.remove_custom_value(KEY).await?; - - let generation = store.get_custom_value(GENERATION_KEY).await?.unwrap()[0]; - store.set_custom_value(GENERATION_KEY, vec![generation + 1]).await?; - - lock.unlock().await?; - } - - Command::Quit => { - break; - } - } - } - - close(read_pipe)?; - - Ok(()) -} - -fn main() -> Result<()> { - let path = temp_dir().join("db.sqlite"); - - if path.exists() { - std::fs::remove_dir_all(&path)?; - } - - // Force running migrations first. - { - let rt = Runtime::new()?; - let path = path.clone(); - rt.block_on(async { - let _store = SqliteCryptoStore::open(path, None).await?; - anyhow::Ok(()) - })?; - } - - let (read_pipe, write_pipe) = pipe()?; - - let pid = unsafe { fork() }?; - match pid { - nix::unistd::ForkResult::Parent { .. } => { - // Parent doesn't read. - close(read_pipe)?; - - let rt = Runtime::new()?; - rt.block_on(parent_main(&path, write_pipe)) - } - - nix::unistd::ForkResult::Child => { - // Child doesn't write. - close(write_pipe)?; - - let rt = Runtime::new()?; - rt.block_on(child_main(&path, read_pipe)) - } - } -}