diff options
Diffstat (limited to 'karld/src/schedule.rs')
-rw-r--r-- | karld/src/schedule.rs | 92 |
1 files changed, 72 insertions, 20 deletions
diff --git a/karld/src/schedule.rs b/karld/src/schedule.rs index 971c63a..c30fd5c 100644 --- a/karld/src/schedule.rs +++ b/karld/src/schedule.rs @@ -1,8 +1,14 @@ +use chrono::Utc; use karlcommon::{Condition, Schedule}; +use log::{info, warn}; -use crate::TASKS; +use crate::{ + condition::{ConditionFind, Direction}, + TASKS, +}; pub fn schedule_dynamic() { + info!("starting dynamic scheduling"); let mut tasks = TASKS.write().unwrap(); let mut colliders = vec![]; @@ -24,25 +30,71 @@ pub fn schedule_dynamic() { } }); - let cond = Condition::Invert(box Condition::Or( - colliders - .iter() - .map(|c| match &c.schedule { - Schedule::Never => Condition::Never, - Schedule::Condition(c) => c.clone(), - Schedule::Static(r) => Condition::Range { - min: r.start, - max: r.end, - modulus: None, - prop: karlcommon::Property::Unix, - }, - Schedule::Dynamic { .. } => unreachable!(), - }) - .collect(), - )); - println!("{:?}", cond); + let now = Utc::now().naive_local(); + while let Some(t) = dynamic.pop() { + let props = match &t.schedule { + Schedule::Dynamic { + duration, + condition, + priority, + scheduled, + } => (duration, condition, priority, scheduled), + _ => unreachable!(), + }; - while dynamic.len() != 0 { - todo!() + let duration = + chrono::Duration::from_std(std::time::Duration::from_secs(*props.0 as u64)).unwrap(); + + let cond = Condition::Invert(box Condition::Or( + colliders + .iter() + .map(|c| match &c.schedule { + Schedule::Never => Condition::Never, + Schedule::Condition(c) => c.clone(), + Schedule::Static(r) => Condition::Range { + min: r.start, + max: r.end, + modulus: None, + prop: karlcommon::Property::Unix, + }, + Schedule::Dynamic { scheduled, .. } => match scheduled { + Some(r) => Condition::Range { + min: r.start, + max: r.end, + modulus: None, + prop: karlcommon::Property::Unix, + }, + None => Condition::Never, + }, + }) + .collect(), + )); + + let mut cursor = now; + + let mut found_spot = false; + for _ in 0..256 { + // TODO actually respect the condition and repeat + let free = cond.find_instance(Direction::Forward, cursor); + let p_start = free.start.unwrap_or(now); + let p_end = p_start + duration; + if free.end.map(|e| e >= p_end).unwrap_or(true) { + t.schedule = Schedule::Dynamic { + condition: props.1.clone(), + duration: *props.0, + priority: *props.2, + scheduled: Some(p_start.timestamp()..p_end.timestamp()), + }; + colliders.push(t); + found_spot = true; + break; + } + cursor = free.end.unwrap() + } + if !found_spot { + warn!("could not find a spot where the task fits in"); + } } + drop(tasks); + info!("done"); } |