From a706fc6e3a811e4443deb5385f58893c52d5496b Mon Sep 17 00:00:00 2001 From: Mike Dilger Date: Thu, 25 Jul 2024 11:45:17 +1200 Subject: [PATCH] Rapid command (run in fast but potentially unsafe LMDB syncing mode) --- gossip-bin/src/commands.rs | 9 +++++++-- gossip-bin/src/main.rs | 24 +++++++++++++++++++++--- gossip-lib/src/lib.rs | 4 ++-- gossip-lib/src/storage/mod.rs | 17 +++++++++++++++-- 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/gossip-bin/src/commands.rs b/gossip-bin/src/commands.rs index c4677786..45b2ab3c 100644 --- a/gossip-bin/src/commands.rs +++ b/gossip-bin/src/commands.rs @@ -25,7 +25,7 @@ impl Command { } } -const COMMANDS: [Command; 36] = [ +const COMMANDS: [Command; 37] = [ Command { cmd: "oneshot", usage_params: "{depends}", @@ -166,6 +166,11 @@ const COMMANDS: [Command; 36] = [ usage_params: "", desc: "print the relays the event was seen on", }, + Command { + cmd: "rapid", + usage_params: "", + desc: "Use much faster disk access. A crash can corrupt your local data, unless your filesystem preserves write ordering", + }, Command { cmd: "rebuild_indices", usage_params: "", @@ -209,7 +214,6 @@ const COMMANDS: [Command; 36] = [ ]; pub fn handle_command(mut args: env::Args, runtime: &Runtime) -> Result { - let _ = args.next(); // program name let command_string = args.next().unwrap(); // must be there or we would not have been called let mut command: Option = None; @@ -259,6 +263,7 @@ pub fn handle_command(mut args: env::Args, runtime: &Runtime) -> Result print_relay(command, args)?, "print_relays" => print_relays(command)?, "print_seen_on" => print_seen_on(command, args)?, + "rapid" => {} // is handled early in main.rs "rebuild_indices" => rebuild_indices()?, "rename_person_list" => rename_person_list(command, args)?, "reprocess_recent" => reprocess_recent(command, runtime)?, diff --git a/gossip-bin/src/main.rs b/gossip-bin/src/main.rs index 2c4bbd36..e26b7bc1 100644 --- a/gossip-bin/src/main.rs +++ b/gossip-bin/src/main.rs @@ -43,8 +43,27 @@ fn main() -> Result<(), Error> { let about = about::About::new(); println!("Gossip {}", about.version); + // Handle rapid command before initializing the lib + let mut rapid: bool = false; + { + let mut args = env::args(); + let _ = args.next(); // program name + if let Some(cmd) = args.next() { + if &*cmd == "rapid" { + rapid = true; + } + } + } + + // restart args + let mut args = env::args(); + let _ = args.next(); // program name + if rapid { + let _ = args.next(); // rapid param + } + // Initialize the lib - gossip_lib::init()?; + gossip_lib::init(rapid)?; // Setup async // We create and enter the runtime on the main thread so that @@ -54,8 +73,7 @@ fn main() -> Result<(), Error> { let _main_rt = rt.enter(); // <-- this allows it. // If we were handed a command, execute the command and return - let args = env::args(); - if args.len() > 1 { + if args.len() > 0 { match commands::handle_command(args, &rt) { Err(e) => { println!("{}", e); diff --git a/gossip-lib/src/lib.rs b/gossip-lib/src/lib.rs index 2389e250..cff1c3bf 100644 --- a/gossip-lib/src/lib.rs +++ b/gossip-lib/src/lib.rs @@ -198,11 +198,11 @@ impl std::convert::TryFrom for RunState { } /// Initialize gossip-lib -pub fn init() -> Result<(), Error> { +pub fn init(rapid: bool) -> Result<(), Error> { use std::sync::atomic::Ordering; // Initialize storage - GLOBALS.storage.init()?; + GLOBALS.storage.init(rapid)?; // Load signer from settings GLOBALS.identity.load()?; diff --git a/gossip-lib/src/storage/mod.rs b/gossip-lib/src/storage/mod.rs index 3973eb89..06e3fe5c 100644 --- a/gossip-lib/src/storage/mod.rs +++ b/gossip-lib/src/storage/mod.rs @@ -94,13 +94,26 @@ impl Storage { /// Run this after GLOBALS lazy static initialisation, so functions within storage can /// access GLOBALS without hanging. - pub fn init(&self) -> Result<(), Error> { + pub fn init(&self, rapid: bool) -> Result<(), Error> { let mut builder = EnvOpenOptions::new(); + + let flags = if rapid { + tracing::warn!("Storage using rapid config - data corruption is possible on crash"); + EnvFlags::NO_TLS + | EnvFlags::NO_META_SYNC + | EnvFlags::WRITE_MAP + | EnvFlags::NO_SYNC + | EnvFlags::MAP_ASYNC + } else { + EnvFlags::NO_TLS | EnvFlags::NO_META_SYNC + }; + unsafe { - builder.flags(EnvFlags::NO_TLS | EnvFlags::NO_META_SYNC); + builder.flags(flags); // See flats at http://www.lmdb.tech/doc/group__mdb__env.html // See flags at http://www.lmdb.tech/doc/group__mdb.html (more detail) } + // builder.max_readers(126); // this is the default builder.max_dbs(32);