@@ -6,6 +6,7 @@ package issues
6
6
7
7
import (
8
8
"context"
9
+ "fmt"
9
10
"os"
10
11
"sync"
11
12
"time"
@@ -51,9 +52,10 @@ type Indexer interface {
51
52
}
52
53
53
54
type indexerHolder struct {
54
- indexer Indexer
55
- mutex sync.RWMutex
56
- cond * sync.Cond
55
+ indexer Indexer
56
+ mutex sync.RWMutex
57
+ cond * sync.Cond
58
+ cancelled bool
57
59
}
58
60
59
61
func newIndexerHolder () * indexerHolder {
@@ -62,6 +64,13 @@ func newIndexerHolder() *indexerHolder {
62
64
return h
63
65
}
64
66
67
+ func (h * indexerHolder ) cancel () {
68
+ h .mutex .Lock ()
69
+ defer h .mutex .Unlock ()
70
+ h .cancelled = true
71
+ h .cond .Broadcast ()
72
+ }
73
+
65
74
func (h * indexerHolder ) set (indexer Indexer ) {
66
75
h .mutex .Lock ()
67
76
defer h .mutex .Unlock ()
@@ -72,7 +81,7 @@ func (h *indexerHolder) set(indexer Indexer) {
72
81
func (h * indexerHolder ) get () Indexer {
73
82
h .mutex .RLock ()
74
83
defer h .mutex .RUnlock ()
75
- if h .indexer == nil {
84
+ if h .indexer == nil && ! h . cancelled {
76
85
h .cond .Wait ()
77
86
}
78
87
return h .indexer
@@ -93,6 +102,12 @@ func InitIssueIndexer(syncReindex bool) {
93
102
switch setting .Indexer .IssueType {
94
103
case "bleve" :
95
104
handler := func (data ... queue.Data ) {
105
+ indexer := holder .get ()
106
+ if indexer == nil {
107
+ log .Error ("Unable to get indexer!" )
108
+ return
109
+ }
110
+
96
111
iData := make ([]* IndexerData , 0 , setting .Indexer .IssueQueueBatchNumber )
97
112
for _ , datum := range data {
98
113
indexerData , ok := datum .(* IndexerData )
@@ -102,12 +117,12 @@ func InitIssueIndexer(syncReindex bool) {
102
117
}
103
118
log .Trace ("IndexerData Process: %d %v %t" , indexerData .ID , indexerData .IDs , indexerData .IsDelete )
104
119
if indexerData .IsDelete {
105
- _ = holder . get () .Delete (indexerData .IDs ... )
120
+ _ = indexer .Delete (indexerData .IDs ... )
106
121
continue
107
122
}
108
123
iData = append (iData , indexerData )
109
124
}
110
- if err := holder . get () .Index (iData ); err != nil {
125
+ if err := indexer .Index (iData ); err != nil {
111
126
log .Error ("Error whilst indexing: %v Error: %v" , iData , err )
112
127
}
113
128
}
@@ -132,6 +147,7 @@ func InitIssueIndexer(syncReindex bool) {
132
147
issueIndexer := NewBleveIndexer (setting .Indexer .IssuePath )
133
148
exist , err := issueIndexer .Init ()
134
149
if err != nil {
150
+ holder .cancel ()
135
151
log .Fatal ("Unable to initialize Bleve Issue Indexer: %v" , err )
136
152
}
137
153
populate = ! exist
@@ -153,6 +169,7 @@ func InitIssueIndexer(syncReindex bool) {
153
169
issueIndexer := & DBIndexer {}
154
170
holder .set (issueIndexer )
155
171
default :
172
+ holder .cancel ()
156
173
log .Fatal ("Unknown issue indexer type: %s" , setting .Indexer .IssueType )
157
174
}
158
175
@@ -168,10 +185,14 @@ func InitIssueIndexer(syncReindex bool) {
168
185
}
169
186
}
170
187
waitChannel <- time .Since (start )
188
+ close (waitChannel )
171
189
}()
172
190
173
191
if syncReindex {
174
- <- waitChannel
192
+ select {
193
+ case <- waitChannel :
194
+ case <- graceful .GetManager ().IsShutdown ():
195
+ }
175
196
} else if setting .Indexer .StartupTimeout > 0 {
176
197
go func () {
177
198
timeout := setting .Indexer .StartupTimeout
@@ -181,6 +202,8 @@ func InitIssueIndexer(syncReindex bool) {
181
202
select {
182
203
case duration := <- waitChannel :
183
204
log .Info ("Issue Indexer Initialization took %v" , duration )
205
+ case <- graceful .GetManager ().IsShutdown ():
206
+ log .Warn ("Shutdown occurred before issue index initialisation was complete" )
184
207
case <- time .After (timeout ):
185
208
if shutdownable , ok := issueIndexerQueue .(queue.Shutdownable ); ok {
186
209
shutdownable .Terminate ()
@@ -293,7 +316,13 @@ func DeleteRepoIssueIndexer(repo *models.Repository) {
293
316
// SearchIssuesByKeyword search issue ids by keywords and repo id
294
317
func SearchIssuesByKeyword (repoIDs []int64 , keyword string ) ([]int64 , error ) {
295
318
var issueIDs []int64
296
- res , err := holder .get ().Search (keyword , repoIDs , 1000 , 0 )
319
+ indexer := holder .get ()
320
+
321
+ if indexer == nil {
322
+ log .Error ("Unable to get indexer!" )
323
+ return nil , fmt .Errorf ("unable to get issue indexer" )
324
+ }
325
+ res , err := indexer .Search (keyword , repoIDs , 1000 , 0 )
297
326
if err != nil {
298
327
return nil , err
299
328
}
0 commit comments