1package main
2
3import (
4	"flag"
5	"fmt"
6	"io"
7	"net"
8
9	"github.com/couchbase/gomemcached"
10	"github.com/couchbase/gomemcached/server"
11	"github.com/couchbase/goutils/logging"
12)
13
14var port = flag.Int("port", 11212, "Port on which to listen")
15
16type chanReq struct {
17	req *gomemcached.MCRequest
18	res chan *gomemcached.MCResponse
19}
20
21type reqHandler struct {
22	ch chan chanReq
23}
24
25func (rh *reqHandler) HandleMessage(w io.Writer, req *gomemcached.MCRequest) *gomemcached.MCResponse {
26	cr := chanReq{
27		req,
28		make(chan *gomemcached.MCResponse),
29	}
30
31	rh.ch <- cr
32	return <-cr.res
33}
34
35func connectionHandler(s net.Conn, h memcached.RequestHandler) {
36	// Explicitly ignoring errors since they all result in the
37	// client getting hung up on and many are common.
38	_ = memcached.HandleIO(s, h)
39}
40
41func waitForConnections(ls net.Listener) {
42	reqChannel := make(chan chanReq)
43
44	go RunServer(reqChannel)
45	handler := &reqHandler{reqChannel}
46
47	logging.Infof("Listening on port %d", *port)
48	for {
49		s, e := ls.Accept()
50		if e == nil {
51			logging.Infof("Got a connection from %v", s.RemoteAddr())
52			go connectionHandler(s, handler)
53		} else {
54			logging.Errorf("Error accepting from %s", ls)
55		}
56	}
57}
58
59func main() {
60	flag.Parse()
61	ls, e := net.Listen("tcp", fmt.Sprintf(":%d", *port))
62	if e != nil {
63		logging.Severef("Got an error:  %s", e)
64	}
65
66	waitForConnections(ls)
67}
68