Skip to content

Commit

Permalink
fix: runtime init panic
Browse files Browse the repository at this point in the history
Signed-off-by: peefy <[email protected]>
  • Loading branch information
Peefy committed Jul 24, 2024
1 parent 08b8ea6 commit efecf0a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 31 deletions.
29 changes: 2 additions & 27 deletions pkg/runtime/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,10 @@
package runtime

import (
"context"
"fmt"
"os"
"path/filepath"
"runtime"
"sync"
"time"

"github.com/gofrs/flock"
"kcl-lang.io/kcl-go/pkg/env"
"kcl-lang.io/kcl-go/pkg/logger"
"kcl-lang.io/kcl-go/pkg/path"
"kcl-lang.io/kcl-go/pkg/spec/gpyrpc"
)

Expand All @@ -36,25 +28,8 @@ func GetRuntime() *Runtime {
}

func initRuntime(maxProc int) {
if !env.GetDisableInstallArtifact() {
// Get the install lib path.
path := path.LibPath()
err := os.MkdirAll(path, 0777)
if err != nil {
logger.GetLogger().Warningf("install kclvm failed: %s", err.Error())
}
// Acquire a file lock for process synchronization
lockPath := filepath.Join(path, "init.lock")
fileLock := flock.New(lockPath)
lockCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
locked, err := fileLock.TryLockContext(lockCtx, time.Second)
if err == nil && locked {
defer fileLock.Unlock()
}
}
if maxProc <= 0 {
maxProc = 1
maxProc = 2
}
if maxProc > runtime.NumCPU()*2 {
maxProc = runtime.NumCPU() * 2
Expand All @@ -76,7 +51,7 @@ func initRuntime(maxProc int) {
args := &gpyrpc.Ping_Args{Value: "echo"}
resp, err := client.Ping(args)
if err != nil || resp.Value != args.Value {
fmt.Println("Init kcl runtime failed, path: ", MustGetKclvmPath())
fmt.Println("Init kcl runtime failed, path:", MustGetKclvmPath())
fmt.Println(tip)
fmt.Printf("If not, you can run `rm -r %s/bin` to fix this issue\n", MustGetKclvmPath())
panic(err)
Expand Down
28 changes: 28 additions & 0 deletions pkg/runtime/init_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright The KCL Authors. All rights reserved.

package runtime

import (
"sync"
"testing"
)

func TestInitRuntimeConcurrency(t *testing.T) {
var wg sync.WaitGroup
numConcurrentCalls := 10

for i := 0; i < numConcurrentCalls; i++ {
wg.Add(1)
go func(maxProc int) {
defer wg.Done()
defer func() {
if err := recover(); err != nil {
t.Errorf("initRuntime panicked: %v", err)
}
}()
initRuntime(maxProc)
}(2)
}

wg.Wait()
}
15 changes: 11 additions & 4 deletions pkg/runtime/kclvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,19 @@ func installKclArtifact() {
lockCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
locked, err := fileLock.TryLockContext(lockCtx, time.Second)
if err == nil && locked {
defer fileLock.Unlock()
}
if err != nil {
logger.GetLogger().Warningf("install kclvm failed: %s", err.Error())
logger.GetLogger().Warningf("attempt to acquire file lock failed: %s", err.Error())
return
}
if !locked {
logger.GetLogger().Warning("unable to acquire file lock")
return
}
defer func() {
if err := fileLock.Unlock(); err != nil {
logger.GetLogger().Errorf("failed to unlock file: %s", err.Error())
}
}()
// Install lib
err = lib.InstallKclvm(path)
if err != nil {
Expand Down

0 comments on commit efecf0a

Please sign in to comment.