-
Notifications
You must be signed in to change notification settings - Fork 1
/
lvdbCli.go
119 lines (102 loc) · 2.13 KB
/
lvdbCli.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
package lvDB
import (
"container/list"
"errors"
//"github.com/golang/glog"
"net/rpc"
"sync"
)
var ErrClientBroken = errors.New("lvDB: client broken")
type Pool struct {
Url string
MaxIdle uint32
//IdleTimeout time.Time
mu sync.Mutex
idleClients list.List
}
func NewPool(url string, maxIdel uint32) *Pool {
pool := Pool{
Url: url,
MaxIdle: maxIdel,
}
pool.idleClients.Init()
return &pool
}
func (p *Pool) Get() (*Client, error) {
p.mu.Lock()
e := p.idleClients.Front()
if e != nil {
p.idleClients.Remove(e)
p.mu.Unlock()
return &Client{p, e.Value.(*rpc.Client), false}, nil
}
p.mu.Unlock()
//create new
client, err := rpc.DialHTTP("tcp", p.Url)
if err != nil {
return nil, err
}
return &Client{p, client, false}, nil
}
func (p *Pool) Put(client *Client) {
p.mu.Lock()
p.idleClients.PushBack(client.client)
if p.idleClients.Len() > int(p.MaxIdle) {
e := p.idleClients.Front()
e.Value.(*rpc.Client).Close()
p.idleClients.Remove(e)
}
p.mu.Unlock()
}
type Client struct {
pool *Pool
client *rpc.Client
broken bool
}
func (c *Client) Close() {
if c.broken {
c.client.Close()
return
}
c.pool.Put(c)
}
func (c *Client) Put(kvs ...Kv) error {
err := c.client.Call("Lvdb.Put", kvs, nil)
if err == rpc.ErrShutdown {
c.broken = true
return ErrClientBroken
}
return err
}
func (c *Client) Get(keys ...[]byte) (replys [][]byte, err error) {
err = c.client.Call("Lvdb.Get", keys, &replys)
if err == rpc.ErrShutdown {
c.broken = true
return nil, ErrClientBroken
}
return replys, err
}
func (c *Client) Del(keys ...[]byte) error {
err := c.client.Call("Lvdb.Del", keys, nil)
if err == rpc.ErrShutdown {
c.broken = true
return ErrClientBroken
}
return err
}
func (c *Client) Ping() error {
err := c.client.Call("Lvdb.Get", [][]byte{[]byte("")}, nil)
if err == rpc.ErrShutdown {
c.broken = true
return ErrClientBroken
}
return err
}
//func (c *Client) Call(serviceMethod string, args interface{}, reply interface{}) error {
// err := c.client.Call(serviceMethod, args, reply)
// if err == rpc.ErrShutdown {
// c.broken = true
// return ErrClientBroken
// }
// return err
//}