use async_trait::async_trait;
use crate::state::LambdaFunction;
#[derive(Debug, thiserror::Error)]
pub enum RuntimeError {
#[error("no code ZIP provided for function {0}")]
NoCodeZip(String),
#[error("unsupported runtime: {0}")]
UnsupportedRuntime(String),
#[error("container failed to start: {0}")]
ContainerStartFailed(String),
#[error("invocation failed: {0}")]
InvocationFailed(String),
#[error("ZIP extraction failed: {0}")]
ZipExtractionFailed(String),
}
#[derive(Debug, Clone)]
pub enum BackendHandle {
Container { id: String },
Pod { namespace: String, name: String },
}
#[derive(Debug, Clone)]
pub struct WarmInstance {
pub endpoint: String,
pub handle: BackendHandle,
}
pub struct StreamingInvocation {
pub(crate) resp: reqwest::Response,
}
impl StreamingInvocation {
pub async fn next_chunk(&mut self) -> Result<Option<bytes::Bytes>, RuntimeError> {
match self.resp.chunk().await {
Ok(Some(b)) => Ok(Some(b)),
Ok(None) => Ok(None),
Err(e) => Err(RuntimeError::InvocationFailed(e.to_string())),
}
}
}
#[async_trait]
pub trait LambdaBackend: Send + Sync + 'static {
fn name(&self) -> &str;
async fn launch(
&self,
func: &LambdaFunction,
code_zip: Option<&[u8]>,
layers: &[Vec<u8>],
deploy_id: &str,
) -> Result<WarmInstance, RuntimeError>;
async fn terminate(&self, handle: &BackendHandle);
async fn reap_stale(&self) {}
}