aboutsummaryrefslogtreecommitdiff
path: root/karld/src/schedule.rs
diff options
context:
space:
mode:
authormetamuffin <yvchraiqi@protonmail.com>2022-06-14 13:58:09 +0200
committermetamuffin <yvchraiqi@protonmail.com>2022-06-14 13:58:09 +0200
commit09ee50601311c802e67e1f7b0a5278c334d2e406 (patch)
tree12325eda3288e08c16ffd85cce0aaa3ff4344be9 /karld/src/schedule.rs
parenta7abc26af31b69db06a5875fc3fbc756adc838b1 (diff)
downloadkarlender-09ee50601311c802e67e1f7b0a5278c334d2e406.tar
karlender-09ee50601311c802e67e1f7b0a5278c334d2e406.tar.bz2
karlender-09ee50601311c802e67e1f7b0a5278c334d2e406.tar.zst
dynamic scheduling
Diffstat (limited to 'karld/src/schedule.rs')
-rw-r--r--karld/src/schedule.rs92
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");
}