automatic ssl live reload
This commit is contained in:
100
smtp/fswatcher.go
Normal file
100
smtp/fswatcher.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package smtp
|
||||
|
||||
import (
|
||||
"math"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"gitlab.com/etke.cc/go/logger"
|
||||
)
|
||||
|
||||
const fsdelay = 100 * time.Millisecond
|
||||
|
||||
type FSWatcher struct {
|
||||
watcher *fsnotify.Watcher
|
||||
files []string
|
||||
log *logger.Logger
|
||||
mu sync.Mutex
|
||||
t map[string]*time.Timer
|
||||
}
|
||||
|
||||
func NewFSWatcher(files []string, loglevel string) (*FSWatcher, error) {
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
err = watcher.Add(filepath.Dir(file))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
fswatcher := &FSWatcher{
|
||||
watcher: watcher,
|
||||
files: files,
|
||||
log: logger.New("fs.", loglevel),
|
||||
t: make(map[string]*time.Timer),
|
||||
}
|
||||
|
||||
return fswatcher, nil
|
||||
}
|
||||
|
||||
func (w *FSWatcher) watch(handler func(e fsnotify.Event)) {
|
||||
for {
|
||||
select {
|
||||
case err, ok := <-w.watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
w.log.Error("%v", err)
|
||||
case e, ok := <-w.watcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
handler(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start watcher
|
||||
func (w *FSWatcher) Start(handler func(e fsnotify.Event)) {
|
||||
w.watch(func(e fsnotify.Event) {
|
||||
var found bool
|
||||
for _, f := range w.files {
|
||||
if f == e.Name {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return
|
||||
}
|
||||
w.mu.Lock()
|
||||
t, ok := w.t[e.Name]
|
||||
w.mu.Unlock()
|
||||
if !ok {
|
||||
t = time.AfterFunc(math.MaxInt64, func() {
|
||||
w.log.Info("handling fs event %+v", e)
|
||||
handler(e)
|
||||
})
|
||||
t.Stop()
|
||||
|
||||
w.mu.Lock()
|
||||
w.t[e.Name] = t
|
||||
w.mu.Unlock()
|
||||
}
|
||||
t.Reset(fsdelay)
|
||||
})
|
||||
}
|
||||
|
||||
// Stop watcher
|
||||
func (w *FSWatcher) Stop() {
|
||||
err := w.watcher.Close()
|
||||
if err != nil {
|
||||
w.log.Error("cannot stop fs watcher: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user