Simplifying action and task reference a bit, fixing some logic errors, and adding in runner message queue polling

This commit is contained in:
Kinesin Data Technologies Incorporated
2022-10-06 14:20:23 -03:00
parent ce621dc9d5
commit 2c96b16ec8
7 changed files with 241 additions and 212 deletions
+53 -21
View File
@@ -3,28 +3,67 @@ use std::convert::From;
use std::ops::{Deref, DerefMut};
#[derive(Clone, Debug)]
pub struct TaskSet(HashMap<String, Task>);
pub struct TaskSet(Vec<Task>);
impl TaskSet {
pub fn new() -> Self {
TaskSet(HashMap::new())
TaskSet(Vec::new())
}
pub fn coverage(&self) -> Result<ResourceInterval> {
pub fn coverage(&self) -> ResourceInterval {
self.get_state(MAX_TIME)
}
pub fn validate(&self) -> Result<()> {
self.get_state(MAX_TIME)?;
let state = self.coverage();
for task in &self.0 {
for resource in task.requires_resources() {
if !state.contains_key(&resource) {
return Err(anyhow!(
"Task {} requires resource {}, which isn't produced.",
task.name,
resource
));
}
}
}
// validate that no task generates the same resource on overlapping times
let providers: HashMap<Resource, Vec<usize>> =
self.0
.iter()
.enumerate()
.fold(HashMap::new(), |mut acc, (idx, t)| {
for res in &t.provides {
acc.entry(res.clone()).or_insert(Vec::new()).push(idx)
}
acc
});
for (res, tids) in providers {
let mut is = IntervalSet::new();
for tid in tids {
let already_provided = is.intersection(&self.0[tid].valid_over);
if !already_provided.is_empty() {
return Err(anyhow!(
"Task set invalid: multiple tasks provide resource {} on the intervals {:?}",
res,
already_provided
));
}
is.merge(&self.0[tid].valid_over);
}
}
Ok(())
}
pub fn get_state<T: TimeZone>(&self, time: DateTime<T>) -> Result<ResourceInterval> {
pub fn get_state<T: TimeZone>(&self, time: DateTime<T>) -> ResourceInterval {
let mut res = ResourceInterval::new();
// Insert all of the covered items
for task in self.values() {
// TODO Need to align each of these intervals with a scheduled time
for task in &self.0 {
// Need to align each of these intervals with a scheduled time
let timeline = if time < MAX_TIME {
let cur_intv = task.schedule.interval(time.clone(), 0);
if cur_intv.end > time {
@@ -37,25 +76,18 @@ impl TaskSet {
};
let task_timeline = task.valid_over.intersection(&timeline);
for resource in &task.provides {
let ris = res.entry(resource.clone()).or_insert(IntervalSet::new());
let already_provided = ris.intersection(&task_timeline);
if !already_provided.is_empty() {
return Err(anyhow!(
"Task set invalid: multiple tasks provide resource {} on the intervals {:?}",
resource,
already_provided
));
}
ris.merge(&task_timeline);
res.entry(resource.clone())
.or_insert(IntervalSet::new())
.merge(&task_timeline);
}
}
Ok(res)
res
}
}
impl Deref for TaskSet {
type Target = HashMap<String, Task>;
type Target = Vec<Task>;
fn deref(&self) -> &Self::Target {
&self.0
}
@@ -67,8 +99,8 @@ impl DerefMut for TaskSet {
}
}
impl From<HashMap<String, Task>> for TaskSet {
fn from(data: HashMap<String, Task>) -> Self {
impl From<Vec<Task>> for TaskSet {
fn from(data: Vec<Task>) -> Self {
Self(data)
}
}