From 9856ac5818445cdd3a1eb3ceb4a3e2c6be250c5f Mon Sep 17 00:00:00 2001
From: Lunny Xiao <xiaolunwen@gmail.com>
Date: Sat, 23 Nov 2019 23:03:35 +0800
Subject: [PATCH] fix race on indexer (#9136)

---
 models/repo_indexer.go | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/models/repo_indexer.go b/models/repo_indexer.go
index 7bfcde8db0..4085982c26 100644
--- a/models/repo_indexer.go
+++ b/models/repo_indexer.go
@@ -60,7 +60,7 @@ func (repo *Repository) updateIndexerStatus(sha string) error {
 }
 
 type repoIndexerOperation struct {
-	repo     *Repository
+	repoID   int64
 	deleted  bool
 	watchers []chan<- error
 }
@@ -145,7 +145,7 @@ func populateRepoIndexer(maxRepoID int64) {
 		}
 		for _, repo := range repos {
 			repoIndexerOperationQueue <- repoIndexerOperation{
-				repo:    repo,
+				repoID:  repo.ID,
 				deleted: false,
 			}
 			maxRepoID = repo.ID - 1
@@ -154,7 +154,12 @@ func populateRepoIndexer(maxRepoID int64) {
 	log.Info("Done populating the repo indexer with existing repositories")
 }
 
-func updateRepoIndexer(repo *Repository) error {
+func updateRepoIndexer(repoID int64) error {
+	repo, err := getRepositoryByID(x, repoID)
+	if err != nil {
+		return err
+	}
+
 	sha, err := getDefaultBranchSha(repo)
 	if err != nil {
 		return err
@@ -362,11 +367,11 @@ func processRepoIndexerOperationQueue() {
 		op := <-repoIndexerOperationQueue
 		var err error
 		if op.deleted {
-			if err = indexer.DeleteRepoFromIndexer(op.repo.ID); err != nil {
+			if err = indexer.DeleteRepoFromIndexer(op.repoID); err != nil {
 				log.Error("DeleteRepoFromIndexer: %v", err)
 			}
 		} else {
-			if err = updateRepoIndexer(op.repo); err != nil {
+			if err = updateRepoIndexer(op.repoID); err != nil {
 				log.Error("updateRepoIndexer: %v", err)
 			}
 		}
@@ -378,12 +383,12 @@ func processRepoIndexerOperationQueue() {
 
 // DeleteRepoFromIndexer remove all of a repository's entries from the indexer
 func DeleteRepoFromIndexer(repo *Repository, watchers ...chan<- error) {
-	addOperationToQueue(repoIndexerOperation{repo: repo, deleted: true, watchers: watchers})
+	addOperationToQueue(repoIndexerOperation{repoID: repo.ID, deleted: true, watchers: watchers})
 }
 
 // UpdateRepoIndexer update a repository's entries in the indexer
 func UpdateRepoIndexer(repo *Repository, watchers ...chan<- error) {
-	addOperationToQueue(repoIndexerOperation{repo: repo, deleted: false, watchers: watchers})
+	addOperationToQueue(repoIndexerOperation{repoID: repo.ID, deleted: false, watchers: watchers})
 }
 
 func addOperationToQueue(op repoIndexerOperation) {