Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
463 changes: 142 additions & 321 deletions Cargo.lock

Large diffs are not rendered by default.

79 changes: 58 additions & 21 deletions dispatcher/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,27 @@ use machine_interface::memory_domain::ContextTrait;
use machine_interface::{
composition::{
get_sharding, AnyShardingMode, Composition, CompositionSet, InputSetDescriptor,
JoinStrategy, LocalCompositionSet, RemoteData, ShardingMode,
JoinStrategy, LocalCompositionSet, ShardingMode,
},
function_driver::{Metadata, WorkToDo},
machine_config::{get_available_domains, DomainType, EngineType, IntoEnumIterator},
memory_domain::{MemoryDomain, MemoryResource},
};
use std::{collections::BTreeMap, sync::Arc};
use std::{
collections::BTreeMap,
sync::{atomic::AtomicUsize, Arc},
};

// TODO also here and in registry replace Arc Box with static references from leaked boxes for things we expect to be there for
// the entire execution time anyway
// TODO: the composition ids currently just go up from 0, there is no overflow handling.
// We are not expecting to overflow, but this should be handled for proper deployments.
pub struct Dispatcher {
function_registry: FunctionRegistry,
work_queue: WorkQueue,
domains: Vec<Arc<Box<dyn MemoryDomain>>>,
any_sharding_mode: AnyShardingMode,
composition_id: AtomicUsize,
}

impl Dispatcher {
Expand Down Expand Up @@ -68,9 +74,15 @@ impl Dispatcher {
work_queue,
domains,
any_sharding_mode,
composition_id: AtomicUsize::new(0),
});
}

pub fn get_composition_id(&self) -> usize {
self.composition_id
.fetch_add(1, std::sync::atomic::Ordering::AcqRel)
}

pub fn insert_function(
&self,
function_name: String,
Expand Down Expand Up @@ -105,9 +117,15 @@ impl Dispatcher {
) -> DandelionResult<(Vec<Option<LocalCompositionSet>>, Recorder)> {
debug!("Queuing function {}", function_id);
recorder.record(RecordPoint::EnterDispatcher);

let composition_id = self.get_composition_id();
let results = self
.queue_function(function_id, inputs, caching, recorder.clone())
.queue_function(
composition_id,
function_id,
inputs,
caching,
recorder.clone(),
)
.await?;

// if any set is not local send them trough reference resolution
Expand All @@ -119,9 +137,12 @@ impl Dispatcher {
}
}) {
self.work_queue
.do_work(WorkToDo::SetsToResolve {
input_sets: results,
})
.do_work(
WorkToDo::SetsToResolve {
input_sets: results,
},
composition_id,
)
.await?
.get_composition()
} else {
Expand All @@ -136,13 +157,6 @@ impl Dispatcher {
Ok((local_results, recorder))
}

pub async fn delete_remote_data(&self, remote_data: RemoteData) -> DandelionResult<()> {
self.work_queue
.do_work(WorkToDo::RemoteToDelete { remote_data })
.await
.map(|_| ())
}

pub async fn queue_unregistered_composition(
&self,
composition_desc: String,
Expand All @@ -151,6 +165,7 @@ impl Dispatcher {
recorder: Recorder,
) -> DandelionResult<(Vec<Option<LocalCompositionSet>>, Recorder)> {
debug!("Parsing single use composition");

let composition_meta_pairs = self
.function_registry
.parse_compositions(&composition_desc.as_str())?;
Expand All @@ -164,12 +179,14 @@ impl Dispatcher {
));
}

let composition_id = self.get_composition_id();
debug!(
"Queuing single use composition {}",
composition_meta_pairs[0].0
"Queuing single use composition {} with id {}",
composition_meta_pairs[0].0, composition_id,
);
let results = self
.queue_composition(
composition_id,
composition_meta_pairs[0].1.clone(),
inputs,
caching,
Expand All @@ -186,9 +203,12 @@ impl Dispatcher {
}
}) {
self.work_queue
.do_work(WorkToDo::SetsToResolve {
input_sets: results,
})
.do_work(
WorkToDo::SetsToResolve {
input_sets: results,
},
composition_id,
)
.await?
.get_composition()
} else {
Expand All @@ -211,6 +231,7 @@ impl Dispatcher {
/// * `inputs` vec of input set options, where the index in the vec is the input set number
pub async fn queue_composition(
&self,
composition_id: usize,
composition: Composition,
inputs: Vec<Option<CompositionSet>>,
caching: bool,
Expand Down Expand Up @@ -309,6 +330,7 @@ impl Dispatcher {
// start all functions that are ready and insert their sets into the awaited ones
for args in ready_functions.into_iter() {
awaited_sets.push(Either::Right(self.queue_function_sharded(
composition_id,
args.function_id,
args.function_index,
args.input_sets,
Expand Down Expand Up @@ -389,6 +411,7 @@ impl Dispatcher {
}
if args.missing_sets.is_empty() {
awaited_sets.push(Either::Right(self.queue_function_sharded(
composition_id,
args.function_id,
args.function_index,
args.input_sets,
Expand Down Expand Up @@ -423,6 +446,7 @@ impl Dispatcher {
/// Also handles sharing of sets
async fn queue_function_sharded<'context>(
&self,
composition_id: usize,
function_id: FunctionId,
// index of the function within the composition
function_index: usize,
Expand Down Expand Up @@ -459,6 +483,7 @@ impl Dispatcher {
.map(|ins| {
let new_recorder = Recorder::new_from_parent(function_id.clone(), &recorder);
let future_box = Box::pin(self.queue_function(
composition_id,
function_id.clone(),
ins,
caching,
Expand All @@ -474,7 +499,13 @@ impl Dispatcher {
} else {
let new_recorder = Recorder::new_from_parent(function_id.clone(), &recorder);
let future_box = self
.queue_function(function_id, vec![], caching, new_recorder.clone())
.queue_function(
composition_id,
function_id,
vec![],
caching,
new_recorder.clone(),
)
.await
.and_then(|result| Ok(vec![result]));
recorders = vec![new_recorder];
Expand Down Expand Up @@ -518,6 +549,7 @@ impl Dispatcher {
/// the index describes which output set the composition belongs to.
pub async fn queue_function<'dispatcher>(
&'dispatcher self,
composition_id: usize,
function_id: FunctionId,
input_sets: Vec<Option<CompositionSet>>,
caching: bool,
Expand Down Expand Up @@ -563,7 +595,11 @@ impl Dispatcher {
recorder: recorder.clone(),
};

let sets = self.work_queue.do_work(args).await?.get_composition();
let sets = self
.work_queue
.do_work(args, composition_id)
.await?
.get_composition();
recorder.record(RecordPoint::FutureReturn);

#[cfg(feature = "log_function_stdio")]
Expand Down Expand Up @@ -608,6 +644,7 @@ impl Dispatcher {
}
FunctionType::Composition(comp_info) => {
self.queue_composition(
composition_id,
(*comp_info.composition).clone(),
input_sets,
caching,
Expand Down
Loading
Loading