diff --git a/project/src/main.rs b/project/src/main.rs index e7a11a9..0792247 100644 --- a/project/src/main.rs +++ b/project/src/main.rs @@ -1,3 +1,92 @@ -fn main() { - println!("Hello, world!"); +// Libraries +use std::sync::{Arc, Mutex}; +use std::error::Error; +use tokio::{self, task}; + +mod base; +mod updater; +mod api; + +use updater::Updater; +use base::conf::Conf; +use base::database::Database; +use api::API; + +// Functions +async fn handle_updating(updater: Arc>, conf: Arc) -> Result<(), Box> { + // Tracking all Symbols + let tracked_symbols: Vec = conf.get_arr_str("general.tracked")?; + + // Iterating through all tracked symbols + let update_futures = tracked_symbols.iter().filter_map(|symbol: &String| { + // Cloning Mutexes + let updater: Arc> = Arc::clone(&updater); + let conf: Arc = Arc::clone(&conf); + let symbol: String = symbol.clone(); + + // Checking if we need to be updated + let needs_update: bool; + { + let mut l_updater: std::sync::MutexGuard<'_, Updater> = updater.lock().unwrap(); + needs_update = l_updater.needs_update(&conf, &symbol).unwrap_or(false); + } + + // Should it be updated? + if needs_update { + // Spawning a new thread + Some(tokio::spawn(async move { + // Telling updater to pull that stock + let mut l_updater: std::sync::MutexGuard<'_, Updater> = updater.lock().unwrap(); + l_updater.pull_symbol(&conf, &symbol).unwrap(); + })) + } else { + None + } + }); + + // Awaiting all futures + for fut in update_futures { + fut.await?; + } + + // Returning with Ok + return Ok(()); +} + +// Entry Point +#[tokio::main] +async fn main() -> Result<(), Box> { + // Initilization & Configuration + let a_conf: Arc = Arc::new(Conf::init("data/settings.yaml")?); + let a_db: Arc> = Arc::new(Mutex::new(base::init_db(&a_conf)?)); + + // Creating Manager + let m_updater: Arc> = Arc::new(Mutex::new(Updater::init(&a_conf, Arc::clone(&a_db))?)); + + // Creating an API + let a_api: Arc = Arc::new(API::init(&a_conf, Arc::clone(&a_db))?); + + // Starting the server + let api_future: task::JoinHandle<()> = a_api.start(Arc::clone(&a_api))?; + + // Combining all futures + tokio::join!( + async { + // API + if let Err(e) = api_future.await { + eprintln!("Main> Issue running api ({})", e); + } + }, + async { + // Updater + loop { + if let Err(e) = handle_updating(Arc::clone(&m_updater), Arc::clone(&a_conf)).await { + eprintln!("Main> Issue running updater ({})", e); + } + } + } + ); + + // Program loop + loop {} }