-
Notifications
You must be signed in to change notification settings - Fork 6
/
ports.go
73 lines (63 loc) · 1.28 KB
/
ports.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package ports
import (
stderror "errors"
"fmt"
"net"
"os"
"path/filepath"
"sync"
"github.com/pkg/errors"
)
const (
ReservationSize = 1000
MinPort = 0
MaxPort = 65535
)
var (
errNop = stderror.New("nop")
tempDir = os.TempDir()
)
type Lease struct {
base int
name string
release func() error
once sync.Once
}
func (r *Lease) Release() (err error) {
r.once.Do(func() {
err = r.release()
})
return err
}
func (r *Lease) Base() int {
return r.base
}
func ReserveWeakly(begin int) (*Lease, error) {
if MinPort > begin || begin > MaxPort {
return nil, errors.New("invalid port range")
}
if begin%ReservationSize != 0 {
return nil, errors.Errorf("begin should be multiple of %d", ReservationSize)
}
name := filepath.Join(tempDir, fmt.Sprintf("varlog_ports_pool_%d", begin))
ua := &net.UnixAddr{Name: name}
lis, err := net.ListenUnix("unix", ua)
if err != nil {
return nil, errors.WithStack(err)
}
lease := &Lease{
base: begin,
name: name,
release: func() error {
return errors.WithStack(lis.Close())
},
}
return lease, err
}
func ReserveWeaklyWithRetry(begin int) (lease *Lease, err error) {
err = errNop
for ; err != nil && begin < MaxPort; begin += ReservationSize {
lease, err = ReserveWeakly(begin)
}
return lease, err
}