Skip to content

Commit 965003c

Browse files
committed
🐛 Use non blocking file locking for flock library
Signed-off-by: Vince Prignano <[email protected]>
1 parent 3c78540 commit 965003c

File tree

3 files changed

+25
-13
lines changed

3 files changed

+25
-13
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ require (
1212
github.com/imdario/mergo v0.3.12 // indirect
1313
github.com/onsi/ginkgo v1.16.4
1414
github.com/onsi/gomega v1.14.0
15+
github.com/pkg/errors v0.9.1
1516
github.com/prometheus/client_golang v1.11.0
1617
github.com/prometheus/client_model v0.2.0
1718
go.uber.org/goleak v1.1.10

pkg/internal/flock/flock_unix.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ limitations under the License.
1818

1919
package flock
2020

21-
import "golang.org/x/sys/unix"
21+
import (
22+
"github.com/pkg/errors"
23+
"golang.org/x/sys/unix"
24+
)
25+
26+
var (
27+
// ErrAlreadyLocked is returned when the file is already locked.
28+
ErrAlreadyLocked = errors.New("the file is already locked")
29+
)
2230

2331
// Acquire acquires a lock on a file for the duration of the process. This method
2432
// is reentrant.
@@ -30,6 +38,9 @@ func Acquire(path string) error {
3038

3139
// We don't need to close the fd since we should hold
3240
// it until the process exits.
33-
34-
return unix.Flock(fd, unix.LOCK_EX)
41+
err = unix.Flock(fd, unix.LOCK_NB|unix.LOCK_EX)
42+
if errors.Is(err, unix.EWOULDBLOCK) { // This condition requires LOCK_NB.
43+
return errors.Wrapf(ErrAlreadyLocked, "cannot lock file %q", path)
44+
}
45+
return err
3546
}

pkg/internal/testing/addr/manager.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package addr
1818

1919
import (
20+
"errors"
2021
"fmt"
2122
"io/fs"
2223
"net"
@@ -31,7 +32,7 @@ import (
3132
// TODO(directxman12): interface / release functionality for external port managers
3233

3334
const (
34-
portReserveTime = 10 * time.Minute
35+
portReserveTime = 2 * time.Minute
3536
portConflictRetry = 100
3637
portFilePrefix = "port-"
3738
)
@@ -76,7 +77,8 @@ func (c *portCache) add(port int) (bool, error) {
7677
return false, err
7778
}
7879
// Try allocating new port, by acquiring a file.
79-
if err := flock.Acquire(fmt.Sprintf("%s/%s%d", cacheDir, portFilePrefix, port)); os.IsExist(err) {
80+
path := fmt.Sprintf("%s/%s%d", cacheDir, portFilePrefix, port)
81+
if err := flock.Acquire(path); errors.Is(err, os.ErrExist) || errors.Is(err, flock.ErrAlreadyLocked) {
8082
return false, nil
8183
} else if err != nil {
8284
return false, err
@@ -86,22 +88,19 @@ func (c *portCache) add(port int) (bool, error) {
8688

8789
var cache = &portCache{}
8890

89-
func suggest(listenHost string) (int, string, error) {
91+
func suggest(listenHost string) (*net.TCPListener, int, string, error) {
9092
if listenHost == "" {
9193
listenHost = "localhost"
9294
}
9395
addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(listenHost, "0"))
9496
if err != nil {
95-
return -1, "", err
97+
return nil, -1, "", err
9698
}
9799
l, err := net.ListenTCP("tcp", addr)
98100
if err != nil {
99-
return -1, "", err
101+
return nil, -1, "", err
100102
}
101-
if err := l.Close(); err != nil {
102-
return -1, "", err
103-
}
104-
return l.Addr().(*net.TCPAddr).Port,
103+
return l, l.Addr().(*net.TCPAddr).Port,
105104
addr.IP.String(),
106105
nil
107106
}
@@ -112,10 +111,11 @@ func suggest(listenHost string) (int, string, error) {
112111
// allocated within 1 minute.
113112
func Suggest(listenHost string) (int, string, error) {
114113
for i := 0; i < portConflictRetry; i++ {
115-
port, resolvedHost, err := suggest(listenHost)
114+
listener, port, resolvedHost, err := suggest(listenHost)
116115
if err != nil {
117116
return -1, "", err
118117
}
118+
defer listener.Close()
119119
if ok, err := cache.add(port); ok {
120120
return port, resolvedHost, nil
121121
} else if err != nil {

0 commit comments

Comments
 (0)