diff --git a/.gitignore b/.gitignore index 4032def..0631b18 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ /*.txt /players.redb -/players.json +/players.json* diff --git a/sdgb-cli/src/main.rs b/sdgb-cli/src/main.rs index f2594f5..e878f51 100644 --- a/sdgb-cli/src/main.rs +++ b/sdgb-cli/src/main.rs @@ -39,8 +39,13 @@ async fn main() -> Result<(), Box> { } ctrlc::set_handler(|| { - warn!("received early-quit request! will abort soon"); - EARLY_QUIT.store(true, Ordering::Relaxed); + if EARLY_QUIT.load(Ordering::Relaxed) { + error!("force-quit triggered!"); + std::process::exit(1); + } else { + warn!("received early-quit request! will abort soon"); + EARLY_QUIT.store(true, Ordering::Relaxed); + } })?; let Cli { command } = ::parse(); @@ -105,46 +110,54 @@ async fn main() -> Result<(), Box> { #[cfg(feature = "fetchall")] commands::Commands::ListAllUser { concurrency } => { use futures_util::StreamExt; - use redb::ReadableTable; use sdgb_api::bincode::borrow_decode_from_slice; use std::io::{self, BufRead}; - let mut stdin = io::stdin().lock(); - let mut buf = String::new(); let mut user_ids = Vec::new(); + { + let mut stdin = io::stdin().lock(); + let mut buf = String::new(); - while stdin.read_line(&mut buf).is_ok_and(|size| size != 0) { - if buf.is_empty() { - continue; + while stdin.read_line(&mut buf).is_ok_and(|size| size != 0) { + if buf.is_empty() { + continue; + } + + let user_id: u32 = buf.trim().parse()?; + buf.clear(); + user_ids.push(user_id); } - - let user_id: u32 = buf.trim().parse()?; - buf.clear(); - user_ids.push(user_id); } let _ = cache::init_db(); + let read = cache::read_txn()?; let write = cache::write_txn()?; let config = sdgb_api::bincode::config::Configuration::< sdgb_api::bincode::config::LittleEndian, >::default() .with_no_limit(); - let _ = futures_util::stream::iter(user_ids) - .map(async |user_id| { - let cache_table = cache::open_table(&write)?; - let data = cache_table.get(user_id)?; - if let Some(data) = data { - let decoded: (GetUserPreviewApiResp, _) = - borrow_decode_from_slice(&data.value(), config)?; + info!("number of user_id: {}", user_ids.len()); - return Ok(decoded.0); + let collect = futures_util::stream::iter(user_ids) + .map(async |user_id| { + { + let cache_table = cache::open_table_read(&read)?; + let data = cache_table.get(user_id)?; + if let Some(data) = data { + let decoded: (GetUserPreviewApiResp, _) = + borrow_decode_from_slice(&data.value(), config)?; + + return Ok(decoded.0); + } } if EARLY_QUIT.load(Ordering::Relaxed) { return Err("early skip due to ctrl-c")?; } + info!("processing: {user_id}"); + let resp = Sdgb1_50::request::<_, GetUserPreviewApiResp>( &client, APIMethod::GetUserPreviewApi, @@ -155,8 +168,6 @@ async fn main() -> Result<(), Box> { match &resp { Ok(resp) => { - info!("preview: {user_id} succeed"); - use sdgb_api::bincode::encode_to_vec; if let Ok(mut table) = cache::open_table(&write) @@ -179,12 +190,13 @@ async fn main() -> Result<(), Box> { .filter_map(async |r| r.ok()) .collect::>() .await; + drop(collect); let _ = write.commit(); } #[cfg(feature = "fetchall")] commands::Commands::ListAllUserDump { .. } => { - use std::fs::OpenOptions; + use std::{fs::OpenOptions, io::BufWriter}; use redb::ReadableTable; use sdgb_api::bincode::{self, borrow_decode_from_slice}; @@ -211,7 +223,8 @@ async fn main() -> Result<(), Box> { .write(true) .open("players.json")?; file.lock()?; - serde_json::to_writer(file, &user_ids)?; + let writer = BufWriter::new(file); + serde_json::to_writer(writer, &user_ids)?; } commands::Commands::Userdata { user_id } => {