use std::io;
use std::sync::mpsc::{RecvError, SendError};
use serde::Deserialize;
use serde_json::Error as SerdeError;
use thiserror::Error;
use crate::BlobCacheEntry;
#[derive(Error, Debug)]
pub enum MetricsError {
#[error("no counter found for the metric")]
NoCounter,
#[error("failed to serialize metric: {0:?}")]
Serialize(#[source] SerdeError),
}
#[derive(Clone, Deserialize, Debug)]
pub struct ApiMountCmd {
pub source: String,
#[serde(default)]
pub fs_type: String,
pub config: String,
#[serde(default)]
pub prefetch_files: Option<Vec<String>>,
}
#[derive(Clone, Deserialize, Debug)]
pub struct ApiUmountCmd {
pub mountpoint: String,
}
#[derive(Clone, Deserialize, Debug)]
pub struct DaemonConf {
pub log_level: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct BlobCacheObjectId {
#[serde(default)]
pub domain_id: String,
#[serde(default)]
pub blob_id: String,
}
#[derive(Debug)]
pub enum ApiRequest {
ConfigureDaemon(DaemonConf),
GetDaemonInfo,
GetEvents,
Exit,
Start,
SendFuseFd,
TakeoverFuseFd,
Mount(String, ApiMountCmd),
Remount(String, ApiMountCmd),
Umount(String),
ExportBackendMetrics(Option<String>),
ExportBlobcacheMetrics(Option<String>),
ExportFsGlobalMetrics(Option<String>),
ExportFsAccessPatterns(Option<String>),
ExportFsBackendInfo(String),
ExportFsFilesMetrics(Option<String>, bool),
ExportFsInflightMetrics,
GetDaemonInfoV2,
CreateBlobObject(Box<BlobCacheEntry>),
GetBlobObject(BlobCacheObjectId),
DeleteBlobObject(BlobCacheObjectId),
DeleteBlobFile(String),
}
#[derive(Debug)]
pub enum DaemonErrorKind {
NotReady,
Other(String),
Serde(SerdeError),
UnexpectedEvent(String),
UpgradeManager(String),
Unsupported,
}
#[derive(Debug)]
pub enum MetricsErrorKind {
Daemon(DaemonErrorKind),
Stats(MetricsError),
}
#[derive(Error, Debug)]
#[allow(clippy::large_enum_variant)]
pub enum ApiError {
#[error("daemon internal error: {0:?}")]
DaemonAbnormal(DaemonErrorKind),
#[error("daemon events error: {0}")]
Events(String),
#[error("metrics error: {0:?}")]
Metrics(MetricsErrorKind),
#[error("failed to mount filesystem: {0:?}")]
MountFilesystem(DaemonErrorKind),
#[error("failed to send request to the API service: {0:?}")]
RequestSend(#[from] SendError<Option<ApiRequest>>),
#[error("failed to parse response payload type")]
ResponsePayloadType,
#[error("failed to receive response from the API service: {0:?}")]
ResponseRecv(#[from] RecvError),
#[error("failed to wake up the daemon: {0:?}")]
Wakeup(#[source] io::Error),
}
pub type ApiResult<T> = std::result::Result<T, ApiError>;
#[derive(Serialize)]
pub enum ApiResponsePayload {
BackendMetrics(String),
BlobcacheMetrics(String),
DaemonInfo(String),
Empty,
Events(String),
FsGlobalMetrics(String),
FsFilesMetrics(String),
FsFilesPatterns(String),
FsBackendInfo(String),
FsInflightMetrics(String),
BlobObjectList(String),
}
pub type ApiResponse = std::result::Result<ApiResponsePayload, ApiError>;
#[derive(Debug)]
pub enum HttpError {
BadRequest,
Configure(ApiError),
DaemonInfo(ApiError),
Events(ApiError),
NoRoute,
ParseBody(SerdeError),
QueryString(String),
Mount(ApiError),
Upgrade(ApiError),
BackendMetrics(ApiError),
BlobcacheMetrics(ApiError),
FsBackendInfo(ApiError),
FsFilesMetrics(ApiError),
GlobalMetrics(ApiError),
InflightMetrics(ApiError),
Pattern(ApiError),
CreateBlobObject(ApiError),
DeleteBlobObject(ApiError),
DeleteBlobFile(ApiError),
GetBlobObjects(ApiError),
}
#[derive(Serialize, Debug)]
pub(crate) struct ErrorMessage {
pub code: String,
pub message: String,
}
impl From<ErrorMessage> for Vec<u8> {
fn from(msg: ErrorMessage) -> Self {
serde_json::to_vec(&msg).unwrap()
}
}