tracker/storage/redis/redis.go
Jimmy Zelinskie 7ef424639b nickpicking
2013-06-28 16:29:02 -04:00

131 lines
2.5 KiB
Go

// Copyright 2013 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package redis
import (
"time"
"github.com/garyburd/redigo/redis"
"github.com/pushrax/chihaya/config"
"github.com/pushrax/chihaya/storage"
)
type driver struct{}
func (d *driver) New(conf *config.Storage) (storage.Conn, error) {
return &Conn{
conf: conf,
pool: &redis.Pool{
MaxIdle: 3,
IdleTimeout: 240 * time.Second,
Dial: makeDialFunc(conf),
TestOnBorrow: testOnBorrow,
},
}, nil
}
func makeDialFunc(conf *config.Storage) func() (redis.Conn, error) {
return func() (redis.Conn, error) {
var (
conn redis.Conn
err error
)
if conf.ConnectTimeout != nil &&
conf.ReadTimeout != nil &&
conf.WriteTimeout != nil {
conn, err = redis.DialTimeout(
conf.Network,
conf.Addr,
conf.ConnectTimeout.Duration,
conf.ReadTimeout.Duration,
conf.WriteTimeout.Duration,
)
} else {
conn, err = redis.Dial(conf.Network, conf.Addr)
}
if err != nil {
return nil, err
}
return conn, nil
}
}
func testOnBorrow(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
}
type Conn struct {
conf *config.Storage
pool *redis.Pool
}
func (c *Conn) Close() error {
return c.pool.Close()
}
func (c *Conn) FindUser(passkey string) (*storage.User, bool, error) {
conn := c.pool.Get()
defer c.pool.Close()
key := c.conf.Prefix + "User:" + passkey
exists, err := redis.Bool(conn.Do("EXISTS", key))
if err != nil {
return nil, false, err
}
if !exists {
return nil, false, nil
}
reply, err := redis.Values(conn.Do("HGETALL", key))
if err != nil {
return nil, true, err
}
user := &storage.User{}
err = redis.ScanStruct(reply, user)
if err != nil {
return nil, true, err
}
return user, true, nil
}
func (c *Conn) FindTorrent(infohash string) (*storage.Torrent, bool, error) {
conn := c.pool.Get()
defer c.pool.Close()
key := c.conf.Prefix + "Torrent:" + infohash
exists, err := redis.Bool(conn.Do("EXISTS", key))
if err != nil {
return nil, false, err
}
if !exists {
return nil, false, nil
}
reply, err := redis.Values(conn.Do("HGETALL", key))
if err != nil {
return nil, true, err
}
torrent := &storage.Torrent{}
err = redis.ScanStruct(reply, torrent)
if err != nil {
return nil, true, err
}
return torrent, true, nil
}
func (c *Conn) UnpruneTorrent(torrent *storage.Torrent) error {
// TODO
return nil
}
func init() {
storage.Register("redis", &driver{})
}