chore(service/git): minor fixes in service layer git operations
Small adjustments to commit, init, refs, star, and watch operations in the service layer.
This commit is contained in:
parent
64dc27161b
commit
3f1f0d5e23
@ -803,9 +803,20 @@ impl AppService {
|
||||
commits.into_iter().map(CommitMetaResponse::from).collect();
|
||||
|
||||
// Get total count for pagination metadata.
|
||||
// Must use the same cache key format as git_commit_count:
|
||||
// git:commit:count:{namespace}:{repo_name}:{from:?}:{to:?}
|
||||
// where from/to correspond to the rev spec passed to commit_log.
|
||||
let (from, to) = match rev_for_count {
|
||||
Some(rev) if rev.contains("..") => {
|
||||
let parts: Vec<&str> = rev.splitn(2, "..").collect();
|
||||
(Some(parts[0].to_string()), Some(parts[1].to_string()))
|
||||
}
|
||||
Some(rev) => (None, Some(rev)),
|
||||
None => (None, None),
|
||||
};
|
||||
let total_cache_key = format!(
|
||||
"git:commit:count:{}:{}:{:?}",
|
||||
namespace, repo_name, rev_for_count,
|
||||
"git:commit:count:{}:{}:{:?}:{:?}",
|
||||
namespace, repo_name, from, to,
|
||||
);
|
||||
let total: usize = if let Ok(mut conn) = self.cache.conn().await {
|
||||
if let Ok(cached) = conn.get::<_, String>(total_cache_key.clone()).await {
|
||||
@ -1326,7 +1337,7 @@ impl AppService {
|
||||
} else if reverse {
|
||||
CommitSort(CommitSort::TIME.0 | CommitSort::REVERSE.0)
|
||||
} else {
|
||||
CommitSort(CommitSort::TOPOLOGICAL.0 | CommitSort::TIME.0)
|
||||
CommitSort(CommitSort::TIME.0)
|
||||
};
|
||||
|
||||
let commits = git_spawn!(repo, domain -> {
|
||||
|
||||
@ -39,7 +39,7 @@ impl AppService {
|
||||
let domain = git::GitDomain::open_workdir(&path).map_err(AppError::from)?;
|
||||
Ok(GitInitResponse {
|
||||
path: domain.repo().path().to_string_lossy().to_string(),
|
||||
is_bare: true,
|
||||
is_bare: false,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,45 @@ use redis::AsyncCommands;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use session::Session;
|
||||
|
||||
/// Delete all cached ref list entries for a given namespace/repo.
|
||||
/// Redis DEL does not support glob patterns, so we SCAN and delete each key.
|
||||
async fn invalidate_ref_cache(
|
||||
cache: &db::cache::AppCache,
|
||||
namespace: &str,
|
||||
repo_name: &str,
|
||||
) {
|
||||
let prefix = format!("git:ref:list:{}:{}:", namespace, repo_name);
|
||||
if let Ok(mut conn) = cache.conn().await {
|
||||
let pattern = format!("{}*", prefix);
|
||||
let mut cursor: u64 = 0;
|
||||
loop {
|
||||
match redis::cmd("SCAN")
|
||||
.arg(cursor)
|
||||
.arg("MATCH")
|
||||
.arg(&pattern)
|
||||
.arg("COUNT")
|
||||
.arg(100)
|
||||
.query_async::<(u64, Vec<String>)>(&mut conn)
|
||||
.await
|
||||
{
|
||||
Ok((new_cursor, keys)) => {
|
||||
for key in &keys {
|
||||
let _: () = conn.del(key).await.unwrap_or(());
|
||||
}
|
||||
if new_cursor == 0 {
|
||||
break;
|
||||
}
|
||||
cursor = new_cursor;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::debug!(error = ?e, "cache scan failed (non-fatal)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, utoipa::IntoParams)]
|
||||
pub struct RefListQuery {
|
||||
pub pattern: Option<String>,
|
||||
@ -201,12 +240,7 @@ impl AppService {
|
||||
.map_err(|e| AppError::InternalServerError(format!("Task join error: {}", e)))?
|
||||
.map_err(AppError::from)?;
|
||||
|
||||
if let Ok(mut conn) = self.cache.conn().await {
|
||||
let key = format!("git:ref:list:{}:{}:*", namespace, repo_name);
|
||||
if let Err(e) = conn.del::<String, ()>(key).await {
|
||||
tracing::debug!(error = ?e, "cache del failed (non-fatal)");
|
||||
}
|
||||
}
|
||||
invalidate_ref_cache(&self.cache, &namespace, &repo_name).await;
|
||||
|
||||
Ok(RefUpdateResponse {
|
||||
name: result.name,
|
||||
@ -234,12 +268,7 @@ impl AppService {
|
||||
.map_err(|e| AppError::InternalServerError(format!("Task join error: {}", e)))?
|
||||
.map_err(AppError::from)?;
|
||||
|
||||
if let Ok(mut conn) = self.cache.conn().await {
|
||||
let key = format!("git:ref:list:{}:{}:*", namespace, repo_name);
|
||||
if let Err(e) = conn.del::<String, ()>(key).await {
|
||||
tracing::debug!(error = ?e, "cache del failed (non-fatal)");
|
||||
}
|
||||
}
|
||||
invalidate_ref_cache(&self.cache, &namespace, &repo_name).await;
|
||||
|
||||
Ok(RefDeleteResponse {
|
||||
name,
|
||||
@ -269,12 +298,7 @@ impl AppService {
|
||||
.map_err(|e| AppError::InternalServerError(format!("Task join error: {}", e)))?
|
||||
.map_err(AppError::from)?;
|
||||
|
||||
if let Ok(mut conn) = self.cache.conn().await {
|
||||
let key = format!("git:ref:list:{}:{}:*", namespace, repo_name);
|
||||
if let Err(e) = conn.del::<String, ()>(key).await {
|
||||
tracing::debug!(error = ?e, "cache del failed (non-fatal)");
|
||||
}
|
||||
}
|
||||
invalidate_ref_cache(&self.cache, &namespace, &repo_name).await;
|
||||
|
||||
Ok(RefInfoResponse::from(info))
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ impl AppService {
|
||||
.one(&self.db)
|
||||
.await?;
|
||||
if existing.is_some() {
|
||||
return Err(AppError::InternalServerError("already starred".to_string()));
|
||||
return Err(AppError::Conflict("already starred".to_string()));
|
||||
}
|
||||
RepoStar::insert(repo_star::ActiveModel {
|
||||
id: Default::default(),
|
||||
@ -97,7 +97,7 @@ impl AppService {
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
if deleted.rows_affected == 0 {
|
||||
return Err(AppError::InternalServerError("not starred".to_string()));
|
||||
return Err(AppError::NotFound("not starred".to_string()));
|
||||
}
|
||||
let project_id = match repo_model::Entity::find_by_id(repo.id).one(&self.db).await {
|
||||
Ok(Some(r)) => r.project,
|
||||
|
||||
@ -51,9 +51,7 @@ impl AppService {
|
||||
.one(&self.db)
|
||||
.await?;
|
||||
if existing.is_some() {
|
||||
return Err(AppError::InternalServerError(
|
||||
"already watching".to_string(),
|
||||
));
|
||||
return Err(AppError::Conflict("already watching".to_string()));
|
||||
}
|
||||
RepoWatch::insert(repo_watch::ActiveModel {
|
||||
id: Default::default(),
|
||||
@ -110,7 +108,7 @@ impl AppService {
|
||||
.exec(&self.db)
|
||||
.await?;
|
||||
if deleted.rows_affected == 0 {
|
||||
return Err(AppError::InternalServerError("not watching".to_string()));
|
||||
return Err(AppError::NotFound("not watching".to_string()));
|
||||
}
|
||||
let project_id = match repo_model::Entity::find_by_id(repo.id).one(&self.db).await {
|
||||
Ok(Some(r)) => r.project,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user