Skip to content

Commit

Permalink
Merge pull request #127 from zong-zhe/fix-windows-lock
Browse files Browse the repository at this point in the history
fix: lock on global file package-cache when 'kpm add'.
  • Loading branch information
Peefy authored Jul 18, 2023
2 parents d20ac3d + 959db7d commit 523917d
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 57 deletions.
40 changes: 19 additions & 21 deletions pkg/cmd/cmd_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
package cmd

import (
"context"
"fmt"
"os"
"strings"
"time"

"github.com/gofrs/flock"
"github.com/urfave/cli/v2"
"kcl-lang.io/kpm/pkg/env"
"kcl-lang.io/kpm/pkg/errors"
Expand Down Expand Up @@ -37,6 +34,25 @@ func NewAddCmd() *cli.Command {
},

Action: func(c *cli.Context) error {
// 1. get settings from the global config file.
settings, err := settings.GetSettings()
if err != nil {
return err
}

// 2. acquire the lock of the package cache.
err = settings.AcquirePackageCacheLock()
if err != nil {
return err
}

defer func() {
// 3. release the lock of the package cache after the function returns.
releaseErr := settings.ReleasePackageCacheLock()
if releaseErr != nil && err == nil {
err = releaseErr
}
}()

pwd, err := os.Getwd()

Expand Down Expand Up @@ -69,24 +85,6 @@ func NewAddCmd() *cli.Command {
return err
}

// Lock the kcl.mod.lock.
fileLock := flock.New(kclPkg.GetLockFilePath())
lockCtx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
locked, err := fileLock.TryLockContext(lockCtx, time.Second)
if err == nil && locked {
defer func() {
if unlockErr := fileLock.Unlock(); unlockErr != nil && err == nil {
err = errors.InternalBug
}
}()
}
if err != nil {
reporter.Report("kpm: sorry, the program encountered an issue while trying to add a dependency.")
reporter.Report("kpm: please try again later")
return err
}

err = kclPkg.AddDeps(addOpts)
if err != nil {
return err
Expand Down
8 changes: 0 additions & 8 deletions pkg/mod/modfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,6 @@ func (dep *Dependency) Download(localPath string) (*Dependency, error) {
return nil, err
}

// Creating symbolic links in a global cache is not an optimal solution.
// This allows kcl compiler to locate the package by default.
// This feature is unstable and will be removed soon.
err = utils.CreateSymlink(dep.LocalFullPath, filepath.Join(filepath.Dir(dep.LocalFullPath), dep.Name))
if err != nil {
return nil, err
}

return dep, nil
}

Expand Down
28 changes: 4 additions & 24 deletions pkg/package/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"kcl-lang.io/kpm/pkg/opt"
"kcl-lang.io/kpm/pkg/reporter"
"kcl-lang.io/kpm/pkg/runner"
"kcl-lang.io/kpm/pkg/settings"
"kcl-lang.io/kpm/pkg/utils"
)

Expand Down Expand Up @@ -250,36 +249,17 @@ func (kclPkg *KclPkg) CreateDefaultKclProgram() error {

// AddDeps will add the dependencies to current kcl package and update kcl.mod and kcl.mod.lock.
func (kclPkg *KclPkg) AddDeps(opt *opt.AddOptions) error {
// 1. get settings from the global config file.
settings, err := settings.GetSettings()
if err != nil {
return err
}

// 2. acquire the lock of the package cache.
err = settings.AcquirePackageCacheLock()
if err != nil {
return err
}

defer func() {
// 3. release the lock of the package cache after the function returns.
releaseErr := settings.ReleasePackageCacheLock()
if releaseErr != nil && err == nil {
err = releaseErr
}
}()

// 4. get the name and version of the repository from the input arguments.
// 1. get the name and version of the repository from the input arguments.
d := modfile.ParseOpt(&opt.RegistryOpts)

// 5. download the dependency to the local path.
err = kclPkg.DownloadDep(d, opt.LocalPath)
// 2. download the dependency to the local path.
err := kclPkg.DownloadDep(d, opt.LocalPath)
if err != nil {
return err
}

// 6. update the kcl.mod and kcl.mod.lock.
// 3. update the kcl.mod and kcl.mod.lock.
err = kclPkg.UpdateModAndLockFile()
if err != nil {
return err
Expand Down
12 changes: 8 additions & 4 deletions pkg/settings/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,24 +123,28 @@ func TestPackageCacheLock(t *testing.T) {
go func() {
defer wg.Done()
err := settings.AcquirePackageCacheLock()
assert.Equal(t, err, nil)
fmt.Printf("1: locked.")
fmt.Printf("err: %v\n", err)
for i := 0; i < 10; i++ {
gotlist = append(gotlist, fmt.Sprintf("goroutine 1: %d", i))
}
err = settings.ReleasePackageCacheLock()
assert.Equal(t, err, nil)
fmt.Printf("err: %v\n", err)
fmt.Printf("1: released.")
}()

// goroutine 2: append "goroutine 2: %d" to the list
go func() {
defer wg.Done()
err := settings.AcquirePackageCacheLock()
assert.Equal(t, err, nil)
fmt.Printf("2: locked.")
fmt.Printf("err: %v\n", err)
for i := 0; i < 10; i++ {
gotlist = append(gotlist, fmt.Sprintf("goroutine 2: %d", i))
}
err = settings.ReleasePackageCacheLock()
assert.Equal(t, err, nil)
fmt.Printf("err: %v\n", err)
fmt.Printf("2: released.")
}()

wg.Wait()
Expand Down

0 comments on commit 523917d

Please sign in to comment.