Moonshark/core/watchers/api.go

149 lines
3.7 KiB
Go

package watchers
import (
"fmt"
"sync"
"git.sharkk.net/Sky/Moonshark/core/logger"
"git.sharkk.net/Sky/Moonshark/core/routers"
"git.sharkk.net/Sky/Moonshark/core/runner"
)
// Global watcher manager instance
var (
globalManager *WatcherManager
globalManagerOnce sync.Once
)
// GetWatcherManager returns the global watcher manager, creating it if needed
func GetWatcherManager(log *logger.Logger, adaptive bool) *WatcherManager {
globalManagerOnce.Do(func() {
globalManager = NewWatcherManager(log, adaptive)
})
return globalManager
}
// WatchDirectory creates a new directory watcher and registers it with the manager
func WatchDirectory(config DirectoryWatcherConfig, manager *WatcherManager) (*Watcher, error) {
dirWatcher, err := NewDirectoryWatcher(config)
if err != nil {
return nil, fmt.Errorf("failed to create directory watcher: %w", err)
}
manager.AddWatcher(dirWatcher)
// Create a wrapper Watcher that implements the old interface
w := &Watcher{
dir: config.Dir,
dirWatch: dirWatcher,
manager: manager,
}
config.Log.Debug("Started watching directory: %s", config.Dir)
return w, nil
}
// Watcher is a compatibility wrapper that maintains the old API
type Watcher struct {
dir string
dirWatch *DirectoryWatcher
manager *WatcherManager
}
// Close unregisters the watcher from the manager
func (w *Watcher) Close() error {
w.manager.RemoveWatcher(w.dir)
return nil
}
// WatchLuaRouter sets up a watcher for a LuaRouter's routes directory
func WatchLuaRouter(router *routers.LuaRouter, routesDir string, log *logger.Logger) (*Watcher, error) {
manager := GetWatcherManager(log, true) // Use adaptive polling
config := DirectoryWatcherConfig{
Dir: routesDir,
Callback: router.Refresh,
Log: log,
Recursive: true,
}
watcher, err := WatchDirectory(config, manager)
if err != nil {
return nil, err
}
log.Info("Started watching Lua routes directory: %s", routesDir)
return watcher, nil
}
// WatchStaticRouter sets up a watcher for a StaticRouter's root directory
func WatchStaticRouter(router *routers.StaticRouter, staticDir string, log *logger.Logger) (*Watcher, error) {
manager := GetWatcherManager(log, true) // Use adaptive polling
config := DirectoryWatcherConfig{
Dir: staticDir,
Callback: router.Refresh,
Log: log,
Recursive: true,
}
watcher, err := WatchDirectory(config, manager)
if err != nil {
return nil, err
}
log.Info("Started watching static files directory: %s", staticDir)
return watcher, nil
}
// WatchLuaModules sets up watchers for Lua module directories
func WatchLuaModules(luaRunner *runner.LuaRunner, libDirs []string, log *logger.Logger) ([]*Watcher, error) {
manager := GetWatcherManager(log, true) // Use adaptive polling
watchers := make([]*Watcher, 0, len(libDirs))
for _, dir := range libDirs {
// Create a directory-specific callback
dirCopy := dir // Capture for closure
callback := func() error {
log.Debug("Detected changes in Lua module directory: %s", dirCopy)
// Reload modules from this directory
if err := luaRunner.ReloadAllModules(); err != nil {
log.Warning("Error reloading modules: %v", err)
}
return nil
}
config := DirectoryWatcherConfig{
Dir: dir,
Callback: callback,
Log: log,
Recursive: true,
}
watcher, err := WatchDirectory(config, manager)
if err != nil {
// Clean up already created watchers
for _, w := range watchers {
w.Close()
}
return nil, err
}
watchers = append(watchers, watcher)
log.Info("Started watching Lua modules directory: %s", dir)
}
return watchers, nil
}
// ShutdownWatcherManager closes the global watcher manager if it exists
func ShutdownWatcherManager() {
if globalManager != nil {
globalManager.Close()
globalManager = nil
}
}