Browse Source

lib/model: Add done chan to track folder-lifetime (fixes #6664) (#7094)

Simon Frei 5 years ago
parent
commit
1f1729ba43
1 changed files with 11 additions and 9 deletions
  1. 11 9
      lib/model/folder.go

+ 11 - 9
lib/model/folder.go

@@ -49,7 +49,8 @@ type folder struct {
 	fset          *db.FileSet
 	ignores       *ignore.Matcher
 	modTimeWindow time.Duration
-	ctx           context.Context
+	ctx           context.Context // used internally, only accessible on serve lifetime
+	done          chan struct{}   // used externally, accessible regardless of serve
 
 	scanInterval           time.Duration
 	scanTimer              *time.Timer
@@ -103,6 +104,7 @@ func newFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg conf
 		fset:          fset,
 		ignores:       ignores,
 		modTimeWindow: cfg.ModTimeWindow(),
+		done:          make(chan struct{}),
 
 		scanInterval:           time.Duration(cfg.RescanIntervalS) * time.Second,
 		scanTimer:              time.NewTimer(0), // The first scan should be done immediately.
@@ -165,6 +167,7 @@ func (f *folder) serve(ctx context.Context) {
 	for {
 		select {
 		case <-f.ctx.Done():
+			close(f.done)
 			return
 
 		case <-f.pullScheduled:
@@ -218,7 +221,10 @@ func (f *folder) Override() {}
 func (f *folder) Revert() {}
 
 func (f *folder) DelayScan(next time.Duration) {
-	f.Delay(next)
+	select {
+	case f.scanDelay <- next:
+	case <-f.done:
+	}
 }
 
 func (f *folder) ignoresUpdated() {
@@ -258,8 +264,8 @@ func (f *folder) doInSync(fn func() error) error {
 	select {
 	case f.doInSyncChan <- req:
 		return <-req.err
-	case <-f.ctx.Done():
-		return f.ctx.Err()
+	case <-f.done:
+		return context.Canceled
 	}
 }
 
@@ -274,10 +280,6 @@ func (f *folder) Reschedule() {
 	f.scanTimer.Reset(interval)
 }
 
-func (f *folder) Delay(next time.Duration) {
-	f.scanDelay <- next
-}
-
 func (f *folder) getHealthErrorAndLoadIgnores() error {
 	if err := f.getHealthErrorWithoutIgnores(); err != nil {
 		return err
@@ -925,7 +927,7 @@ func (f *folder) scanOnWatchErr() {
 	err := f.watchErr
 	f.watchMut.Unlock()
 	if err != nil {
-		f.Delay(0)
+		f.DelayScan(0)
 	}
 }