From 6e01a68c91feefd468e036148ab69c9b9e198688 Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Thu, 13 Apr 2023 14:01:31 +0000 Subject: [PATCH] Prevent double delays and add some docs (#411) * Fix a few linter warnings * Prevent double delays and add some docs I just noticed that reusing `delay` for the poll interval will cause an unintended double delay (first the delay is used as interval, and when a change happened delay is used to wait before building after the change). Adding a dedicated `poll_interval` parameter allows people to prevent that and apply a more fine-grained configuration. Also added the new params to the example toml file with some docs which I forgot to do in the initial PR. --- air_example.toml | 4 ++++ runner/config.go | 1 + runner/engine.go | 2 -- runner/engine_test.go | 27 +++++++++++++++++---------- runner/logger.go | 2 +- runner/watcher.go | 4 ++-- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/air_example.toml b/air_example.toml index bf03514a..01e716f5 100644 --- a/air_example.toml +++ b/air_example.toml @@ -30,6 +30,10 @@ exclude_unchanged = true follow_symlink = true # This log file places in your tmp_dir. log = "air.log" +# Poll files for changes instead of using fsnotify. +poll = false +# Poll interval (defaults to the minimum interval of 500ms). +poll_interval = 500 # ms # It's not necessary to trigger build each time file changes if it's too frequent. delay = 0 # ms # Stop running old binary when build errors occur. diff --git a/runner/config.go b/runner/config.go index 842f5f3f..fe954467 100644 --- a/runner/config.go +++ b/runner/config.go @@ -48,6 +48,7 @@ type cfgBuild struct { ExcludeUnchanged bool `toml:"exclude_unchanged"` FollowSymlink bool `toml:"follow_symlink"` Poll bool `toml:"poll"` + PollInterval int `toml:"poll_interval"` Delay int `toml:"delay"` StopOnError bool `toml:"stop_on_error"` SendInterrupt bool `toml:"send_interrupt"` diff --git a/runner/engine.go b/runner/engine.go index df970d7e..7d59f5a2 100644 --- a/runner/engine.go +++ b/runner/engine.go @@ -345,7 +345,6 @@ func (e *Engine) start() { e.mainLog("%s has changed", e.config.rel(filename)) case <-firstRunCh: // go down - break } // already build and run now @@ -449,7 +448,6 @@ func (e *Engine) runBin() error { close(e.canExit) default: } - }() killFunc := func(cmd *exec.Cmd, stdout io.ReadCloser, stderr io.ReadCloser, killCh chan struct{}, processExit chan struct{}, wg *sync.WaitGroup) { diff --git a/runner/engine_test.go b/runner/engine_test.go index 2c8e9953..28b55b23 100644 --- a/runner/engine_test.go +++ b/runner/engine_test.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "io/ioutil" + "log" "net" "os" "os/exec" @@ -508,10 +509,7 @@ func checkPortConnectionRefused(port int) bool { _ = conn.Close() } }() - if errors.Is(err, syscall.ECONNREFUSED) { - return true - } - return false + return errors.Is(err, syscall.ECONNREFUSED) } func checkPortHaveBeenUsed(port int) bool { @@ -572,6 +570,9 @@ func main() { return err } _, err = file.WriteString(code) + if err != nil { + return err + } // generate go mod file mod := `module air.sample.com @@ -604,6 +605,9 @@ func main() { return err } _, err = file.WriteString(code) + if err != nil { + return err + } // generate go mod file mod := `module air.sample.com @@ -639,6 +643,9 @@ func main() { return err } _, err = file.WriteString(code) + if err != nil { + return err + } // generate go mod file mod := `module air.sample.com @@ -688,12 +695,12 @@ func TestRebuildWhenRunCmdUsingDLV(t *testing.T) { go func() { file, err := os.OpenFile("main.go", os.O_APPEND|os.O_WRONLY, 0o644) if err != nil { - t.Fatalf("Should not be fail: %s.", err) + log.Fatalf("Should not be fail: %s.", err) } defer file.Close() _, err = file.WriteString("\n") if err != nil { - t.Fatalf("Should not be fail: %s.", err) + log.Fatalf("Should not be fail: %s.", err) } }() err = waitingPortConnectionRefused(t, port, time.Second*10) @@ -895,11 +902,11 @@ include_ext = ["sh"] include_dir = ["nonexist"] # prevent default "." watch from taking effect include_file = ["main.sh"] ` - if err := ioutil.WriteFile(dftTOML, []byte(config), 0644); err != nil { + if err := ioutil.WriteFile(dftTOML, []byte(config), 0o644); err != nil { t.Fatal(err) } - err := os.WriteFile("main.sh", []byte("#!/bin/sh\nprintf original > output"), 0755) + err := os.WriteFile("main.sh", []byte("#!/bin/sh\nprintf original > output"), 0o755) if err != nil { t.Fatal(err) } @@ -922,9 +929,9 @@ include_file = ["main.sh"] t.Logf("start change main.sh") go func() { - err := os.WriteFile("main.sh", []byte("#!/bin/sh\nprintf modified > output"), 0755) + err := os.WriteFile("main.sh", []byte("#!/bin/sh\nprintf modified > output"), 0o755) if err != nil { - t.Fatalf("Error updating file: %s.", err) + log.Fatalf("Error updating file: %s.", err) } }() diff --git a/runner/logger.go b/runner/logger.go index 67c836b7..d76d5cd8 100644 --- a/runner/logger.go +++ b/runner/logger.go @@ -53,7 +53,7 @@ func newLogFunc(colorname string, cfg cfgLog) logFunc { return func(msg string, v ...interface{}) { // There are some escape sequences to format color in terminal, so cannot // just trim new line from right. - msg = strings.Replace(msg, "\n", "", -1) + msg = strings.ReplaceAll(msg, "\n", "") msg = strings.TrimSpace(msg) if len(msg) == 0 { return diff --git a/runner/watcher.go b/runner/watcher.go index 6497db3c..6c607fbf 100644 --- a/runner/watcher.go +++ b/runner/watcher.go @@ -12,9 +12,9 @@ func newWatcher(cfg *Config) (filenotify.FileWatcher, error) { } // Get the poll interval from the config. - interval := cfg.Build.Delay + interval := cfg.Build.PollInterval - // Configure a minimum poll interval of 500ms. + // Make sure the interval is at least 500ms. if interval < 500 { interval = 500 }