@@ -17,6 +17,7 @@ import (
17
17
"fmt"
18
18
"strings"
19
19
"sync"
20
+ "time"
20
21
)
21
22
22
23
//go:generate pegomock generate --package mocks -o mocks/mock_working_dir_locker.go WorkingDirLocker
@@ -78,19 +79,35 @@ func (d *DefaultWorkingDirLocker) TryLock(repoFullName string, pullNum int, work
78
79
d .mutex .Lock ()
79
80
defer d .mutex .Unlock ()
80
81
81
- pullKey := d .pullKey (repoFullName , pullNum )
82
- workspaceKey := d .workspaceKey (repoFullName , pullNum , workspace , path )
83
- for _ , l := range d .locks {
84
- if l == pullKey || l == workspaceKey {
85
- return func () {}, fmt .Errorf ("the %s workspace at path %s is currently locked by another" +
86
- " command that is running for this pull request.\n " +
87
- "Wait until the previous command is complete and try again" , workspace , path )
82
+ ticker := time .NewTicker (time .Second )
83
+ timeout := time .NewTimer (600 * time .Second )
84
+ addLock := false
85
+
86
+ for {
87
+ workspaceKey := d .workspaceKey (repoFullName , pullNum , workspace , path )
88
+
89
+ if addLock || len (d .locks ) == 0 {
90
+ d .locks = append (d .locks , workspaceKey )
91
+ return func () {
92
+ d .unlock (repoFullName , pullNum , workspace , path )
93
+ }, nil
88
94
}
95
+
96
+ select {
97
+ case <- timeout .C :
98
+ return func () {}, fmt .Errorf ("the Atlantis working dir is currently locked by another" +
99
+ " command that is running for this pull request.\n " +
100
+ "Wait until the previous command is complete and try again" )
101
+ case <- ticker .C :
102
+ for _ , l := range d .locks {
103
+ pullKey := d .pullKey (repoFullName , pullNum )
104
+ if l != pullKey && l != workspaceKey {
105
+ addLock = true
106
+ }
107
+ }
108
+ }
109
+
89
110
}
90
- d .locks = append (d .locks , workspaceKey )
91
- return func () {
92
- d .unlock (repoFullName , pullNum , workspace , path )
93
- }, nil
94
111
}
95
112
96
113
// Unlock unlocks the workspace for this pull.
0 commit comments