@@ -29,8 +29,13 @@ type Searcher struct {
2929 // It has a buffer size of 1 to allow at most one pending
3030 // update at a time.
3131 updateCh chan time.Time
32+
33+ shutdownRequested bool
34+ shutdownCh chan empty
35+ doneCh chan empty
3236}
3337
38+ type empty struct {}
3439type limiter chan bool
3540
3641/**
@@ -141,6 +146,24 @@ func (s *Searcher) Update() bool {
141146 return true
142147}
143148
149+ // Shut down the searcher cleanly, waiting for any indexing operations to complete.
150+ func (s * Searcher ) Stop () {
151+ select {
152+ case s .shutdownCh <- empty {}:
153+ s .shutdownRequested = true
154+ default :
155+ }
156+ }
157+
158+ // Blocks until the searcher's associated goroutine is stopped.
159+ func (s * Searcher ) Wait () {
160+ <- s .doneCh
161+ }
162+
163+ func (s * Searcher ) completeShutdown () {
164+ close (s .doneCh )
165+ }
166+
144167// Wait for either the delay period to expire or an update request to
145168// arrive. Note that an empty delay will result in an infinite timeout.
146169func (s * Searcher ) waitForUpdate (delay time.Duration ) {
@@ -149,10 +172,11 @@ func (s *Searcher) waitForUpdate(delay time.Duration) {
149172 tch = time .After (delay )
150173 }
151174
152- // wait for either the timeout or the update channel signal
175+ // wait for a timeout, the update channel signal, or a shutdown request
153176 select {
154177 case <- s .updateCh :
155178 case <- tch :
179+ case <- s .shutdownCh :
156180 }
157181}
158182
@@ -393,9 +417,11 @@ func newSearcher(
393417 }
394418
395419 s := & Searcher {
396- idx : idx ,
397- updateCh : make (chan time.Time , 1 ),
398- Repo : repo ,
420+ idx : idx ,
421+ updateCh : make (chan time.Time , 1 ),
422+ Repo : repo ,
423+ doneCh : make (chan empty ),
424+ shutdownCh : make (chan empty , 1 ),
399425 }
400426
401427 go func () {
@@ -405,6 +431,7 @@ func newSearcher(
405431
406432 // if all forms of updating are turned off, we're done here.
407433 if ! repo .PollUpdatesEnabled () && ! repo .PushUpdatesEnabled () {
434+ s .completeShutdown ()
408435 return
409436 }
410437
@@ -414,10 +441,14 @@ func newSearcher(
414441 }
415442
416443 for {
417-
418444 // Wait for a signal to proceed
419445 s .waitForUpdate (delay )
420446
447+ if s .shutdownRequested {
448+ s .completeShutdown ()
449+ return
450+ }
451+
421452 // attempt to update and reindex this searcher
422453 newRev , ok := updateAndReindex (s , dbpath , vcsDir , name , rev , wd , opt , lim )
423454 if ! ok {
0 commit comments