use tokio::sync::{mpsc, oneshot};
use crate::{
TaskOutcome,
controller::{ControllerError, ControllerSpec},
identity::TaskId,
};
use super::{
super::{ControllerCommand, Submission},
ControllerHandle,
};
impl ControllerHandle {
#[cfg(test)]
pub async fn submit(&self, spec: ControllerSpec) -> Result<TaskId, ControllerError> {
let id = TaskId::next();
self.submit_prepared(id, spec).await
}
pub(crate) async fn submit_prepared(
&self,
id: TaskId,
spec: ControllerSpec,
) -> Result<TaskId, ControllerError> {
let owned = self.own(spec).await?;
self.tx
.send(ControllerCommand::Submit(Box::new(Submission {
id,
owned,
done: None,
})))
.await
.map_err(|_| ControllerError::Closed)?;
Ok(id)
}
#[cfg(test)]
pub fn try_submit(&self, spec: ControllerSpec) -> Result<TaskId, ControllerError> {
let id = TaskId::next();
self.try_submit_prepared(id, spec)
}
pub(crate) fn try_submit_prepared(
&self,
id: TaskId,
spec: ControllerSpec,
) -> Result<TaskId, ControllerError> {
let permit = self.tx.try_reserve().map_err(|error| match error {
mpsc::error::TrySendError::Full(()) => ControllerError::Full,
mpsc::error::TrySendError::Closed(()) => ControllerError::Closed,
})?;
let owned = self.try_own(spec)?;
permit.send(ControllerCommand::Submit(Box::new(Submission {
id,
owned,
done: None,
})));
Ok(id)
}
#[cfg(test)]
pub async fn submit_and_watch(
&self,
spec: ControllerSpec,
) -> Result<(TaskId, oneshot::Receiver<TaskOutcome>), ControllerError> {
let id = TaskId::next();
self.submit_prepared_and_watch(id, spec).await
}
pub(crate) async fn submit_prepared_and_watch(
&self,
id: TaskId,
spec: ControllerSpec,
) -> Result<(TaskId, oneshot::Receiver<TaskOutcome>), ControllerError> {
let owned = self.own(spec).await?;
let (tx, rx) = oneshot::channel();
self.tx
.send(ControllerCommand::Submit(Box::new(Submission {
id,
owned,
done: Some(tx),
})))
.await
.map_err(|_| ControllerError::Closed)?;
Ok((id, rx))
}
#[cfg(test)]
pub fn try_submit_and_watch(
&self,
spec: ControllerSpec,
) -> Result<(TaskId, oneshot::Receiver<TaskOutcome>), ControllerError> {
let id = TaskId::next();
self.try_submit_prepared_and_watch(id, spec)
}
pub(crate) fn try_submit_prepared_and_watch(
&self,
id: TaskId,
spec: ControllerSpec,
) -> Result<(TaskId, oneshot::Receiver<TaskOutcome>), ControllerError> {
let permit = self.tx.try_reserve().map_err(|error| match error {
mpsc::error::TrySendError::Full(()) => ControllerError::Full,
mpsc::error::TrySendError::Closed(()) => ControllerError::Closed,
})?;
let owned = self.try_own(spec)?;
let (tx, rx) = oneshot::channel();
permit.send(ControllerCommand::Submit(Box::new(Submission {
id,
owned,
done: Some(tx),
})));
Ok((id, rx))
}
}