Skip to content

Commit 930bae2

Browse files
authored
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.
1 parent f219ea8 commit 930bae2

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

services/repository/branch.go

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ import (
1616
issues_model "code.gitea.io/gitea/models/issues"
1717
repo_model "code.gitea.io/gitea/models/repo"
1818
user_model "code.gitea.io/gitea/models/user"
19+
"code.gitea.io/gitea/modules/cache"
1920
"code.gitea.io/gitea/modules/git"
2021
"code.gitea.io/gitea/modules/gitrepo"
2122
"code.gitea.io/gitea/modules/graceful"
23+
"code.gitea.io/gitea/modules/json"
2224
"code.gitea.io/gitea/modules/log"
2325
"code.gitea.io/gitea/modules/optional"
2426
"code.gitea.io/gitea/modules/queue"
@@ -99,7 +101,6 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git
99101
if err != nil {
100102
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
101103
}
102-
103104
branches = append(branches, branch)
104105
}
105106

@@ -109,10 +110,44 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git
109110
if err != nil {
110111
return nil, nil, 0, fmt.Errorf("loadOneBranch: %v", err)
111112
}
112-
113113
return defaultBranch, branches, totalNumOfBranches, nil
114114
}
115115

116+
func getDivergenceCacheKey(repoID int64, branchName string) string {
117+
return fmt.Sprintf("%d-%s", repoID, branchName)
118+
}
119+
120+
// getDivergenceFromCache gets the divergence from cache
121+
func getDivergenceFromCache(repoID int64, branchName string) (*git.DivergeObject, bool) {
122+
data := cache.GetCache().Get(getDivergenceCacheKey(repoID, branchName))
123+
res := git.DivergeObject{
124+
Ahead: -1,
125+
Behind: -1,
126+
}
127+
s, ok := data.([]byte)
128+
if !ok || len(s) == 0 {
129+
return &res, false
130+
}
131+
132+
if err := json.Unmarshal(s, &res); err != nil {
133+
log.Error("json.UnMarshal failed: %v", err)
134+
return &res, false
135+
}
136+
return &res, true
137+
}
138+
139+
func putDivergenceFromCache(repoID int64, branchName string, divergence *git.DivergeObject) error {
140+
bs, err := json.Marshal(divergence)
141+
if err != nil {
142+
return err
143+
}
144+
return cache.GetCache().Put(getDivergenceCacheKey(repoID, branchName), bs, 30*24*60*60)
145+
}
146+
147+
func DelDivergenceFromCache(repoID int64, branchName string) error {
148+
return cache.GetCache().Delete(getDivergenceCacheKey(repoID, branchName))
149+
}
150+
116151
func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *git_model.Branch, protectedBranches *git_model.ProtectedBranchRules,
117152
repoIDToRepo map[int64]*repo_model.Repository,
118153
repoIDToGitRepo map[int64]*git.Repository,
@@ -130,10 +165,18 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g
130165

131166
// it's not default branch
132167
if repo.DefaultBranch != dbBranch.Name && !dbBranch.IsDeleted {
133-
var err error
134-
divergence, err = files_service.CountDivergingCommits(ctx, repo, git.BranchPrefix+branchName)
135-
if err != nil {
136-
log.Error("CountDivergingCommits: %v", err)
168+
var cached bool
169+
divergence, cached = getDivergenceFromCache(repo.ID, dbBranch.Name)
170+
if !cached {
171+
var err error
172+
divergence, err = files_service.CountDivergingCommits(ctx, repo, git.BranchPrefix+branchName)
173+
if err != nil {
174+
log.Error("CountDivergingCommits: %v", err)
175+
} else {
176+
if err = putDivergenceFromCache(repo.ID, dbBranch.Name, divergence); err != nil {
177+
log.Error("putDivergenceFromCache: %v", err)
178+
}
179+
}
137180
}
138181
}
139182

services/repository/push.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,11 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
220220
}
221221
}
222222

223+
// delete cache for divergence
224+
if err := DelDivergenceFromCache(repo.ID, branch); err != nil {
225+
log.Error("DelDivergenceFromCache: %v", err)
226+
}
227+
223228
commits := repo_module.GitToPushCommits(l)
224229
commits.HeadCommit = repo_module.CommitToPushCommit(newCommit)
225230

0 commit comments

Comments
 (0)