2017-01-25 05:43:02 +03:00
|
|
|
// Copyright 2017 The Gitea Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a MIT-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package models
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2017-09-16 23:16:21 +03:00
|
|
|
"code.gitea.io/gitea/modules/indexer"
|
2017-01-25 05:43:02 +03:00
|
|
|
"code.gitea.io/gitea/modules/log"
|
|
|
|
"code.gitea.io/gitea/modules/setting"
|
|
|
|
"code.gitea.io/gitea/modules/util"
|
|
|
|
)
|
|
|
|
|
2017-09-16 23:16:21 +03:00
|
|
|
// issueIndexerUpdateQueue queue of issue ids to be updated
|
|
|
|
var issueIndexerUpdateQueue chan int64
|
2017-01-25 05:43:02 +03:00
|
|
|
|
|
|
|
// InitIssueIndexer initialize issue indexer
|
|
|
|
func InitIssueIndexer() {
|
2017-09-16 23:16:21 +03:00
|
|
|
indexer.InitIssueIndexer(populateIssueIndexer)
|
|
|
|
issueIndexerUpdateQueue = make(chan int64, setting.Indexer.UpdateQueueLength)
|
2017-01-25 05:43:02 +03:00
|
|
|
go processIssueIndexerUpdateQueue()
|
|
|
|
}
|
|
|
|
|
|
|
|
// populateIssueIndexer populate the issue indexer with issue data
|
|
|
|
func populateIssueIndexer() error {
|
2017-09-25 03:08:48 +03:00
|
|
|
batch := indexer.IssueIndexerBatch()
|
2017-01-25 05:43:02 +03:00
|
|
|
for page := 1; ; page++ {
|
2017-10-10 23:37:18 +03:00
|
|
|
repos, _, err := SearchRepositoryByName(&SearchRepoOptions{
|
2017-10-27 00:16:13 +03:00
|
|
|
Page: page,
|
|
|
|
PageSize: 10,
|
|
|
|
OrderBy: SearchOrderByID,
|
|
|
|
Private: true,
|
|
|
|
Collaborate: util.OptionalBoolFalse,
|
2017-01-25 05:43:02 +03:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Repositories: %v", err)
|
|
|
|
}
|
|
|
|
if len(repos) == 0 {
|
2017-09-25 03:08:48 +03:00
|
|
|
return batch.Flush()
|
2017-01-25 05:43:02 +03:00
|
|
|
}
|
|
|
|
for _, repo := range repos {
|
|
|
|
issues, err := Issues(&IssuesOptions{
|
2017-12-26 02:25:16 +03:00
|
|
|
RepoIDs: []int64{repo.ID},
|
2017-01-25 05:43:02 +03:00
|
|
|
IsClosed: util.OptionalBoolNone,
|
|
|
|
IsPull: util.OptionalBoolNone,
|
|
|
|
})
|
2017-09-25 03:08:48 +03:00
|
|
|
if err != nil {
|
|
|
|
return err
|
2017-01-25 05:43:02 +03:00
|
|
|
}
|
2017-11-21 08:28:22 +03:00
|
|
|
if err = IssueList(issues).LoadComments(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-09-25 03:08:48 +03:00
|
|
|
for _, issue := range issues {
|
|
|
|
if err := batch.Add(issue.update()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-01-25 05:43:02 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func processIssueIndexerUpdateQueue() {
|
2017-09-25 03:08:48 +03:00
|
|
|
batch := indexer.IssueIndexerBatch()
|
2017-01-25 05:43:02 +03:00
|
|
|
for {
|
2017-09-25 03:08:48 +03:00
|
|
|
var issueID int64
|
2017-01-25 05:43:02 +03:00
|
|
|
select {
|
2017-09-25 03:08:48 +03:00
|
|
|
case issueID = <-issueIndexerUpdateQueue:
|
|
|
|
default:
|
|
|
|
// flush whatever updates we currently have, since we
|
|
|
|
// might have to wait a while
|
|
|
|
if err := batch.Flush(); err != nil {
|
|
|
|
log.Error(4, "IssueIndexer: %v", err)
|
2017-01-25 05:43:02 +03:00
|
|
|
}
|
2017-09-25 03:08:48 +03:00
|
|
|
issueID = <-issueIndexerUpdateQueue
|
|
|
|
}
|
|
|
|
issue, err := GetIssueByID(issueID)
|
|
|
|
if err != nil {
|
|
|
|
log.Error(4, "GetIssueByID: %v", err)
|
|
|
|
} else if err = batch.Add(issue.update()); err != nil {
|
|
|
|
log.Error(4, "IssueIndexer: %v", err)
|
2017-01-25 05:43:02 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-16 23:16:21 +03:00
|
|
|
func (issue *Issue) update() indexer.IssueIndexerUpdate {
|
|
|
|
comments := make([]string, 0, 5)
|
|
|
|
for _, comment := range issue.Comments {
|
|
|
|
if comment.Type == CommentTypeComment {
|
|
|
|
comments = append(comments, comment.Content)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return indexer.IssueIndexerUpdate{
|
|
|
|
IssueID: issue.ID,
|
|
|
|
Data: &indexer.IssueIndexerData{
|
|
|
|
RepoID: issue.RepoID,
|
|
|
|
Title: issue.Title,
|
|
|
|
Content: issue.Content,
|
|
|
|
Comments: comments,
|
|
|
|
},
|
2017-01-25 05:43:02 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-17 14:53:02 +03:00
|
|
|
// updateNeededCols whether a change to the specified columns requires updating
|
|
|
|
// the issue indexer
|
|
|
|
func updateNeededCols(cols []string) bool {
|
|
|
|
for _, col := range cols {
|
|
|
|
switch col {
|
|
|
|
case "name", "content":
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateIssueIndexerCols update an issue in the issue indexer, given changes
|
|
|
|
// to the specified columns
|
|
|
|
func UpdateIssueIndexerCols(issueID int64, cols ...string) {
|
|
|
|
if updateNeededCols(cols) {
|
|
|
|
UpdateIssueIndexer(issueID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-25 05:43:02 +03:00
|
|
|
// UpdateIssueIndexer add/update an issue to the issue indexer
|
2017-09-16 23:16:21 +03:00
|
|
|
func UpdateIssueIndexer(issueID int64) {
|
|
|
|
select {
|
|
|
|
case issueIndexerUpdateQueue <- issueID:
|
|
|
|
default:
|
|
|
|
go func() {
|
|
|
|
issueIndexerUpdateQueue <- issueID
|
|
|
|
}()
|
|
|
|
}
|
2017-01-25 05:43:02 +03:00
|
|
|
}
|