hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

batcher.go (2149B)

    1 // Copyright 2020 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 	"github.com/gohugoio/hugo/watcher/filenotify"
   21 )
   22 
   23 // Batcher batches file watch events in a given interval.
   24 type Batcher struct {
   25 	filenotify.FileWatcher
   26 	interval time.Duration
   27 	done     chan struct{}
   28 
   29 	Events chan []fsnotify.Event // Events are returned on this channel
   30 }
   31 
   32 // New creates and starts a Batcher with the given time interval.
   33 // It will fall back to a poll based watcher if native isn's supported.
   34 // To always use polling, set poll to true.
   35 func New(intervalBatcher, intervalPoll time.Duration, poll bool) (*Batcher, error) {
   36 	var err error
   37 	var watcher filenotify.FileWatcher
   38 
   39 	if poll {
   40 		watcher = filenotify.NewPollingWatcher(intervalPoll)
   41 	} else {
   42 		watcher, err = filenotify.New(intervalPoll)
   43 	}
   44 
   45 	if err != nil {
   46 		return nil, err
   47 	}
   48 
   49 	batcher := &Batcher{}
   50 	batcher.FileWatcher = watcher
   51 	batcher.interval = intervalBatcher
   52 	batcher.done = make(chan struct{}, 1)
   53 	batcher.Events = make(chan []fsnotify.Event, 1)
   54 
   55 	if err == nil {
   56 		go batcher.run()
   57 	}
   58 
   59 	return batcher, nil
   60 }
   61 
   62 func (b *Batcher) run() {
   63 	tick := time.Tick(b.interval)
   64 	evs := make([]fsnotify.Event, 0)
   65 OuterLoop:
   66 	for {
   67 		select {
   68 		case ev := <-b.FileWatcher.Events():
   69 			evs = append(evs, ev)
   70 		case <-tick:
   71 			if len(evs) == 0 {
   72 				continue
   73 			}
   74 			b.Events <- evs
   75 			evs = make([]fsnotify.Event, 0)
   76 		case <-b.done:
   77 			break OuterLoop
   78 		}
   79 	}
   80 	close(b.done)
   81 }
   82 
   83 // Close stops the watching of the files.
   84 func (b *Batcher) Close() {
   85 	b.done <- struct{}{}
   86 	b.FileWatcher.Close()
   87 }