Skip to content

Commit

Permalink
fix: lock git checkout dirs
Browse files Browse the repository at this point in the history
  • Loading branch information
moshloop committed Nov 26, 2023
1 parent 4e108ad commit 9f546ee
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
16 changes: 13 additions & 3 deletions checks/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@ import (
"path/filepath"
"runtime"
"strings"
"time"

"github.com/flanksource/canary-checker/api/context"
"github.com/flanksource/canary-checker/api/external"
v1 "github.com/flanksource/canary-checker/api/v1"
"github.com/flanksource/canary-checker/pkg"
"github.com/flanksource/canary-checker/pkg/utils"
"github.com/flanksource/commons/files"
"github.com/flanksource/commons/hash"
"github.com/flanksource/duty/models"
"github.com/hashicorp/go-getter"
)

var checkoutLocks = utils.NamedLock{}

type ExecChecker struct {
}

Expand Down Expand Up @@ -91,11 +95,17 @@ func (c *ExecChecker) prepareEnvironment(ctx *context.Context, check v1.ExecChec

result.mountPoint = check.Checkout.Destination
if result.mountPoint == "" {
pwd, _ := os.Getwd()
result.mountPoint = filepath.Join(pwd, ".downloads", hash.Sha256Hex(goGetterURL))
result.mountPoint = filepath.Join("exec-checkout", hash.Sha256Hex(goGetterURL))
}
// We allow multiple checks to use the same checkout location, for disk space and performance reasons
// however git does not allow multiple operations to be performed, so we need to lock it
lock := checkoutLocks.TryLock(result.mountPoint, 5*time.Minute)
if lock == nil {
return nil, fmt.Errorf("failed to acquire checkout lock for %s", result.mountPoint)
}
defer lock.Release()

if err := checkout(ctx, goGetterURL, result.mountPoint); err != nil {
if err := checkout(ctx, goGetterURL, filepath.Join(os.TempDir(), result.mountPoint)); err != nil {
return nil, fmt.Errorf("error checking out: %w", err)
}
}
Expand Down
32 changes: 32 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,48 @@
package utils

import (
"context"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"sync"
"time"

"golang.org/x/sync/semaphore"

"github.com/google/uuid"
"k8s.io/apimachinery/pkg/util/duration"
)

type NamedLock struct {
locks sync.Map
}

type Unlocker interface {
Release()
}

type unlocker struct {
lock *semaphore.Weighted
}

func (u *unlocker) Release() {
u.lock.Release(1)
}

func (n *NamedLock) TryLock(name string, timeout time.Duration) Unlocker {
o, _ := n.locks.LoadOrStore(name, semaphore.NewWeighted(1))
lock := o.(*semaphore.Weighted)

ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(timeout))
defer cancel()
if err := lock.Acquire(ctx, 1); err != nil {
return nil
}
return &unlocker{lock}
}

func Age(d time.Duration) string {
if d.Milliseconds() == 0 {
return "0ms"
Expand Down

0 comments on commit 9f546ee

Please sign in to comment.