If a repository return no commitstatus, then still cache it but not query it from database (#30700)

The previous repository default branch commit status cache will only
store if the commit status has value. So the repository which have no
any commit status will always be fetched from database.

This PR will store the empty state of commit status of a repository into
cache because the cache will be updated once there is a commit status
stored.
This commit is contained in:
Lunny Xiao 2024-04-25 17:14:23 +08:00 committed by GitHub
parent 4ff54933f8
commit c685eefe4a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 15 additions and 7 deletions

View File

@ -38,12 +38,10 @@ func getCommitStatusCache(repoID int64, branchName string) *commitStatusCacheVal
if ok && statusStr != "" { if ok && statusStr != "" {
var cv commitStatusCacheValue var cv commitStatusCacheValue
err := json.Unmarshal([]byte(statusStr), &cv) err := json.Unmarshal([]byte(statusStr), &cv)
if err == nil && cv.State != "" { if err == nil {
return &cv return &cv
} }
if err != nil { log.Warn("getCommitStatusCache: json.Unmarshal failed: %v", err)
log.Warn("getCommitStatusCache: json.Unmarshal failed: %v", err)
}
} }
return nil return nil
} }
@ -128,15 +126,22 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato
// FindReposLastestCommitStatuses loading repository default branch latest combinded commit status with cache // FindReposLastestCommitStatuses loading repository default branch latest combinded commit status with cache
func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Repository) ([]*git_model.CommitStatus, error) { func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Repository) ([]*git_model.CommitStatus, error) {
results := make([]*git_model.CommitStatus, len(repos)) results := make([]*git_model.CommitStatus, len(repos))
allCached := true
for i, repo := range repos { for i, repo := range repos {
if cv := getCommitStatusCache(repo.ID, repo.DefaultBranch); cv != nil { if cv := getCommitStatusCache(repo.ID, repo.DefaultBranch); cv != nil {
results[i] = &git_model.CommitStatus{ results[i] = &git_model.CommitStatus{
State: api.CommitStatusState(cv.State), State: api.CommitStatusState(cv.State),
TargetURL: cv.TargetURL, TargetURL: cv.TargetURL,
} }
} else {
allCached = false
} }
} }
if allCached {
return results, nil
}
// collect the latest commit of each repo // collect the latest commit of each repo
// at most there are dozens of repos (limited by MaxResponseItems), so it's not a big problem at the moment // at most there are dozens of repos (limited by MaxResponseItems), so it's not a big problem at the moment
repoBranchNames := make(map[int64]string, len(repos)) repoBranchNames := make(map[int64]string, len(repos))
@ -165,10 +170,10 @@ func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Rep
for i, repo := range repos { for i, repo := range repos {
if repo.ID == summary.RepoID { if repo.ID == summary.RepoID {
results[i] = summary results[i] = summary
_ = slices.DeleteFunc(repoSHAs, func(repoSHA git_model.RepoSHA) bool { repoSHAs = slices.DeleteFunc(repoSHAs, func(repoSHA git_model.RepoSHA) bool {
return repoSHA.RepoID == repo.ID return repoSHA.RepoID == repo.ID
}) })
if results[i].State != "" { if results[i] != nil {
if err := updateCommitStatusCache(repo.ID, repo.DefaultBranch, results[i].State, results[i].TargetURL); err != nil { if err := updateCommitStatusCache(repo.ID, repo.DefaultBranch, results[i].State, results[i].TargetURL); err != nil {
log.Error("updateCommitStatusCache[%d:%s] failed: %v", repo.ID, repo.DefaultBranch, err) log.Error("updateCommitStatusCache[%d:%s] failed: %v", repo.ID, repo.DefaultBranch, err)
} }
@ -177,6 +182,9 @@ func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Rep
} }
} }
} }
if len(repoSHAs) == 0 {
return results, nil
}
// call the database O(1) times to get the commit statuses for all repos // call the database O(1) times to get the commit statuses for all repos
repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoSHAs) repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoSHAs)
@ -187,7 +195,7 @@ func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Rep
for i, repo := range repos { for i, repo := range repos {
if results[i] == nil { if results[i] == nil {
results[i] = git_model.CalcCommitStatus(repoToItsLatestCommitStatuses[repo.ID]) results[i] = git_model.CalcCommitStatus(repoToItsLatestCommitStatuses[repo.ID])
if results[i].State != "" { if results[i] != nil {
if err := updateCommitStatusCache(repo.ID, repo.DefaultBranch, results[i].State, results[i].TargetURL); err != nil { if err := updateCommitStatusCache(repo.ID, repo.DefaultBranch, results[i].State, results[i].TargetURL); err != nil {
log.Error("updateCommitStatusCache[%d:%s] failed: %v", repo.ID, repo.DefaultBranch, err) log.Error("updateCommitStatusCache[%d:%s] failed: %v", repo.ID, repo.DefaultBranch, err)
} }