From 5e3a28398dbb6de3d743a3a0c9bd43a03cdfbf94 Mon Sep 17 00:00:00 2001 From: LordMathis Date: Sun, 17 Aug 2025 21:10:48 +0200 Subject: [PATCH] Implement periodic timeout checking for instances --- pkg/instance/timeout.go | 3 +-- pkg/manager/manager.go | 19 +++++++++++++++++++ pkg/manager/timeout.go | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 pkg/manager/timeout.go diff --git a/pkg/instance/timeout.go b/pkg/instance/timeout.go index fd9eeb5..4b7a8c8 100644 --- a/pkg/instance/timeout.go +++ b/pkg/instance/timeout.go @@ -15,8 +15,7 @@ func (i *Process) ShouldTimeout() bool { i.mu.RLock() defer i.mu.RUnlock() - // If idle timeout is not set, no timeout - if i.options.IdleTimeout == nil || *i.options.IdleTimeout <= 0 { + if !i.Running || i.options.IdleTimeout == nil || *i.options.IdleTimeout <= 0 { return false } diff --git a/pkg/manager/manager.go b/pkg/manager/manager.go index 43b1fea..12d0e77 100644 --- a/pkg/manager/manager.go +++ b/pkg/manager/manager.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strings" "sync" + "time" ) // InstanceManager defines the interface for managing instances of the llama server. @@ -31,6 +32,9 @@ type instanceManager struct { instances map[string]*instance.Process ports map[int]bool instancesConfig config.InstancesConfig + + // Timeout checker + timeoutChecker *time.Ticker } // NewInstanceManager creates a new instance of InstanceManager. @@ -39,12 +43,21 @@ func NewInstanceManager(instancesConfig config.InstancesConfig) InstanceManager instances: make(map[string]*instance.Process), ports: make(map[int]bool), instancesConfig: instancesConfig, + + timeoutChecker: time.NewTicker(time.Duration(instancesConfig.TimeoutCheckInterval) * time.Minute), } // Load existing instances from disk if err := im.loadInstances(); err != nil { log.Printf("Error loading instances: %v", err) } + + go func() { + for range im.timeoutChecker.C { + im.checkAllTimeouts() + } + }() + return im } @@ -94,6 +107,12 @@ func (im *instanceManager) Shutdown() { im.mu.Lock() defer im.mu.Unlock() + // Stop the timeout checker + if im.timeoutChecker != nil { + im.timeoutChecker.Stop() + im.timeoutChecker = nil + } + var wg sync.WaitGroup wg.Add(len(im.instances)) diff --git a/pkg/manager/timeout.go b/pkg/manager/timeout.go new file mode 100644 index 0000000..090311b --- /dev/null +++ b/pkg/manager/timeout.go @@ -0,0 +1,19 @@ +package manager + +import "log" + +func (im *instanceManager) checkAllTimeouts() { + im.mu.RLock() + defer im.mu.RUnlock() + + for _, inst := range im.instances { + if inst.ShouldTimeout() { + log.Printf("Instance %s has timed out, stopping it", inst.Name) + if proc, err := im.StopInstance(inst.Name); err != nil { + log.Printf("Error stopping instance %s: %v", inst.Name, err) + } else { + log.Printf("Instance %s stopped successfully, process: %v", inst.Name, proc) + } + } + } +}