optional http logging, updated module watcher
This commit is contained in:
parent
82a7c88d35
commit
522a5770ed
|
@ -19,16 +19,18 @@ type Server struct {
|
|||
luaRunner *runner.LuaRunner
|
||||
logger *logger.Logger
|
||||
httpServer *http.Server
|
||||
loggingEnabled bool
|
||||
}
|
||||
|
||||
// New creates a new HTTP server with optimized connection settings
|
||||
func New(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRouter, runner *runner.LuaRunner, log *logger.Logger) *Server {
|
||||
func New(luaRouter *routers.LuaRouter, staticRouter *routers.StaticRouter, runner *runner.LuaRunner, log *logger.Logger, loggingEnabled bool) *Server {
|
||||
server := &Server{
|
||||
luaRouter: luaRouter,
|
||||
staticRouter: staticRouter,
|
||||
luaRunner: runner,
|
||||
logger: log,
|
||||
httpServer: &http.Server{},
|
||||
loggingEnabled: loggingEnabled,
|
||||
}
|
||||
server.httpServer.Handler = server
|
||||
|
||||
|
@ -74,7 +76,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
statusCode := wrappedWriter.StatusCode()
|
||||
|
||||
// Log the request with our custom format
|
||||
if s.loggingEnabled {
|
||||
LogRequest(s.logger, statusCode, r, duration)
|
||||
}
|
||||
}
|
||||
|
||||
// handleRequest processes the actual request
|
||||
|
|
|
@ -212,21 +212,8 @@ func (c *RequireCache) RefreshAll() int {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Collect paths to check
|
||||
var paths []string
|
||||
c.modules.Range(func(key, _ any) bool {
|
||||
if path, ok := key.(string); ok {
|
||||
paths = append(paths, path)
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
// Check each path
|
||||
for _, path := range paths {
|
||||
if c.RefreshModule(path) {
|
||||
refreshed++
|
||||
}
|
||||
}
|
||||
// For maximum performance, just clear everything
|
||||
c.Clear()
|
||||
|
||||
// Reset the needsRefresh flag
|
||||
c.needsRefresh.Store(false)
|
||||
|
@ -267,6 +254,13 @@ func findAndCompileModule(
|
|||
}
|
||||
}
|
||||
|
||||
// If the cache needs refresh, handle it immediately
|
||||
if cache.needsRefresh.Load() {
|
||||
cache.Clear() // Complete reset for max performance
|
||||
cache.needsRefresh.Store(false)
|
||||
cache.lastRefresh = time.Now()
|
||||
}
|
||||
|
||||
// Try each path
|
||||
for _, path := range paths {
|
||||
// Clean the path to handle .. and such (security)
|
||||
|
@ -295,7 +289,7 @@ func findAndCompileModule(
|
|||
return value.([]byte), nil
|
||||
}
|
||||
|
||||
// Only do refresh check if marked as needed (by watcher)
|
||||
// Check file modification time if cache is marked for refresh
|
||||
if cache.needsRefresh.Load() {
|
||||
fileInfo, err := os.Stat(cleanPath)
|
||||
// Remove from cache if file changed or doesn't exist
|
||||
|
@ -303,10 +297,15 @@ func findAndCompileModule(
|
|||
cache.modules.Delete(cleanPath)
|
||||
// Continue to recompile
|
||||
} else {
|
||||
// Update last used time and return cached bytecode
|
||||
entry.LastUsed = time.Now()
|
||||
cache.modules.Store(cleanPath, entry)
|
||||
return entry.Bytecode, nil
|
||||
}
|
||||
} else {
|
||||
// No refresh needed, use cached bytecode
|
||||
// Update last used time and return cached bytecode
|
||||
entry.LastUsed = time.Now()
|
||||
cache.modules.Store(cleanPath, entry)
|
||||
return entry.Bytecode, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,18 @@ func WatchLuaModules(luaRunner *runner.LuaRunner, libDirs []string, log *logger.
|
|||
watchers := make([]*Watcher, 0, len(libDirs))
|
||||
|
||||
for _, dir := range libDirs {
|
||||
// Create a directory-specific callback that only signals changes
|
||||
// without doing heavy processing in the callback itself
|
||||
// Create a directory-specific callback that only does minimal work
|
||||
dirCopy := dir // Capture for closure
|
||||
|
||||
callback := func() error {
|
||||
log.Debug("Detected changes in Lua module directory: %s", dirCopy)
|
||||
// Only mark that refresh is needed instead of doing refresh now
|
||||
luaRunner.RequireCache().MarkNeedsRefresh()
|
||||
|
||||
// Completely reset the cache to match fresh-start performance
|
||||
luaRunner.RequireCache().Clear()
|
||||
|
||||
// Force reset of Lua's module registry
|
||||
luaRunner.ResetPackageLoaded()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -27,13 +31,11 @@ func WatchLuaModules(luaRunner *runner.LuaRunner, libDirs []string, log *logger.
|
|||
Log: log,
|
||||
Recursive: true,
|
||||
Adaptive: true,
|
||||
// Use a longer debounce time to avoid too frequent updates
|
||||
DebounceTime: defaultDebounceTime * 4,
|
||||
DebounceTime: defaultDebounceTime,
|
||||
}
|
||||
|
||||
watcher, err := WatchDirectory(config)
|
||||
if err != nil {
|
||||
// Close any watchers we've already created
|
||||
for _, w := range watchers {
|
||||
w.Close()
|
||||
}
|
||||
|
|
|
@ -14,9 +14,7 @@ import (
|
|||
const (
|
||||
defaultPollInterval = 1 * time.Second // Initial polling interval
|
||||
extendedPollInterval = 5 * time.Second // Extended polling interval after inactivity
|
||||
maxPollInterval = 10 * time.Second // Maximum polling interval after long inactivity
|
||||
inactivityThreshold = 5 * time.Minute // Time before extending polling interval
|
||||
secondExtendThreshold = 30 * time.Minute // Time before second extension
|
||||
inactivityThreshold = 10 * time.Minute // Time before extending polling interval
|
||||
)
|
||||
|
||||
// Default debounce time between detected change and callback
|
||||
|
@ -121,7 +119,7 @@ func WatchDirectory(config WatcherConfig) (*Watcher, error) {
|
|||
go w.debounceLoop()
|
||||
|
||||
if config.Adaptive {
|
||||
w.logDebug("Started watching with adaptive polling")
|
||||
w.logDebug("Started watching with adaptive polling (1s default, 5s after 10m inactivity)")
|
||||
} else {
|
||||
w.logDebug("Started watching with fixed polling interval: %v", pollInterval)
|
||||
}
|
||||
|
@ -173,17 +171,11 @@ func (w *Watcher) watchLoop() {
|
|||
inactiveDuration := time.Since(w.lastChangeTime)
|
||||
|
||||
if w.pollInterval == w.basePollInterval && inactiveDuration > inactivityThreshold {
|
||||
// First extension
|
||||
// Extend polling interval
|
||||
w.pollInterval = extendedPollInterval
|
||||
ticker.Reset(w.pollInterval)
|
||||
w.logDebug("Extended polling interval to: %v after %v of inactivity",
|
||||
w.pollInterval, inactiveDuration.Round(time.Second))
|
||||
} else if w.pollInterval == extendedPollInterval && inactiveDuration > secondExtendThreshold {
|
||||
// Second extension
|
||||
w.pollInterval = maxPollInterval
|
||||
ticker.Reset(w.pollInterval)
|
||||
w.logDebug("Extended polling interval to: %v after %v of inactivity",
|
||||
w.pollInterval, inactiveDuration.Round(time.Second))
|
||||
w.pollInterval, inactiveDuration.Round(time.Minute))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,6 +260,7 @@ func (w *Watcher) logError(format string, args ...any) {
|
|||
w.log.Error("[Watcher] [%s] %s", w.dir, fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
// checkForChanges detects if any files have been added, modified, or deleted
|
||||
func (w *Watcher) checkForChanges() (bool, error) {
|
||||
// Get current state
|
||||
currentFiles := make(map[string]FileInfo)
|
||||
|
@ -308,43 +301,36 @@ func (w *Watcher) checkForChanges() (bool, error) {
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// Check for modified files
|
||||
var changed bool
|
||||
// Check for modified, added, or removed files
|
||||
for path, currentInfo := range currentFiles {
|
||||
prevInfo, exists := previousFiles[path]
|
||||
if !exists {
|
||||
// New file
|
||||
w.logDebug("New file detected: %s", path)
|
||||
changed = true
|
||||
break
|
||||
w.updateFiles(currentFiles)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if currentInfo.ModTime != prevInfo.ModTime || currentInfo.Size != prevInfo.Size {
|
||||
// File modified
|
||||
w.logDebug("File modified: %s", path)
|
||||
changed = true
|
||||
break
|
||||
w.updateFiles(currentFiles)
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Check for deleted files
|
||||
if !changed {
|
||||
for path := range previousFiles {
|
||||
if _, exists := currentFiles[path]; !exists {
|
||||
// File deleted
|
||||
w.logDebug("File deleted: %s", path)
|
||||
changed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update internal files state if there were changes
|
||||
if changed {
|
||||
w.updateFiles(currentFiles)
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return changed, nil
|
||||
// No changes detected
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// updateFiles updates the internal file list
|
||||
|
|
|
@ -208,8 +208,15 @@ func main() {
|
|||
}
|
||||
}()
|
||||
|
||||
httpLoggingEnabled := cfg.GetBool("http_logging_enabled", true)
|
||||
if httpLoggingEnabled {
|
||||
log.Info("HTTP logging is enabled")
|
||||
} else {
|
||||
log.Info("HTTP logging is disabled")
|
||||
}
|
||||
|
||||
// Create HTTP server
|
||||
server := http.New(luaRouter, staticRouter, luaRunner, log)
|
||||
server := http.New(luaRouter, staticRouter, luaRunner, log, httpLoggingEnabled)
|
||||
|
||||
// Handle graceful shutdown
|
||||
stop := make(chan os.Signal, 1)
|
||||
|
|
Loading…
Reference in New Issue
Block a user