diff --git a/launchpad/pkg/filewatcher.go b/launchpad/pkg/filewatcher.go index cd6a0a6..2a2d369 100644 --- a/launchpad/pkg/filewatcher.go +++ b/launchpad/pkg/filewatcher.go @@ -7,7 +7,23 @@ import ( "sync" ) -var changeFlagLock sync.Mutex +var ( + changeFlagLock sync.Mutex + workLock sync.Mutex + isPaused = false +) + +func PauseFileWatcher() { + workLock.Lock() + defer workLock.Unlock() + isPaused = true +} + +func ContinueFileWatcher() { + workLock.Lock() + defer workLock.Unlock() + isPaused = false +} func StartFileWatcher() error { watcher, err := fsnotify.NewWatcher() @@ -24,9 +40,17 @@ func StartFileWatcher() error { return } if event.Op&(fsnotify.Create|fsnotify.Write|fsnotify.Remove) != 0 { + workLock.Lock() + if isPaused { + workLock.Unlock() + fmt.Printf("%v config changed, but file watcher is paused \n", event.Name) + return + } fmt.Printf("%v config changed, regenerating JSON...\n", event.Name) if err := CombineJSONFiles(InputDir); err != nil { fmt.Printf("Error combining JSON files: %v\n", err) + workLock.Unlock() + return } if strings.HasSuffix(event.Name, "changing-flag.json") { changeFlagLock.Lock() @@ -36,6 +60,8 @@ func StartFileWatcher() error { changeFlagUpdateListeners = nil changeFlagLock.Unlock() } + + workLock.Unlock() } case err, ok := <-watcher.Errors: if !ok { diff --git a/launchpad/pkg/flagd.go b/launchpad/pkg/flagd.go index ea2739e..37929fd 100644 --- a/launchpad/pkg/flagd.go +++ b/launchpad/pkg/flagd.go @@ -3,8 +3,10 @@ package flagd import ( "bufio" "context" + "errors" "fmt" "io" + "os" "os/exec" "strings" "sync" @@ -18,6 +20,21 @@ var ( restartCancelFunc context.CancelFunc // Stores the cancel function for delayed restarts ) +func ensureStartConditions() { + if _, err := os.Stat(OutputFile); errors.Is(err, os.ErrNotExist) { + err := CombineJSONFiles(InputDir) + if err != nil { + fmt.Printf("Error combining JSON files on flagd start: %v\n", err) + } + } + ContinueFileWatcher() +} + +func deleteCombinedFlagsFile() { + // if we cannot delete it, we can assume it did not exist in the first place, so we can ignore this error + _ = os.Remove(OutputFile) +} + func RestartFlagd(seconds int) { flagdLock.Lock() if restartCancelFunc != nil { @@ -28,6 +45,8 @@ func RestartFlagd(seconds int) { ctx, cancel := context.WithCancel(context.Background()) restartCancelFunc = cancel + PauseFileWatcher() + deleteCombinedFlagsFile() err := stopFlagDWithoutLock() if err != nil { fmt.Printf("Failed to restart flagd: %v\n", err) @@ -69,6 +88,8 @@ func StartFlagd(config string) error { return err } + ensureStartConditions() + configPath := fmt.Sprintf("./configs/%s.json", config) flagdCmd = exec.Command("./flagd", "start", "--config", configPath)