use mongodb::{Client, options::{ClientOptions, Credential}, Collection}; use std::time::{self, SystemTime, Duration}; use tokio::task; use std::sync::Mutex; use std::sync::Arc; mod packet; use packet::Packet; #[tokio::main] async fn main() { // Parse a connection string into an options struct. let mut client_options = ClientOptions::parse("mongodb://localhost:27017").await.unwrap(); // Manually set an option. client_options.app_name = Some("My App".to_string()); let credential_builder = Credential::builder() .username(String::from(env!("mongo_username"))) .password(String::from(env!("mongo_password"))); client_options.credential = Some(credential_builder.build()); // Get a handle to the deployment. let client = Client::with_options(client_options).unwrap(); let db = client.database("test"); match db.create_collection("test", None).await { Err(_) => { db.collection::("test").drop(None).await.unwrap(); }, _ => {} } //Setup the number of queries that we want to run as well as Arcs and Mutexes to pass to threads const NUM_QUERIES: u32 = 5_000; let collection: Arc> = Arc::new(db.collection::("test")); let mut tasks = vec![]; let queries: Arc>> = Arc::new(Mutex::new(vec![])); let start_time = SystemTime::now(); //Start spawning threads to run the requests for _ in 0..NUM_QUERIES { tasks.push(task::spawn(run_query(collection.clone(), queries.clone()))) } futures::future::join_all(tasks).await; //Print out the results for (i, duration) in queries.lock().unwrap().iter().enumerate() { println!("{}: {}.{} milliseconds", i, duration.as_millis(), duration.as_micros()); } println!("Ran {} queries in {}s", NUM_QUERIES, time::SystemTime::now().duration_since(start_time).unwrap().as_secs_f32()); } /// Function that runs an upload to a a MongoDB collection with a recorded timestamp /// asynchronously async fn run_query(collection: Arc>, query_records: Arc>>) { //Record the start time for a query let query_time = SystemTime::now(); //Perform the insert collection.insert_one(Packet{ time: SystemTime::now(), text: format!("Current Unix time: {:?}", SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap()) }, None).await.unwrap(); //Record the duration and add it to the list let duration = SystemTime::now().duration_since(query_time).unwrap(); query_records.lock().unwrap().push(duration); }