-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
126 lines (103 loc) · 2.29 KB
/
main.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
package dicedb
import (
"fmt"
"net"
"strings"
"time"
"github.com/dicedb/dicedb-go/ironhawk"
"github.com/dicedb/dicedb-go/wire"
"github.com/google/uuid"
)
type Client struct {
id string
conn net.Conn
watchConn net.Conn
watchCh chan *wire.Response
host string
port int
}
type option func(*Client)
func newConn(host string, port int) (net.Conn, error) {
addr := fmt.Sprintf("%s:%d", host, port)
conn, err := net.DialTimeout("tcp", addr, 5*time.Second)
if err != nil {
return nil, err
}
return conn, nil
}
func WithID(id string) option {
return func(c *Client) {
c.id = id
}
}
func NewClient(host string, port int, opts ...option) (*Client, error) {
conn, err := newConn(host, port)
if err != nil {
return nil, err
}
client := &Client{conn: conn, host: host, port: port}
for _, opt := range opts {
opt(client)
}
if client.id == "" {
client.id = uuid.New().String()
}
if resp := client.Fire(&wire.Command{
Cmd: "HANDSHAKE",
Args: []string{client.id, "command"},
}); resp.Err != "" {
return nil, fmt.Errorf("could not complete the handshake: %s", resp.Err)
}
return client, nil
}
func (c *Client) fire(cmd *wire.Command, co net.Conn) *wire.Response {
if err := ironhawk.Write(co, cmd); err != nil {
return &wire.Response{
Err: err.Error(),
}
}
resp, err := ironhawk.Read(co)
if err != nil {
return &wire.Response{
Err: err.Error(),
}
}
return resp
}
func (c *Client) Fire(cmd *wire.Command) *wire.Response {
return c.fire(cmd, c.conn)
}
func (c *Client) FireString(cmdStr string) *wire.Response {
cmdStr = strings.TrimSpace(cmdStr)
tokens := strings.Split(cmdStr, " ")
var args []string
var cmd = tokens[0]
if len(tokens) > 1 {
args = tokens[1:]
}
return c.Fire(&wire.Command{
Cmd: cmd,
Args: args,
})
}
func (c *Client) WatchCh() (<-chan *wire.Response, error) {
var err error
if c.watchCh != nil {
return c.watchCh, nil
}
c.watchCh = make(chan *wire.Response)
c.watchConn, err = newConn(c.host, c.port)
if err != nil {
return nil, err
}
if resp := c.fire(&wire.Command{
Cmd: "HANDSHAKE",
Args: []string{c.id, "watch"},
}, c.watchConn); resp.Err != "" {
return nil, fmt.Errorf("could not complete the handshake: %s", resp.Err)
}
return c.watchCh, nil
}
func (c *Client) Close() {
c.conn.Close()
}