Skip to content

Instantly share code, notes, and snippets.

@henvic
Created March 7, 2018 02:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henvic/ec5b90043cc1cf38bf898312c17ff4f8 to your computer and use it in GitHub Desktop.
Save henvic/ec5b90043cc1cf38bf898312c17ff4f8 to your computer and use it in GitHub Desktop.
fs-notify listener (for debugging load-balancer issue 248 and 'custom domain mock adder')
package main
import (
"errors"
"flag"
"fmt"
"io/ioutil"
"math/rand"
"os"
"path/filepath"
"sync"
"time"
)
func createFile(filename string) error {
var c = []byte(RandStringRunes(2000))
fmt.Printf("creating file %s\n", filename)
return ioutil.WriteFile(filename, c, 0644)
}
func copyFiles(prefix string) error {
for x := 0; x < arguments.filesPerDirectory; x++ {
var name = fmt.Sprintf("%s/file_%d", prefix, x)
if err := createFile(name); err != nil {
fmt.Fprintf(os.Stderr, "x = %v\n", x)
return err
}
time.Sleep(arguments.interval)
}
return nil
}
func createOrPanic(arguments flags, x int, queue *sync.WaitGroup) {
var name = filepath.Join(arguments.target, fmt.Sprintf("dir_%d", x))
defer queue.Done()
if err := os.Mkdir(name, 0777); err != nil {
panic(err)
}
if err := copyFiles(name); err != nil {
panic(err)
}
if err := os.RemoveAll(name); err != nil {
panic(err)
}
fmt.Printf("%s removed\n", name)
}
func createDirectoriesAndFiles(arguments flags) error {
switch err := os.Mkdir(arguments.target, 0777); {
case os.IsExist(err):
return errors.New("remove the target directory to run this test")
case err != nil:
return err
}
var queue sync.WaitGroup
queue.Add(arguments.directories)
for x := 0; x < arguments.directories; x++ {
go func(arguments flags, x int) {
createOrPanic(arguments, x, &queue)
}(arguments, x)
}
queue.Wait()
return os.Remove(arguments.target)
}
var arguments = flags{}
type flags struct {
target string
filesPerDirectory int
directories int
interval time.Duration
}
func init() {
flag.StringVar(&arguments.target, "target", "", "target directory")
flag.IntVar(&arguments.filesPerDirectory, "files-per-dir", 40, "number of files per directory")
flag.IntVar(&arguments.directories, "dirs", 20, "number of directories (and goroutines/threads)")
flag.DurationVar(&arguments.interval, "interval", 500*time.Nanosecond, "interval for each operation")
flag.Parse()
}
func main() {
rand.Seed(time.Now().UTC().UnixNano())
if len(arguments.target) == 0 {
fmt.Fprintf(os.Stderr, "invalid usage: try \"adder -target=test-dir\"\n")
flag.PrintDefaults()
os.Exit(1)
}
if err := createDirectoriesAndFiles(arguments); err != nil {
fmt.Fprintf(os.Stderr, "%+v\n", err)
os.Exit(1)
}
}
// code below from https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-golang/22892181
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
// RandStringRunes returns a random string
func RandStringRunes(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
package main
import (
"fmt"
"log"
"os"
"github.com/fsnotify/fsnotify"
)
// Watcher to listen files
type Watcher struct {
fsnotify *fsnotify.Watcher
}
// Run the watcher
func (w Watcher) Run(files []string) (err error) {
w.fsnotify, err = fsnotify.NewWatcher()
if err != nil {
return err
}
defer w.fsnotify.Close()
done := make(chan bool)
go w.listen()
if err := w.addFiles(files); err != nil {
return err
}
<-done
return nil
}
func (w *Watcher) addFiles(files []string) error {
for _, file := range files {
if err := w.fsnotify.Add(file); err != nil {
return err
}
}
return nil
}
func (w *Watcher) listen() {
fmt.Println("Listening to file changes")
for {
select {
case event := <-w.fsnotify.Events:
log.Println("event: ", event)
if event.Op&fsnotify.Write == fsnotify.Write {
log.Println("modified file: ", event.Name)
}
case err := <-w.fsnotify.Errors:
log.Println("error: ", err)
}
}
}
func main() {
w := Watcher{}
if err := w.Run(os.Args[1:]); err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment