// TODO: // поддержка питона // резолв адреса управляющего сервера через DoT // кроссплатформенность (реализовать интерфейс для винды и никсов) // проверка обнов // самоуничтожение #[macro_use] extern crate log; extern crate env_logger; use std::env; use tokio::time::{sleep, Duration}; use u_lib::{ api::ClientHandler, builder::JobBuilder, cache::JobCache, executor::pop_completed, models::{AssignedJob, ExecResult}, UID, //daemonize }; #[macro_export] macro_rules! retry_until_ok { ( $body:expr ) => { loop { match $body { Ok(r) => break r, Err(e) => error!("{:?}", e), }; sleep(Duration::from_secs(5)).await; } }; } pub async fn process_request(job_requests: Vec, client: &ClientHandler) { if job_requests.len() > 0 { for jr in &job_requests { if !JobCache::contains(&jr.job_id) { info!("Fetching job: {}", &jr.job_id); let fetched_job = retry_until_ok!(client.get_jobs(Some(jr.job_id)).await) .pop() .unwrap(); JobCache::insert(fetched_job); } } info!( "Scheduling jobs: \n{}", job_requests .iter() .map(|j| j.job_id.to_string()) .collect::>() .join("\n") ); let mut builder = JobBuilder::from_request(job_requests); let errors = builder.pop_errors(); if errors.len() > 0 { error!( "Some errors encountered: \n{}", errors .iter() .map(|j| j.to_string()) .collect::>() .join("\n") ); } builder.unwrap_one().spawn().await; } } pub async fn run_forever() { //daemonize(); env_logger::init(); let arg_ip = env::args().nth(1); let instance = ClientHandler::new(arg_ip.as_deref()); info!("Connecting to the server"); loop { let job_requests: Vec = retry_until_ok!(instance.get_agent_jobs(Some(*UID)).await).into_builtin_vec(); process_request(job_requests, &instance).await; let result: Vec = pop_completed().await.into_iter().collect(); if result.len() > 0 { retry_until_ok!(instance.report(&result).await); } sleep(Duration::from_secs(5)).await; } }