aboutsummaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2024-03-08 18:21:24 +0800
committerGitHub <noreply@github.com>2024-03-08 10:21:24 +0000
commit930bae2300be1c62a56d6f019e519b6752d41ad1 (patch)
treeb37b16acaedfd1f6664a62fd7a3e0206c062ddc8 /services
parentf219ea8d0e0eccd74c786202a4ddb2784a0175ad (diff)
downloadgitea-930bae2300be1c62a56d6f019e519b6752d41ad1.tar.gz
gitea-930bae2300be1c62a56d6f019e519b6752d41ad1.zip
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.
Diffstat (limited to 'services')
-rw-r--r--services/repository/branch.go55
-rw-r--r--services/repository/push.go5
2 files changed, 54 insertions, 6 deletions
diff --git a/services/repository/branch.go b/services/repository/branch.go
index 763fb966c5..8d8cfa2d19 100644
--- a/services/repository/branch.go
+++ b/services/repository/branch.go
@@ -16,9 +16,11 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
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/gitrepo"
"code.gitea.io/gitea/modules/graceful"
+ "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/queue"
@@ -99,7 +101,6 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git
if err != nil {
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
}
-
branches = append(branches, branch)
}
@@ -109,10 +110,44 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git
if err != nil {
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
}
-
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,
repoIDToRepo map[int64]*repo_model.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
if repo.DefaultBranch != dbBranch.Name && !dbBranch.IsDeleted {
- var err error
- divergence, err = files_service.CountDivergingCommits(ctx, repo, git.BranchPrefix+branchName)
- if err != nil {
- log.Error("CountDivergingCommits: %v", err)
+ var cached bool
+ divergence, cached = getDivergenceFromCache(repo.ID, dbBranch.Name)
+ if !cached {
+ 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)
+ }
+ }
}
}
diff --git a/services/repository/push.go b/services/repository/push.go
index 0aeb4c830b..39843249a5 100644
--- a/services/repository/push.go
+++ b/services/repository/push.go
@@ -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.HeadCommit = repo_module.CommitToPushCommit(newCommit)