@@ -17,6 +17,7 @@ limitations under the License.
17
17
package addr
18
18
19
19
import (
20
+ "errors"
20
21
"fmt"
21
22
"io/fs"
22
23
"net"
@@ -31,7 +32,7 @@ import (
31
32
// TODO(directxman12): interface / release functionality for external port managers
32
33
33
34
const (
34
- portReserveTime = 10 * time .Minute
35
+ portReserveTime = 2 * time .Minute
35
36
portConflictRetry = 100
36
37
portFilePrefix = "port-"
37
38
)
@@ -76,7 +77,8 @@ func (c *portCache) add(port int) (bool, error) {
76
77
return false , err
77
78
}
78
79
// 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 ) {
80
82
return false , nil
81
83
} else if err != nil {
82
84
return false , err
@@ -86,22 +88,19 @@ func (c *portCache) add(port int) (bool, error) {
86
88
87
89
var cache = & portCache {}
88
90
89
- func suggest (listenHost string ) (int , string , error ) {
91
+ func suggest (listenHost string ) (* net. TCPListener , int , string , error ) {
90
92
if listenHost == "" {
91
93
listenHost = "localhost"
92
94
}
93
95
addr , err := net .ResolveTCPAddr ("tcp" , net .JoinHostPort (listenHost , "0" ))
94
96
if err != nil {
95
- return - 1 , "" , err
97
+ return nil , - 1 , "" , err
96
98
}
97
99
l , err := net .ListenTCP ("tcp" , addr )
98
100
if err != nil {
99
- return - 1 , "" , err
101
+ return nil , - 1 , "" , err
100
102
}
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 ,
105
104
addr .IP .String (),
106
105
nil
107
106
}
@@ -112,10 +111,11 @@ func suggest(listenHost string) (int, string, error) {
112
111
// allocated within 1 minute.
113
112
func Suggest (listenHost string ) (int , string , error ) {
114
113
for i := 0 ; i < portConflictRetry ; i ++ {
115
- port , resolvedHost , err := suggest (listenHost )
114
+ listener , port , resolvedHost , err := suggest (listenHost )
116
115
if err != nil {
117
116
return - 1 , "" , err
118
117
}
118
+ defer listener .Close ()
119
119
if ok , err := cache .add (port ); ok {
120
120
return port , resolvedHost , nil
121
121
} else if err != nil {
0 commit comments