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, 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 = 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 = 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), } } }