use std::time::Duration;
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.send_owned_prepared(id, owned, None).await
}
pub(crate) async fn submit_prepared_with_ownership_timeout(
&self,
id: TaskId,
spec: ControllerSpec,
wait_for: Duration,
) -> Result<TaskId, ControllerError> {
let owned = self.own_with_ownership_timeout(spec, wait_for).await?;
self.send_owned_prepared(id, owned, None).await
}
async fn send_owned_prepared(
&self,
id: TaskId,
owned: crate::core::deferred_drop::OwnedTask<ControllerSpec>,
done: Option<oneshot::Sender<TaskOutcome>>,
) -> Result<TaskId, ControllerError> {
self.tx
.send(ControllerCommand::Submit(Box::new(Submission {
id,
owned,
done,
})))
.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?;
self.send_owned_prepared_and_watch(id, owned).await
}
pub(crate) async fn submit_prepared_and_watch_with_ownership_timeout(
&self,
id: TaskId,
spec: ControllerSpec,
wait_for: Duration,
) -> Result<(TaskId, oneshot::Receiver<TaskOutcome>), ControllerError> {
let owned = self.own_with_ownership_timeout(spec, wait_for).await?;
self.send_owned_prepared_and_watch(id, owned).await
}
async fn send_owned_prepared_and_watch(
&self,
id: TaskId,
owned: crate::core::deferred_drop::OwnedTask<ControllerSpec>,
) -> Result<(TaskId, oneshot::Receiver<TaskOutcome>), ControllerError> {
let (tx, rx) = oneshot::channel();
self.send_owned_prepared(id, owned, Some(tx)).await?;
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))
}
}