Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Add retry on locks
Browse files Browse the repository at this point in the history
Fabianoshz committed Oct 11, 2024
1 parent 346a4d8 commit d313d5a
Showing 2 changed files with 297 additions and 223 deletions.
483 changes: 269 additions & 214 deletions server/events/mock_workingdir_test.go
37 changes: 28 additions & 9 deletions server/events/working_dir_locker.go
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ import (
"fmt"
"strings"
"sync"
"time"
)

//go:generate pegomock generate --package mocks -o mocks/mock_working_dir_locker.go WorkingDirLocker
@@ -52,7 +53,7 @@ type DefaultWorkingDirLocker struct {
}

// NewDefaultWorkingDirLocker is a constructor.
func NewDefaultWorkingDirLocker() *DefaultWorkingDirLocker {
func NewDefaultWorkingDirLocker() WorkingDirLocker {
return &DefaultWorkingDirLocker{}
}

@@ -78,19 +79,37 @@ func (d *DefaultWorkingDirLocker) TryLock(repoFullName string, pullNum int, work
d.mutex.Lock()
defer d.mutex.Unlock()

pullKey := d.pullKey(repoFullName, pullNum)
workspaceKey := d.workspaceKey(repoFullName, pullNum, workspace, path)
for _, l := range d.locks {
if l == pullKey || l == workspaceKey {
ticker := time.NewTicker(time.Second)
// TODO: make this configurable
timeout := time.NewTimer(1 * time.Second)
var acquireLock bool

for {
workspaceKey := d.workspaceKey(repoFullName, pullNum, workspace, path)

if acquireLock || len(d.locks) == 0 {
d.locks = append(d.locks, workspaceKey)
return func() {
d.unlock(repoFullName, pullNum, workspace, path)
}, nil
}

select {
case <-timeout.C:
return func() {}, fmt.Errorf("the %s workspace at path %s is currently locked by another"+
" command that is running for this pull request.\n"+
"Wait until the previous command is complete and try again", workspace, path)
case <-ticker.C:
acquireLock = true
for _, l := range d.locks {
pullKey := d.pullKey(repoFullName, pullNum)
if l == pullKey || l == workspaceKey {
acquireLock = false
}
}
}

}
d.locks = append(d.locks, workspaceKey)
return func() {
d.unlock(repoFullName, pullNum, workspace, path)
}, nil
}

// Unlock unlocks the workspace for this pull.

0 comments on commit d313d5a

Please sign in to comment.