From 74495f8163ac3b8e644f50847655dc63a605e9ed Mon Sep 17 00:00:00 2001 From: LordMathis Date: Sat, 30 Aug 2025 22:04:43 +0200 Subject: [PATCH 1/2] Refactor Shutdown method to improve instance stopping logic and avoid deadlocks --- pkg/manager/manager.go | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/pkg/manager/manager.go b/pkg/manager/manager.go index 90ef27b..5d60f3a 100644 --- a/pkg/manager/manager.go +++ b/pkg/manager/manager.go @@ -123,10 +123,10 @@ func (im *instanceManager) persistInstance(instance *instance.Process) error { func (im *instanceManager) Shutdown() { im.mu.Lock() - defer im.mu.Unlock() // Check if already shutdown if im.isShutdown { + im.mu.Unlock() return } im.isShutdown = true @@ -134,27 +134,32 @@ func (im *instanceManager) Shutdown() { // Signal the timeout checker to stop close(im.shutdownChan) - // Release lock temporarily to wait for goroutine + // Create a list of running instances to stop + var runningInstances []*instance.Process + var runningNames []string + for name, inst := range im.instances { + if inst.IsRunning() { + runningInstances = append(runningInstances, inst) + runningNames = append(runningNames, name) + } + } + + // Release lock before stopping instances to avoid deadlock im.mu.Unlock() + // Wait for the timeout checker goroutine to actually stop <-im.shutdownDone - // Reacquire lock - im.mu.Lock() // Now stop the ticker if im.timeoutChecker != nil { im.timeoutChecker.Stop() } + // Stop instances without holding the manager lock var wg sync.WaitGroup - wg.Add(len(im.instances)) - - for name, inst := range im.instances { - if !inst.IsRunning() { - wg.Done() // If instance is not running, just mark it as done - continue - } + wg.Add(len(runningInstances)) + for i, inst := range runningInstances { go func(name string, inst *instance.Process) { defer wg.Done() fmt.Printf("Stopping instance %s...\n", name) @@ -162,7 +167,7 @@ func (im *instanceManager) Shutdown() { if err := inst.Stop(); err != nil { fmt.Printf("Error stopping instance %s: %v\n", name, err) } - }(name, inst) + }(runningNames[i], inst) } wg.Wait() From fdd46859b9327b2a9c0a59cb4cd657405609299e Mon Sep 17 00:00:00 2001 From: LordMathis Date: Sat, 30 Aug 2025 22:04:52 +0200 Subject: [PATCH 2/2] Add environment variables for development configuration in launch.json --- .vscode/launch.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 7f4175c..cb01dbe 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,6 +10,10 @@ "request": "launch", "mode": "auto", "program": "${workspaceFolder}/cmd/server/main.go", + "env": { + "GO_ENV": "development", + "LLAMACTL_REQUIRE_MANAGEMENT_AUTH": "false" + }, } ] } \ No newline at end of file