use std::sync::Arc;
use std::time::Duration;
use async_trait::async_trait;
use tokio::sync::oneshot;
pub mod boot;
pub mod checkpoint;
pub mod pause;
pub mod release;
pub mod restore;
pub mod resume;
use super::effect::ReleaseScope;
use super::event::{Event, RestoreOrigin};
use crate::agent::GuestAgent;
use crate::error::ComputerError;
use crate::sandbox::CheckpointInfo;
use crate::sandbox::record::ComputerProvisionOutcome;
pub type TaskResult<T = ()> = std::result::Result<T, TaskFailure>;
#[derive(Debug)]
pub struct TaskFailure {
event: Event,
error: ComputerError,
}
impl TaskFailure {
pub fn recoverable(error: ComputerError) -> Self {
Self {
event: Event::Failure,
error,
}
}
pub fn frozen(error: ComputerError) -> Self {
Self {
event: Event::Frozen,
error,
}
}
pub fn stranded(error: ComputerError) -> Self {
Self {
event: Event::Stranded,
error,
}
}
pub(super) fn event(&self) -> Event {
self.event.clone()
}
pub(super) fn message(&self) -> String {
self.error.to_string()
}
pub(super) fn into_error(self) -> ComputerError {
self.error
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Drain {
No,
Until {
since: Option<chrono::DateTime<chrono::Utc>>,
},
}
#[derive(Debug, Clone)]
pub struct CaptureSpec {
pub name: String,
pub labels: std::collections::HashMap<String, String>,
}
#[async_trait]
pub trait ComputerTasks: Send + Sync + 'static {
async fn boot(
&self,
warm: bool,
handed_off: oneshot::Sender<()>,
) -> TaskResult<Arc<dyn GuestAgent>>;
async fn gate(&self) -> TaskResult;
async fn restore(
&self,
origin: RestoreOrigin,
) -> TaskResult<(Arc<dyn GuestAgent>, ComputerProvisionOutcome)>;
async fn checkpoint(&self, hold: bool, spec: Option<CaptureSpec>)
-> TaskResult<CheckpointInfo>;
async fn resume(&self) -> TaskResult<Arc<dyn GuestAgent>>;
async fn stop(&self, budget: Duration, drain: Drain) -> TaskResult;
async fn release(&self, scope: ReleaseScope) -> TaskResult;
async fn detach(&self) -> TaskResult;
fn adopted_agent(&self) -> Option<Arc<dyn GuestAgent>>;
}