Improve watcher detection and rebuild error handling
This commit is contained in:
parent
64dd0b0c56
commit
aa340b7323
23
moonshark.go
23
moonshark.go
@ -90,7 +90,26 @@ func runWithWatcher(scriptPath string) {
|
|||||||
|
|
||||||
fmt.Printf("Starting %s in watch mode...\n", scriptPath)
|
fmt.Printf("Starting %s in watch mode...\n", scriptPath)
|
||||||
|
|
||||||
|
var hadError bool
|
||||||
|
firstRun := true
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
// If we had an error on the last run and this isn't the first run,
|
||||||
|
// wait for file changes before retrying
|
||||||
|
if hadError && !firstRun {
|
||||||
|
fmt.Println("Waiting for file changes before retrying...")
|
||||||
|
select {
|
||||||
|
case <-restartCh:
|
||||||
|
fmt.Println("Files changed, retrying...")
|
||||||
|
case <-sigChan:
|
||||||
|
fmt.Println("\nExiting...")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
firstRun = false
|
||||||
|
hadError = false
|
||||||
|
|
||||||
// Clear cache before each run
|
// Clear cache before each run
|
||||||
state.ClearCache()
|
state.ClearCache()
|
||||||
|
|
||||||
@ -98,14 +117,14 @@ func runWithWatcher(scriptPath string) {
|
|||||||
luaState, err := state.NewFromScript(scriptPath)
|
luaState, err := state.NewFromScript(scriptPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error creating state: %v", err)
|
log.Printf("Error creating state: %v", err)
|
||||||
time.Sleep(1 * time.Second)
|
hadError = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := luaState.ExecuteFile(scriptPath); err != nil {
|
if err := luaState.ExecuteFile(scriptPath); err != nil {
|
||||||
log.Printf("Execution error: %v", err)
|
log.Printf("Execution error: %v", err)
|
||||||
luaState.Close()
|
luaState.Close()
|
||||||
time.Sleep(1 * time.Second)
|
hadError = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
68
watcher.go
68
watcher.go
@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"maps"
|
"maps"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -13,6 +12,7 @@ import (
|
|||||||
|
|
||||||
type FileWatcher struct {
|
type FileWatcher struct {
|
||||||
files map[string]time.Time
|
files map[string]time.Time
|
||||||
|
dirs map[string]bool // Track watched directories
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
restartCh chan bool
|
restartCh chan bool
|
||||||
stopCh chan bool
|
stopCh chan bool
|
||||||
@ -24,6 +24,7 @@ type FileWatcher struct {
|
|||||||
func NewFileWatcher(debounceMs int) (*FileWatcher, error) {
|
func NewFileWatcher(debounceMs int) (*FileWatcher, error) {
|
||||||
return &FileWatcher{
|
return &FileWatcher{
|
||||||
files: make(map[string]time.Time),
|
files: make(map[string]time.Time),
|
||||||
|
dirs: make(map[string]bool),
|
||||||
restartCh: make(chan bool, 1),
|
restartCh: make(chan bool, 1),
|
||||||
stopCh: make(chan bool, 1),
|
stopCh: make(chan bool, 1),
|
||||||
debounceMs: debounceMs,
|
debounceMs: debounceMs,
|
||||||
@ -51,7 +52,16 @@ func (fw *FileWatcher) AddFile(path string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fw *FileWatcher) AddDirectory(dir string) error {
|
func (fw *FileWatcher) AddDirectory(dir string) error {
|
||||||
return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
absDir, err := filepath.Abs(dir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fw.mu.Lock()
|
||||||
|
fw.dirs[absDir] = true
|
||||||
|
fw.mu.Unlock()
|
||||||
|
|
||||||
|
return filepath.Walk(absDir, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -78,6 +88,7 @@ func (fw *FileWatcher) pollLoop() {
|
|||||||
return
|
return
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
fw.checkFiles()
|
fw.checkFiles()
|
||||||
|
fw.scanForNewFiles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,7 +114,7 @@ func (fw *FileWatcher) checkFiles() {
|
|||||||
now := time.Now()
|
now := time.Now()
|
||||||
if now.Sub(fw.lastEvent) > time.Duration(fw.debounceMs)*time.Millisecond {
|
if now.Sub(fw.lastEvent) > time.Duration(fw.debounceMs)*time.Millisecond {
|
||||||
fw.lastEvent = now
|
fw.lastEvent = now
|
||||||
log.Printf("File changed: %s", path)
|
// log.Printf("File changed: %s", path)
|
||||||
changed = true
|
changed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,6 +128,57 @@ func (fw *FileWatcher) checkFiles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fw *FileWatcher) scanForNewFiles() {
|
||||||
|
fw.mu.RLock()
|
||||||
|
dirs := make(map[string]bool, len(fw.dirs))
|
||||||
|
maps.Copy(dirs, fw.dirs)
|
||||||
|
existingFiles := make(map[string]bool, len(fw.files))
|
||||||
|
for path := range fw.files {
|
||||||
|
existingFiles[path] = true
|
||||||
|
}
|
||||||
|
fw.mu.RUnlock()
|
||||||
|
|
||||||
|
newFilesFound := false
|
||||||
|
for dir := range dirs {
|
||||||
|
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !info.IsDir() && strings.HasSuffix(path, ".lua") {
|
||||||
|
absPath, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !existingFiles[absPath] {
|
||||||
|
fw.mu.Lock()
|
||||||
|
fw.files[absPath] = info.ModTime()
|
||||||
|
fw.mu.Unlock()
|
||||||
|
|
||||||
|
fmt.Printf("New file detected: %s\n", absPath)
|
||||||
|
newFilesFound = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if newFilesFound {
|
||||||
|
now := time.Now()
|
||||||
|
if now.Sub(fw.lastEvent) > time.Duration(fw.debounceMs)*time.Millisecond {
|
||||||
|
fw.lastEvent = now
|
||||||
|
select {
|
||||||
|
case fw.restartCh <- true:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (fw *FileWatcher) Close() error {
|
func (fw *FileWatcher) Close() error {
|
||||||
select {
|
select {
|
||||||
case fw.stopCh <- true:
|
case fw.stopCh <- true:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user