Skip to content

Commit

Permalink
remove Conn: in theory simpler, but looks more complicated..
Browse files Browse the repository at this point in the history
  • Loading branch information
igrigorik committed May 29, 2011
1 parent bae813b commit bcebe59
Showing 1 changed file with 61 additions and 66 deletions.
127 changes: 61 additions & 66 deletions turk.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,74 @@ import (
"github.com/kklis/gomemcache"
)

var (
host = flag.String("host", "localhost:8080", "listening port and hostname that will appear in the urls")
help = flag.Bool("h", false, "show this help")
pool *Pool
)

type Robot struct {
Resp string
Code int
}

type Pool struct {
newFn func() (Conn, os.Error)
conns chan Conn
newFn func() (*memcache.Memcache, os.Error)
conns chan *memcache.Memcache
}

type pooledConnection struct {
Conn
conn *memcache.Memcache
pool *Pool
}

type Conn struct {
conn *memcache.Memcache
func NewPool(newFn func() (*memcache.Memcache, os.Error), maxIdle int) *Pool {
return &Pool{newFn: newFn, conns: make(chan *memcache.Memcache, maxIdle)}
}

func NewDialPool(addr string, port int, maxIdle int) *Pool {
connect := func(addr string, port int) *memcache.Memcache {
conn, err := memcache.Connect(addr, port)
if err != nil {
log.Println("Cannot connect to memcache, error: ", err.String())
os.Exit(1)
}
return conn
}

return NewPool(func() (*memcache.Memcache, os.Error) { return connect(addr, port), nil }, maxIdle)
}

func (p *Pool) Get() (*pooledConnection, os.Error) {
var c *memcache.Memcache
select {
case c = <-p.conns:
default:
var err os.Error
c, err = p.newFn()
if err != nil {
return nil, err
}
}
return &pooledConnection{c, p}, nil
}

func (c *pooledConnection) Close() os.Error {
if c.conn == nil {
return nil
}

select {
case c.pool.conns <- c.conn:
default:
c.conn.Close()
}
c.conn = nil
return nil
}

// HTTP handler

func testAgent(path string, agent string, robots *robotstxt.RobotsData, w http.ResponseWriter) {
allow, err := robots.TestAgent(path, agent)
if (err != nil) || !allow {
Expand Down Expand Up @@ -63,10 +112,14 @@ func handler(w http.ResponseWriter, r *http.Request) {

robotsUri := "http://" + uri.Host + "/robots.txt"

cache, _ := pool.Get()
cache, err := pool.Get()
if err != nil {
error("Cannot acquire memcached connection: " + err.String())
return
}
defer cache.Close()

data, _, err := cache.Conn.conn.Get(robotsUri)
data, _, err := cache.conn.Get(robotsUri)
if data != nil {
log.Println("Found robots.txt data in cache for: ", robotsUri)
decoder := gob.NewDecoder(bytes.NewBuffer(data))
Expand Down Expand Up @@ -111,7 +164,7 @@ func handler(w http.ResponseWriter, r *http.Request) {
return
}

err = cache.Conn.conn.Set(robotsUri, []uint8(robotsGob.String()), 0, 60*60*24*30)
err = cache.conn.Set(robotsUri, []uint8(robotsGob.String()), 0, 60*60*24*30)
if err != nil {
error("Cannot store robots gob in memcached: " + err.String())
return
Expand All @@ -120,62 +173,6 @@ func handler(w http.ResponseWriter, r *http.Request) {
testAgent(uri.Path, bot[0], robots, w)
}

var (
host = flag.String("host", "localhost:8080", "listening port and hostname that will appear in the urls")
help = flag.Bool("h", false, "show this help")
pool *Pool
)

//////////////

func NewPool(newFn func() (Conn, os.Error), maxIdle int) *Pool {
return &Pool{newFn: newFn, conns: make(chan Conn, maxIdle)}
}

func NewDialPool(addr string, port int, maxIdle int) *Pool {
connect := func(addr string, port int) Conn {
cache, err := memcache.Connect(addr, port)
if err != nil {
log.Println("Cannot connect to memcache, error: ", err.String())
os.Exit(1)
}
return Conn{conn: cache}
}

return NewPool(func() (Conn, os.Error) { return connect(addr, port), nil }, maxIdle)
}

func (p *Pool) Get() (*pooledConnection, os.Error) {
var c Conn
select {
case c = <-p.conns:
default:
var err os.Error
c, err = p.newFn()
if err != nil {
return nil, err
}
}
return &pooledConnection{Conn: c, pool: p}, nil
}

func (c *pooledConnection) Close() os.Error {
if c.Conn.conn == nil {
return nil
}

select {
case c.pool.conns <- c.Conn:
default:
c.Conn.conn.Close()
}
c.Conn.conn = nil
return nil
}


///////////////

func usage() {
println("turk usage:")
flag.PrintDefaults()
Expand All @@ -189,8 +186,6 @@ func main() {
}

log.Println("Starting Turk server on " + *host)

// open a memcached connection pool
pool = NewDialPool("127.0.0.1", 11211, 10)

http.HandleFunc("/", handler)
Expand Down

0 comments on commit bcebe59

Please sign in to comment.