github.com/aracki/hugo@v0.47.1/watcher/batcher.go (about)

     1  // Copyright 2015 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package watcher
    15  
    16  import (
    17  	"time"
    18  
    19  	"github.com/fsnotify/fsnotify"
    20  )
    21  
    22  // Batcher batches file watch events in a given interval.
    23  type Batcher struct {
    24  	*fsnotify.Watcher
    25  	interval time.Duration
    26  	done     chan struct{}
    27  
    28  	Events chan []fsnotify.Event // Events are returned on this channel
    29  }
    30  
    31  // New creates and starts a Batcher with the given time interval.
    32  func New(interval time.Duration) (*Batcher, error) {
    33  	watcher, err := fsnotify.NewWatcher()
    34  
    35  	batcher := &Batcher{}
    36  	batcher.Watcher = watcher
    37  	batcher.interval = interval
    38  	batcher.done = make(chan struct{}, 1)
    39  	batcher.Events = make(chan []fsnotify.Event, 1)
    40  
    41  	if err == nil {
    42  		go batcher.run()
    43  	}
    44  
    45  	return batcher, err
    46  }
    47  
    48  func (b *Batcher) run() {
    49  	tick := time.Tick(b.interval)
    50  	evs := make([]fsnotify.Event, 0)
    51  OuterLoop:
    52  	for {
    53  		select {
    54  		case ev := <-b.Watcher.Events:
    55  			evs = append(evs, ev)
    56  		case <-tick:
    57  			if len(evs) == 0 {
    58  				continue
    59  			}
    60  			b.Events <- evs
    61  			evs = make([]fsnotify.Event, 0)
    62  		case <-b.done:
    63  			break OuterLoop
    64  		}
    65  	}
    66  	close(b.done)
    67  }
    68  
    69  // Close stops the watching of the files.
    70  func (b *Batcher) Close() {
    71  	b.done <- struct{}{}
    72  	b.Watcher.Close()
    73  }