Support rebuilding issue indexer manually (#26546)

Provide a way to rebuild issue indexer manually.

So if the indexer get outdated because of some bugs like #26539, we can
rebuild it.

<img width="1104" alt="image"
src="https://github.com/go-gitea/gitea/assets/9418365/ac242e29-6f04-47ca-b3d0-801a796448d3">

Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
Jason Song 2023-08-17 22:05:17 +08:00 committed by GitHub
parent 940f997512
commit 47fddaadc8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 7 deletions

View file

@ -5,6 +5,7 @@ package issues
import ( import (
"context" "context"
"fmt"
"os" "os"
"runtime/pprof" "runtime/pprof"
"sync/atomic" "sync/atomic"
@ -202,11 +203,16 @@ func getIssueIndexerQueueHandler(ctx context.Context) func(items ...*IndexerMeta
func populateIssueIndexer(ctx context.Context) { func populateIssueIndexer(ctx context.Context) {
ctx, _, finished := process.GetManager().AddTypedContext(ctx, "Service: PopulateIssueIndexer", process.SystemProcessType, true) ctx, _, finished := process.GetManager().AddTypedContext(ctx, "Service: PopulateIssueIndexer", process.SystemProcessType, true)
defer finished() defer finished()
if err := PopulateIssueIndexer(ctx, true); err != nil {
log.Error("Issue indexer population failed: %v", err)
}
}
func PopulateIssueIndexer(ctx context.Context, keepRetrying bool) error {
for page := 1; ; page++ { for page := 1; ; page++ {
select { select {
case <-ctx.Done(): case <-ctx.Done():
log.Warn("Issue Indexer population shutdown before completion") return fmt.Errorf("shutdown before completion: %w", ctx.Err())
return
default: default:
} }
repos, _, err := repo_model.SearchRepositoryByName(ctx, &repo_model.SearchRepoOptions{ repos, _, err := repo_model.SearchRepositoryByName(ctx, &repo_model.SearchRepoOptions{
@ -221,21 +227,23 @@ func populateIssueIndexer(ctx context.Context) {
} }
if len(repos) == 0 { if len(repos) == 0 {
log.Debug("Issue Indexer population complete") log.Debug("Issue Indexer population complete")
return return nil
} }
for _, repo := range repos { for _, repo := range repos {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
log.Info("Issue Indexer population shutdown before completion") return fmt.Errorf("shutdown before completion: %w", ctx.Err())
return
default: default:
} }
if err := updateRepoIndexer(ctx, repo.ID); err != nil { if err := updateRepoIndexer(ctx, repo.ID); err != nil {
if keepRetrying && ctx.Err() == nil {
log.Warn("Retry to populate issue indexer for repo %d: %v", repo.ID, err) log.Warn("Retry to populate issue indexer for repo %d: %v", repo.ID, err)
continue continue
} }
return fmt.Errorf("populate issue indexer for repo %d: %v", repo.ID, err)
}
break break
} }
} }

View file

@ -2752,6 +2752,7 @@ dashboard.stop_zombie_tasks = Stop zombie tasks
dashboard.stop_endless_tasks = Stop endless tasks dashboard.stop_endless_tasks = Stop endless tasks
dashboard.cancel_abandoned_jobs = Cancel abandoned jobs dashboard.cancel_abandoned_jobs = Cancel abandoned jobs
dashboard.sync_branch.started = Branches Sync started dashboard.sync_branch.started = Branches Sync started
dashboard.rebuild_issue_indexer = Rebuild issue indexer
users.user_manage_panel = User Account Management users.user_manage_panel = User Account Management
users.new_account = Create User Account users.new_account = Create User Account

View file

@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/system" "code.gitea.io/gitea/models/system"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/git"
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/updatechecker" "code.gitea.io/gitea/modules/updatechecker"
repo_service "code.gitea.io/gitea/services/repository" repo_service "code.gitea.io/gitea/services/repository"
@ -213,6 +214,16 @@ func registerGCLFS() {
}) })
} }
func registerRebuildIssueIndexer() {
RegisterTaskFatal("rebuild_issue_indexer", &BaseConfig{
Enabled: false,
RunAtStart: false,
Schedule: "@annually",
}, func(ctx context.Context, _ *user_model.User, config Config) error {
return issue_indexer.PopulateIssueIndexer(ctx, false)
})
}
func initExtendedTasks() { func initExtendedTasks() {
registerDeleteInactiveUsers() registerDeleteInactiveUsers()
registerDeleteRepositoryArchives() registerDeleteRepositoryArchives()
@ -227,4 +238,5 @@ func initExtendedTasks() {
registerUpdateGiteaChecker() registerUpdateGiteaChecker()
registerDeleteOldSystemNotices() registerDeleteOldSystemNotices()
registerGCLFS() registerGCLFS()
registerRebuildIssueIndexer()
} }