-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathclient.go
130 lines (109 loc) · 2.69 KB
/
client.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package goSam
import (
"bufio"
"fmt"
"net"
"github.com/cryptix/go/debug"
)
// A Client represents a single Connection to the SAM bridge
type Client struct {
host string
port string
SamConn net.Conn
rd *bufio.Reader
inLength uint
inVariance int
inQuantity uint
inBackups uint
outLength uint
outVariance int
outQuantity uint
outBackups uint
dontPublishLease bool
encryptLease bool
reduceIdle bool
reduceIdleTime uint
reduceIdleQuantity uint
closeIdle bool
closeIdleTime uint
debug bool
}
// NewDefaultClient creates a new client, connecting to the default host:port at localhost:7656
func NewDefaultClient() (*Client, error) {
return NewClient("localhost:7656")
}
// NewClient creates a new client, connecting to a specified port
func NewClient(addr string) (*Client, error) {
return NewClientFromOptions(SetAddr(addr))
}
// NewClientFromOptions creates a new client, connecting to a specified port
func NewClientFromOptions(opts ...func(*Client) error) (*Client, error) {
var c Client
c.host = "127.0.0.1"
c.port = "7656"
c.inLength = 3
c.inVariance = 0
c.inQuantity = 4
c.inBackups = 2
c.outLength = 3
c.outVariance = 0
c.outQuantity = 4
c.outBackups = 2
c.dontPublishLease = true
c.encryptLease = false
c.reduceIdle = false
c.reduceIdleTime = 300000
c.reduceIdleQuantity = 4
c.closeIdle = true
c.closeIdleTime = 600000
c.debug = false
for _, o := range opts {
if err := o(&c); err != nil {
return nil, err
}
}
conn, err := net.Dial("tcp", c.samaddr())
if err != nil {
return nil, err
}
if c.debug {
conn = debug.WrapConn(conn)
}
c.SamConn = conn
c.rd = bufio.NewReader(conn)
return &c, c.hello()
}
//return the combined host:port of the SAM bridge
func (c *Client) samaddr() string {
return fmt.Sprintf("%s:%s", c.host, c.port)
}
// send the initial handshake command and check that the reply is ok
func (c *Client) hello() error {
r, err := c.sendCmd("HELLO VERSION MIN=3.0 MAX=3.2\n")
if err != nil {
return err
}
if r.Topic != "HELLO" {
return fmt.Errorf("Unknown Reply: %+v\n", r)
}
if r.Pairs["RESULT"] != "OK" || !(r.Pairs["VERSION"] == "3.0" || r.Pairs["VERSION"] == "3.1" || r.Pairs["VERSION"] == "3.2") {
return fmt.Errorf("Handshake did not succeed\nReply:%+v\n", r)
}
return nil
}
// helper to send one command and parse the reply by sam
func (c *Client) sendCmd(str string, args ...interface{}) (*Reply, error) {
if _, err := fmt.Fprintf(c.SamConn, str, args...); err != nil {
return nil, err
}
line, err := c.rd.ReadString('\n')
if err != nil {
return nil, err
}
return parseReply(line)
}
// Close the underlying socket to SAM
func (c *Client) Close() error {
c.rd = nil
return c.SamConn.Close()
}