forked from steveyen/grouter
/
target-memcached-binary.go
71 lines (61 loc) · 1.88 KB
/
target-memcached-binary.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
package grouter
import (
"log"
"strings"
"github.com/dustin/gomemcached"
"github.com/dustin/gomemcached/client"
)
type MemcachedBinaryTarget struct {
spec string
incomingChans []chan []Request
}
func (s MemcachedBinaryTarget) PickChannel(clientNum uint32, bucket string) chan []Request {
return s.incomingChans[clientNum%uint32(len(s.incomingChans))]
}
func MemcachedBinaryTargetStart(spec string, params Params,
statsChan chan Stats) Target {
spec = strings.Replace(spec, "memcached-binary:", "", 1)
s := MemcachedBinaryTarget{
spec: spec,
incomingChans: make([]chan []Request, params.TargetConcurrency),
}
for i := range s.incomingChans {
s.incomingChans[i] = make(chan []Request, params.TargetChanSize)
incomingBatched := make(chan []Request, params.TargetChanSize)
go func() {
BatchRequests(params.TargetChanSize,
s.incomingChans[i], incomingBatched, statsChan)
}()
MemcachedBinaryTargetStartIncoming(s, incomingBatched)
}
return s
}
func MemcachedBinaryTargetStartIncoming(s MemcachedBinaryTarget, incoming chan []Request) {
client, err := memcached.Connect("tcp", s.spec)
if err != nil {
log.Fatalf("error: memcached-binary connect failed: %s; err: %v", s.spec, err)
}
go func() {
for reqs := range incoming {
for _, req := range reqs {
log.Printf("sending.....: %s; err: %v", s.spec, err)
res, err := client.Send(req.Req)
log.Printf("sending.done: %s; err: %v", s.spec, err)
if err != nil {
req.Res <- &gomemcached.MCResponse{
Opcode: req.Req.Opcode,
Status: gomemcached.EINVAL,
Opaque: req.Req.Opaque,
}
log.Printf("warn: memcached-binary closing conn; saw error: %v", err)
client.Close()
client = Reconnect(s.spec, func(spec string) (interface{}, error) {
return memcached.Connect("tcp", spec)
}).(*memcached.Client)
} else {
req.Res <- res
}
}
}
}()
}