gitdataai/libs/git/hook/sync/status.rs
2026-04-15 09:08:09 +08:00

99 lines
3.2 KiB
Rust

use crate::GitError;
use crate::hook::sync::HookMetaDataSync;
#[derive(Debug, Clone)]
pub enum SyncStatus {
Pending,
Processing,
Success,
Failed(String),
}
impl std::fmt::Display for SyncStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SyncStatus::Pending => write!(f, "pending"),
SyncStatus::Processing => write!(f, "processing"),
SyncStatus::Success => write!(f, "success"),
SyncStatus::Failed(_) => write!(f, "failed"),
}
}
}
impl HookMetaDataSync {
const STATUS_TTL_SECS: u64 = 86400;
pub async fn update_sync_status(&self, status: SyncStatus) -> Result<(), GitError> {
let key = format!("git:repo:sync_status:{}", self.repo.id);
let status_str = status.to_string();
let mut conn = self
.cache
.conn()
.await
.map_err(|e| GitError::IoError(format!("failed to get redis connection: {}", e)))?;
let _: () = redis::cmd("SETEX")
.arg(&key)
.arg(Self::STATUS_TTL_SECS)
.arg(&status_str)
.query_async(&mut conn)
.await
.map_err(|e| GitError::IoError(format!("failed to set sync status: {}", e)))?;
if let SyncStatus::Failed(ref error_msg) = status {
let error_key = format!("git:repo:sync_error:{}", self.repo.id);
let _: () = redis::cmd("SETEX")
.arg(&error_key)
.arg(Self::STATUS_TTL_SECS)
.arg(error_msg)
.query_async(&mut conn)
.await
.map_err(|e| GitError::IoError(format!("failed to set sync error: {}", e)))?;
}
Ok(())
}
pub async fn get_sync_status(&self) -> Result<Option<SyncStatus>, GitError> {
let key = format!("git:repo:sync_status:{}", self.repo.id);
let error_key = format!("git:repo:sync_error:{}", self.repo.id);
let mut conn = self
.cache
.conn()
.await
.map_err(|e| GitError::IoError(format!("failed to get redis connection: {}", e)))?;
let status_str: Option<String> =
redis::cmd("GET")
.arg(&key)
.query_async(&mut conn)
.await
.map_err(|e| GitError::IoError(format!("failed to get sync status: {}", e)))?;
match status_str {
Some(status) => {
let error_msg: Option<String> = redis::cmd("GET")
.arg(&error_key)
.query_async(&mut conn)
.await
.map_err(|e| GitError::IoError(format!("failed to get sync error: {}", e)))?;
let sync_status = match status.as_str() {
"pending" => SyncStatus::Pending,
"processing" => SyncStatus::Processing,
"success" => SyncStatus::Success,
"failed" => {
SyncStatus::Failed(error_msg.unwrap_or_else(|| "Unknown error".to_string()))
}
_ => SyncStatus::Pending,
};
Ok(Some(sync_status))
}
None => Ok(None),
}
}
}