Fix commit status cache which missed target_url (#30426)

Fix #30421

---------

Co-authored-by: Jason Song <i@wolfogre.com>
This commit is contained in:
Lunny Xiao 2024-04-12 19:02:42 +08:00 committed by Michael Kriese
parent 6495741238
commit f393ccf745
No known key found for this signature in database
GPG key ID: F8D7748549A5986A

View file

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs" api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/services/automerge" "code.gitea.io/gitea/services/automerge"
@ -26,12 +27,41 @@ func getCacheKey(repoID int64, brancheName string) string {
return fmt.Sprintf("commit_status:%x", hashBytes) return fmt.Sprintf("commit_status:%x", hashBytes)
} }
func updateCommitStatusCache(ctx context.Context, repoID int64, branchName string, status api.CommitStatusState) error { type commitStatusCacheValue struct {
c := cache.GetCache() State string `json:"state"`
return c.Put(getCacheKey(repoID, branchName), string(status), 3*24*60) TargetURL string `json:"target_url"`
} }
func deleteCommitStatusCache(ctx context.Context, repoID int64, branchName string) error { func getCommitStatusCache(repoID int64, branchName string) *commitStatusCacheValue {
c := cache.GetCache()
statusStr, ok := c.Get(getCacheKey(repoID, branchName)).(string)
if ok && statusStr != "" {
var cv commitStatusCacheValue
err := json.Unmarshal([]byte(statusStr), &cv)
if err == nil && cv.State != "" {
return &cv
}
if err != nil {
log.Warn("getCommitStatusCache: json.Unmarshal failed: %v", err)
}
}
return nil
}
func updateCommitStatusCache(repoID int64, branchName string, state api.CommitStatusState, targetURL string) error {
c := cache.GetCache()
bs, err := json.Marshal(commitStatusCacheValue{
State: state.String(),
TargetURL: targetURL,
})
if err != nil {
log.Warn("updateCommitStatusCache: json.Marshal failed: %v", err)
return nil
}
return c.Put(getCacheKey(repoID, branchName), string(bs), 3*24*60)
}
func deleteCommitStatusCache(repoID int64, branchName string) error {
c := cache.GetCache() c := cache.GetCache()
return c.Delete(getCacheKey(repoID, branchName)) return c.Delete(getCacheKey(repoID, branchName))
} }
@ -81,7 +111,7 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato
} }
if commit.ID.String() == defaultBranchCommit.ID.String() { // since one commit status updated, the combined commit status should be invalid if commit.ID.String() == defaultBranchCommit.ID.String() { // since one commit status updated, the combined commit status should be invalid
if err := deleteCommitStatusCache(ctx, repo.ID, repo.DefaultBranch); err != nil { if err := deleteCommitStatusCache(repo.ID, repo.DefaultBranch); err != nil {
log.Error("deleteCommitStatusCache[%d:%s] failed: %v", repo.ID, repo.DefaultBranch, err) log.Error("deleteCommitStatusCache[%d:%s] failed: %v", repo.ID, repo.DefaultBranch, err)
} }
} }
@ -98,12 +128,12 @@ 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))
c := cache.GetCache()
for i, repo := range repos { for i, repo := range repos {
status, ok := c.Get(getCacheKey(repo.ID, repo.DefaultBranch)).(string) if cv := getCommitStatusCache(repo.ID, repo.DefaultBranch); cv != nil {
if ok && status != "" { results[i] = &git_model.CommitStatus{
results[i] = &git_model.CommitStatus{State: api.CommitStatusState(status)} State: api.CommitStatusState(cv.State),
TargetURL: cv.TargetURL,
}
} }
} }
@ -139,7 +169,7 @@ func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Rep
return repoSHA.RepoID == repo.ID return repoSHA.RepoID == repo.ID
}) })
if results[i].State != "" { if results[i].State != "" {
if err := updateCommitStatusCache(ctx, repo.ID, repo.DefaultBranch, results[i].State); 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)
} }
} }
@ -158,7 +188,7 @@ func FindReposLastestCommitStatuses(ctx context.Context, repos []*repo_model.Rep
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] != nil { if results[i] != nil {
if err := updateCommitStatusCache(ctx, repo.ID, repo.DefaultBranch, results[i].State); 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)
} }
} }