forked from gitea/gitea
Add cache for branch divergence on branch list page (#29577)
The branch page for blender project will take 6s because calculating divergence is very slow. This PR will add a cache for the branch divergence calculation. So when the second visit the branch list, it will take only less 200ms.
This commit is contained in:
parent
f219ea8d0e
commit
930bae2300
|
@ -16,9 +16,11 @@ import (
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
|
"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/graceful"
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
|
"code.gitea.io/gitea/modules/json"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/optional"
|
"code.gitea.io/gitea/modules/optional"
|
||||||
"code.gitea.io/gitea/modules/queue"
|
"code.gitea.io/gitea/modules/queue"
|
||||||
|
@ -99,7 +101,6 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
|
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
branches = append(branches, branch)
|
branches = append(branches, branch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,10 +110,44 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
|
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultBranch, branches, totalNumOfBranches, nil
|
return defaultBranch, branches, totalNumOfBranches, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getDivergenceCacheKey(repoID int64, branchName string) string {
|
||||||
|
return fmt.Sprintf("%d-%s", repoID, branchName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDivergenceFromCache gets the divergence from cache
|
||||||
|
func getDivergenceFromCache(repoID int64, branchName string) (*git.DivergeObject, bool) {
|
||||||
|
data := cache.GetCache().Get(getDivergenceCacheKey(repoID, branchName))
|
||||||
|
res := git.DivergeObject{
|
||||||
|
Ahead: -1,
|
||||||
|
Behind: -1,
|
||||||
|
}
|
||||||
|
s, ok := data.([]byte)
|
||||||
|
if !ok || len(s) == 0 {
|
||||||
|
return &res, false
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(s, &res); err != nil {
|
||||||
|
log.Error("json.UnMarshal failed: %v", err)
|
||||||
|
return &res, false
|
||||||
|
}
|
||||||
|
return &res, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func putDivergenceFromCache(repoID int64, branchName string, divergence *git.DivergeObject) error {
|
||||||
|
bs, err := json.Marshal(divergence)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cache.GetCache().Put(getDivergenceCacheKey(repoID, branchName), bs, 30*24*60*60)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DelDivergenceFromCache(repoID int64, branchName string) error {
|
||||||
|
return cache.GetCache().Delete(getDivergenceCacheKey(repoID, branchName))
|
||||||
|
}
|
||||||
|
|
||||||
func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *git_model.Branch, protectedBranches *git_model.ProtectedBranchRules,
|
func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *git_model.Branch, protectedBranches *git_model.ProtectedBranchRules,
|
||||||
repoIDToRepo map[int64]*repo_model.Repository,
|
repoIDToRepo map[int64]*repo_model.Repository,
|
||||||
repoIDToGitRepo map[int64]*git.Repository,
|
repoIDToGitRepo map[int64]*git.Repository,
|
||||||
|
@ -130,10 +165,18 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g
|
||||||
|
|
||||||
// it's not default branch
|
// it's not default branch
|
||||||
if repo.DefaultBranch != dbBranch.Name && !dbBranch.IsDeleted {
|
if repo.DefaultBranch != dbBranch.Name && !dbBranch.IsDeleted {
|
||||||
var err error
|
var cached bool
|
||||||
divergence, err = files_service.CountDivergingCommits(ctx, repo, git.BranchPrefix+branchName)
|
divergence, cached = getDivergenceFromCache(repo.ID, dbBranch.Name)
|
||||||
if err != nil {
|
if !cached {
|
||||||
log.Error("CountDivergingCommits: %v", err)
|
var err error
|
||||||
|
divergence, err = files_service.CountDivergingCommits(ctx, repo, git.BranchPrefix+branchName)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("CountDivergingCommits: %v", err)
|
||||||
|
} else {
|
||||||
|
if err = putDivergenceFromCache(repo.ID, dbBranch.Name, divergence); err != nil {
|
||||||
|
log.Error("putDivergenceFromCache: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,11 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete cache for divergence
|
||||||
|
if err := DelDivergenceFromCache(repo.ID, branch); err != nil {
|
||||||
|
log.Error("DelDivergenceFromCache: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
commits := repo_module.GitToPushCommits(l)
|
commits := repo_module.GitToPushCommits(l)
|
||||||
commits.HeadCommit = repo_module.CommitToPushCommit(newCommit)
|
commits.HeadCommit = repo_module.CommitToPushCommit(newCommit)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue