Skip to content

Commit

Permalink
Simplify watcher.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimafisk committed May 26, 2023
1 parent 1d56bcc commit 60929b1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 52 deletions.
2 changes: 1 addition & 1 deletion cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func Build() error {
if _, buildPathExistsErr := os.Stat(buildPath); buildPathExistsErr == nil {
build.Log("Removing old '" + buildPath + "' build directory")
if err = os.RemoveAll(buildPath); err != nil {
log.Fatal("\nCan't remove \"%v\" folder from previous build", err, buildDir)
log.Fatal("\nCan't remove \"%s\" folder from previous build: %s", buildDir, err)
}
}

Expand Down
1 change: 0 additions & 1 deletion cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ var serveCmd = &cobra.Command{

// Watch filesystem for changes.
serve.Gowatch(buildDir, Build)
serve.Gowatch(buildDir, Build)

if build.Doreload {
// websockets
Expand Down
81 changes: 31 additions & 50 deletions cmd/serve/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"log"
"os"
"path/filepath"
"sync/atomic"

"github.com/plentico/plenti/cmd/build"

Expand Down Expand Up @@ -80,8 +79,8 @@ func (w *watcher) watch(buildPath string, Build buildFunc) {

// Set delay for batching events.
ticker := time.NewTicker(300 * time.Millisecond)
// use a map for double firing events (happens when saving files in some text editors).
events := map[string]fsnotify.Event{}
// Batch events to prevent double firing (happens when saving files in some text editors).
events := make([]fsnotify.Event, 0)

go func() {
for {
Expand All @@ -91,64 +90,26 @@ func (w *watcher) watch(buildPath string, Build buildFunc) {
// Don't rebuild when build dir is added or deleted.
if event.Name != "./"+buildPath {
// Add current event to array for batching.
// don't really care but if we build with
events[event.Name] = event

events = append(events, event)
}

case <-ticker.C:
// Checks on set interval if there are events.
// only build if there was an event.
// Display messages for each event in batch.
logEvents(events, w)
// Only build if there was an event.
if len(events) > 0 {
// if locked i.e still building from last then this will do nothing.
// Can queue build with a mutex but gets messy quickly if you have 3-4 quick ctrl-s with one right after next.
if !atomic.CompareAndSwapUint32(&lock, 0, 1) {
err := Build()
// will be unlocked when we receive loaded message from ws in window.onload
// if any error leave as is. Shoud never send on channel if no connections or it will hang forever or until re load in browser..
if err == nil && build.Doreload && len(connections) > 0 {
reloadC <- struct{}{}

} else {
// not reloading so just unlock
atomic.StoreUint32(&lock, 0)
}

}

}

// Display messages for each events in batch.
for _, event := range events {
if event.Op&fsnotify.Create == fsnotify.Create {
build.Log("File create detected: " + event.String())
//common.CheckErr(w.Add(event.Name))
// TODO: Checking error breaks server on Ubuntu.
w.Add(event.Name)
build.Log("Now watching " + event.Name)
}
if event.Op&fsnotify.Write == fsnotify.Write {
build.Log("File write detected: " + event.String())

}
if event.Op&fsnotify.Remove == fsnotify.Remove {
build.Log("File delete detected: " + event.String())
}
if event.Op&fsnotify.Rename == fsnotify.Rename {
build.Log("File rename detected: " + event.String())
}

// optimised since 1.11 to reuse map. should lock this really and other access
for k := range events {
delete(events, k)
}

Build()
}
// Empty the batch array.
events = make([]fsnotify.Event, 0)

// Watch for errors.
case err := <-w.Errors:
if err != nil {
fmt.Printf("\nFile watching error: %s\n", err)
}

}
}
}()
Expand All @@ -171,3 +132,23 @@ func (w *watcher) watchDir(buildPath string) fs.WalkDirFunc {
return nil
}
}

func logEvents(events []fsnotify.Event, w *watcher) {
for _, event := range events {
if event.Op&fsnotify.Create == fsnotify.Create {
build.Log("File create detected: " + event.String())
w.Add(event.Name) // Start watching new file for changes
build.Log("Now watching " + event.Name)
}
if event.Op&fsnotify.Write == fsnotify.Write {
build.Log("File write detected: " + event.String())

}
if event.Op&fsnotify.Remove == fsnotify.Remove {
build.Log("File delete detected: " + event.String())
}
if event.Op&fsnotify.Rename == fsnotify.Rename {
build.Log("File rename detected: " + event.String())
}
}
}

0 comments on commit 60929b1

Please sign in to comment.