-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
925c0a9
commit 5e1ae49
Showing
6 changed files
with
224 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
vendor/*/ | ||
# Compiled Object files, Static and Dynamic libs (Shared Objects) | ||
*.o | ||
*.a | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
language: go | ||
|
||
go: | ||
- 1.7 | ||
script: | ||
- go test -coverprofile=coverage.txt -covermode=atomic -coverpkg . | ||
|
||
before_install: | ||
- go get -u github.com/kardianos/govendor | ||
- govendor sync | ||
|
||
after_success: | ||
- bash <(curl -s https://codecov.io/bash) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,6 @@ | ||
# reloader | ||
# Reloader | ||
[![Build Status](https://travis-ci.org/aandryashin/reloader.svg?branch=master)](https://travis-ci.org/aandryashin/reloader) | ||
[![Coverage](https://codecov.io/github/aandryashin/reloader/reloader.svg)](https://codecov.io/gh/aandryashin/reloader) | ||
[![Release](https://img.shields.io/github/release/aandryashin/reloader.svg)](https://github.com/aandryashin/reloader/releases/latest) | ||
|
||
Library for automatic reloading configuration files based on file system events. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package reloader | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
|
||
"github.com/fsnotify/fsnotify" | ||
) | ||
|
||
func Watch(dir string, load func(), delay time.Duration) error { | ||
return watch(fsnotify.NewWatcher, dir, load, delay) | ||
} | ||
|
||
func watch(fn func() (*fsnotify.Watcher, error), dir string, load func(), delay time.Duration) error { | ||
watcher, err := fn() | ||
if err != nil { | ||
return fmt.Errorf("unable to initialize file system notifications: %v", err) | ||
} | ||
if err := watcher.Add(dir); err != nil { | ||
return fmt.Errorf("unable to watch directory: %v", err) | ||
} | ||
go func() { | ||
var cancel chan struct{} | ||
for { | ||
select { | ||
case e := <-watcher.Events: | ||
if e.Op != 0 { | ||
if cancel != nil { | ||
close(cancel) | ||
} | ||
cancel = make(chan struct{}) | ||
go func(cancel chan struct{}) { | ||
select { | ||
case <-time.After(delay): | ||
load() | ||
case <-cancel: | ||
} | ||
}(cancel) | ||
} | ||
} | ||
} | ||
}() | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package reloader | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"testing" | ||
"time" | ||
|
||
"github.com/fsnotify/fsnotify" | ||
) | ||
|
||
func TestWatch(t *testing.T) { | ||
dir, err := ioutil.TempDir("", "config") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.Remove(dir) | ||
err = Watch(dir, func() {}, 1*time.Second) | ||
if err != nil { | ||
t.Errorf("uexpected error: %v\n", err) | ||
} | ||
} | ||
|
||
func TestWatchUexistentDir(t *testing.T) { | ||
dir, err := ioutil.TempDir("", "config") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
os.Remove(dir) | ||
err = Watch(dir, func() {}, 1*time.Second) | ||
if err == nil { | ||
t.Error("uexpected success") | ||
} | ||
} | ||
|
||
func TestNewWatcherError(t *testing.T) { | ||
fn := func() (*fsnotify.Watcher, error) { | ||
return nil, fmt.Errorf("error") | ||
} | ||
err := watch(fn, "", func() {}, 1*time.Second) | ||
if err == nil { | ||
t.Error("uexpected success") | ||
} | ||
} | ||
|
||
func TestTimerShouldNotTrigger(t *testing.T) { | ||
watcher, err := fsnotify.NewWatcher() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer watcher.Close() | ||
fn := func() (*fsnotify.Watcher, error) { | ||
return watcher, nil | ||
} | ||
dir, err := ioutil.TempDir("", "config") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.Remove(dir) | ||
ch := make(chan bool) | ||
watch(fn, dir, func() { ch <- true }, 200*time.Millisecond) | ||
call := false | ||
watcher.Events <- fsnotify.Event{Op: fsnotify.Create} | ||
select { | ||
case <-time.After(100 * time.Millisecond): | ||
case call = <-ch: | ||
} | ||
if call { | ||
t.Error("timer should not be triggered after 100ms") | ||
} | ||
} | ||
|
||
func TestTimerShouldTrigger(t *testing.T) { | ||
watcher, err := fsnotify.NewWatcher() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer watcher.Close() | ||
fn := func() (*fsnotify.Watcher, error) { | ||
return watcher, nil | ||
} | ||
dir, err := ioutil.TempDir("", "config") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.Remove(dir) | ||
ch := make(chan bool) | ||
watch(fn, dir, func() { ch <- true }, 100*time.Millisecond) | ||
call := false | ||
watcher.Events <- fsnotify.Event{Op: fsnotify.Create} | ||
select { | ||
case <-time.After(200 * time.Millisecond): | ||
case call = <-ch: | ||
} | ||
if !call { | ||
t.Error("timer should be triggered after 200ms") | ||
} | ||
} | ||
|
||
func TestTimerShouldTriggerOnce(t *testing.T) { | ||
watcher, err := fsnotify.NewWatcher() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer watcher.Close() | ||
fn := func() (*fsnotify.Watcher, error) { | ||
return watcher, nil | ||
} | ||
dir, err := ioutil.TempDir("", "config") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.Remove(dir) | ||
ch := make(chan bool) | ||
watch(fn, dir, func() { ch <- true }, 300*time.Millisecond) | ||
call := false | ||
watcher.Events <- fsnotify.Event{Op: fsnotify.Create} | ||
select { | ||
case <-time.After(200 * time.Millisecond): | ||
case call = <-ch: | ||
} | ||
if call { | ||
t.Error("timer should not be triggered after 200ms") | ||
} | ||
watcher.Events <- fsnotify.Event{Op: fsnotify.Create} | ||
select { | ||
case <-time.After(200 * time.Millisecond): | ||
case call = <-ch: | ||
} | ||
if call { | ||
t.Error("timer still should not be triggered after 400ms") | ||
} | ||
select { | ||
case <-time.After(200 * time.Millisecond): | ||
case call = <-ch: | ||
} | ||
if !call { | ||
t.Error("timer should be triggered after 600ms") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"comment": "", | ||
"ignore": "", | ||
"package": [ | ||
{ | ||
"checksumSHA1": "74zwCNDSsh7NdJcEhgItnfU6d/E=", | ||
"path": "github.com/fsnotify/fsnotify", | ||
"revision": "fd9ec7deca8bf46ecd2a795baaacf2b3a9be1197", | ||
"revisionTime": "2016-10-26T20:31:22Z" | ||
}, | ||
{ | ||
"checksumSHA1": "yAfJ8xBj7cQuDtznpPwPt3UmJiE=", | ||
"path": "golang.org/x/sys/unix", | ||
"revision": "30237cf4eefd639b184d1f2cb77a581ea0be8947", | ||
"revisionTime": "2016-11-19T15:29:01Z" | ||
} | ||
], | ||
"rootPath": "github.com/aandryashin/reloader" | ||
} |