|
@@ -50,7 +50,6 @@ type folder struct {
|
|
|
|
|
|
scanInterval time.Duration
|
|
|
scanTimer *time.Timer
|
|
|
- scanNow chan rescanRequest
|
|
|
scanDelay chan time.Duration
|
|
|
initialScanFinished chan struct{}
|
|
|
scanErrors []FileError
|
|
@@ -58,6 +57,8 @@ type folder struct {
|
|
|
|
|
|
pullScheduled chan struct{}
|
|
|
|
|
|
+ doInSyncChan chan syncRequest
|
|
|
+
|
|
|
watchCancel context.CancelFunc
|
|
|
watchChan chan []string
|
|
|
restartWatchChan chan struct{}
|
|
@@ -67,9 +68,9 @@ type folder struct {
|
|
|
puller puller
|
|
|
}
|
|
|
|
|
|
-type rescanRequest struct {
|
|
|
- subdirs []string
|
|
|
- err chan error
|
|
|
+type syncRequest struct {
|
|
|
+ fn func() error
|
|
|
+ err chan error
|
|
|
}
|
|
|
|
|
|
type puller interface {
|
|
@@ -90,13 +91,14 @@ func newFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg conf
|
|
|
|
|
|
scanInterval: time.Duration(cfg.RescanIntervalS) * time.Second,
|
|
|
scanTimer: time.NewTimer(time.Millisecond), // The first scan should be done immediately.
|
|
|
- scanNow: make(chan rescanRequest),
|
|
|
scanDelay: make(chan time.Duration),
|
|
|
initialScanFinished: make(chan struct{}),
|
|
|
scanErrorsMut: sync.NewMutex(),
|
|
|
|
|
|
pullScheduled: make(chan struct{}, 1), // This needs to be 1-buffered so that we queue a pull if we're busy when it comes.
|
|
|
|
|
|
+ doInSyncChan: make(chan syncRequest),
|
|
|
+
|
|
|
watchCancel: func() {},
|
|
|
restartWatchChan: make(chan struct{}, 1),
|
|
|
watchMut: sync.NewMutex(),
|
|
@@ -172,9 +174,9 @@ func (f *folder) serve(ctx context.Context) {
|
|
|
l.Debugln(f, "Scanning due to timer")
|
|
|
f.scanTimerFired()
|
|
|
|
|
|
- case req := <-f.scanNow:
|
|
|
- l.Debugln(f, "Scanning due to request")
|
|
|
- req.err <- f.scanSubdirs(req.subdirs)
|
|
|
+ case req := <-f.doInSyncChan:
|
|
|
+ l.Debugln(f, "Running something due to request")
|
|
|
+ req.err <- req.fn()
|
|
|
|
|
|
case next := <-f.scanDelay:
|
|
|
l.Debugln(f, "Delaying scan")
|
|
@@ -224,13 +226,19 @@ func (f *folder) Jobs(_, _ int) ([]string, []string, int) {
|
|
|
|
|
|
func (f *folder) Scan(subdirs []string) error {
|
|
|
<-f.initialScanFinished
|
|
|
- req := rescanRequest{
|
|
|
- subdirs: subdirs,
|
|
|
- err: make(chan error),
|
|
|
+ return f.doInSync(func() error { return f.scanSubdirs(subdirs) })
|
|
|
+}
|
|
|
+
|
|
|
+// doInSync allows to run functions synchronously in folder.serve from exported,
|
|
|
+// asynchronously called methods.
|
|
|
+func (f *folder) doInSync(fn func() error) error {
|
|
|
+ req := syncRequest{
|
|
|
+ fn: fn,
|
|
|
+ err: make(chan error, 1),
|
|
|
}
|
|
|
|
|
|
select {
|
|
|
- case f.scanNow <- req:
|
|
|
+ case f.doInSyncChan <- req:
|
|
|
return <-req.err
|
|
|
case <-f.ctx.Done():
|
|
|
return f.ctx.Err()
|