Skip to content

Commit ccdb949

Browse files
ethantkoeniglafriks
authored andcommitted
Asynchronously populate the repo indexer (go-gitea#3366)
* Populate repo indexer in background * Check if no repos exist * race cond
1 parent a8325dd commit ccdb949

File tree

1 file changed

+41
-17
lines changed

1 file changed

+41
-17
lines changed

models/repo_indexer.go

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,34 +70,58 @@ func InitRepoIndexer() {
7070
if !setting.Indexer.RepoIndexerEnabled {
7171
return
7272
}
73-
indexer.InitRepoIndexer(populateRepoIndexer)
7473
repoIndexerOperationQueue = make(chan repoIndexerOperation, setting.Indexer.UpdateQueueLength)
74+
indexer.InitRepoIndexer(populateRepoIndexerAsynchronously)
7575
go processRepoIndexerOperationQueue()
7676
}
7777

78-
// populateRepoIndexer populate the repo indexer with data
79-
func populateRepoIndexer() error {
80-
log.Info("Populating repository indexer (this may take a while)")
81-
for page := 1; ; page++ {
82-
repos, _, err := SearchRepositoryByName(&SearchRepoOptions{
83-
Page: page,
84-
PageSize: RepositoryListDefaultPageSize,
85-
OrderBy: SearchOrderByID,
86-
Private: true,
87-
})
78+
// populateRepoIndexerAsynchronously asynchronously populates the repo indexer
79+
// with pre-existing data. This should only be run when the indexer is created
80+
// for the first time.
81+
func populateRepoIndexerAsynchronously() error {
82+
exist, err := x.Table("repository").Exist()
83+
if err != nil {
84+
return err
85+
} else if !exist {
86+
return nil
87+
}
88+
89+
var maxRepoID int64
90+
if _, err = x.Select("MAX(id)").Table("repository").Get(&maxRepoID); err != nil {
91+
return err
92+
}
93+
go populateRepoIndexer(maxRepoID)
94+
return nil
95+
}
96+
97+
// populateRepoIndexer populate the repo indexer with pre-existing data. This
98+
// should only be run when the indexer is created for the first time.
99+
func populateRepoIndexer(maxRepoID int64) {
100+
log.Info("Populating the repo indexer with existing repositories")
101+
// start with the maximum existing repo ID and work backwards, so that we
102+
// don't include repos that are created after gitea starts; such repos will
103+
// already be added to the indexer, and we don't need to add them again.
104+
for maxRepoID > 0 {
105+
repos := make([]*Repository, 0, RepositoryListDefaultPageSize)
106+
err := x.Where("id <= ?", maxRepoID).
107+
OrderBy("id DESC").
108+
Limit(RepositoryListDefaultPageSize).
109+
Find(&repos)
88110
if err != nil {
89-
return err
111+
log.Error(4, "populateRepoIndexer: %v", err)
112+
return
90113
} else if len(repos) == 0 {
91-
return nil
114+
break
92115
}
93116
for _, repo := range repos {
94-
if err = updateRepoIndexer(repo); err != nil {
95-
// only log error, since this should not prevent
96-
// gitea from starting up
97-
log.Error(4, "updateRepoIndexer: repoID=%d, %v", repo.ID, err)
117+
repoIndexerOperationQueue <- repoIndexerOperation{
118+
repo: repo,
119+
deleted: false,
98120
}
121+
maxRepoID = repo.ID - 1
99122
}
100123
}
124+
log.Info("Done populating the repo indexer with existing repositories")
101125
}
102126

103127
func updateRepoIndexer(repo *Repository) error {

0 commit comments

Comments
 (0)