redis restructured to use strings of JSON

This commit is contained in:
Jimmy Zelinskie 2013-07-24 00:18:43 -04:00
parent f7906b9089
commit 2cd3473d18
3 changed files with 49 additions and 54 deletions

View file

@ -15,7 +15,7 @@ import (
"github.com/pushrax/chihaya/storage"
)
func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
func (s Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
// Parse the required parameters off of a query
compact, numWant, infohash, peerID, event, ip, port, uploaded, downloaded, left, err := s.validateAnnounceQuery(r)
if err != nil {
@ -116,7 +116,7 @@ func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
default:
// Check the user's slots to see if they're allowed to leech
if s.conf.Slots && user.Slots != -1 && left != 0 {
if user.UsedSlots >= user.Slots {
if user.SlotsUsed >= user.Slots {
fail(errors.New("You've run out of download slots."), w, r)
return
}
@ -192,7 +192,7 @@ func (s *Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
// TODO compact, response, etc...
}
func (s *Server) validateAnnounceQuery(r *http.Request) (compact bool, numWant int, infohash, peerID, event, ip string, port, uploaded, downloaded, left uint64, err error) {
func (s Server) validateAnnounceQuery(r *http.Request) (compact bool, numWant int, infohash, peerID, event, ip string, port, uploaded, downloaded, left uint64, err error) {
pq, err := parseQuery(r.URL.RawQuery)
if err != nil {
return false, 0, "", "", "", "", 0, 0, 0, 0, err

View file

@ -5,42 +5,34 @@
package storage
type Peer struct {
ID string
UserID uint64
TorrentID uint64
IP string
Port uint64
Uploaded uint64
Downloaded uint64
Left uint64
LastAnnounce int64
ID string `json:"id"`
UserID uint64 `json:"user_id"`
TorrentID uint64 `json:"torrent_id"`
IP string `json:"ip"`
Port uint64 `json:"port"`
Uploaded uint64 `json:"uploaded"`
Downloaded uint64 `json:"downloaded`
Left uint64 `json:"left"`
LastAnnounce int64 `json:"last_announce"`
}
type Torrent struct {
ID uint64
Infohash string
UpMultiplier float64
DownMultiplier float64
Seeders map[string]Peer
Leechers map[string]Peer
Snatches uint
Pruned bool
LastAction int64
ID uint64 `json:"id"`
Infohash string `json:"infohash"`
Pruned bool `json:"pruned"`
Seeders map[string]Peer `json:"seeders"`
Leechers map[string]Peer `json:"leechers"`
Snatches uint `json:"snatches"`
UpMultiplier float64 `json:"up_multiplier"`
DownMultiplier float64 `json:"down_multipler"`
LastAction int64 `json:"last_action"`
}
type User struct {
ID uint64
Passkey string
UpMultiplier float64
DownMultiplier float64
Slots int64
UsedSlots int64
SlotsLastChecked int64
ID uint64 `json:"id"`
Passkey string `json:"passkey"`
UpMultiplier float64 `json:"up_multiplier"`
DownMultiplier float64 `json:"down_multiplier"`
Slots int64 `json:"slots"`
SlotsUsed int64 `json:"slots_used"`
}

View file

@ -3,9 +3,16 @@
// which can be found in the LICENSE file.
// Package redis implements the storage interface for a BitTorrent tracker.
// The client whitelist is represented as a set with the key name "whitelist"
// with an optional prefix. Torrents and users are JSON-formatted strings.
// Torrents' keys are named "torrent_<infohash>" with an optional prefix.
// Users' keys are named "user_<passkey>" with an optional prefix.
package redis
import (
"encoding/json"
"strings"
"time"
"github.com/garyburd/redigo/redis"
@ -67,19 +74,17 @@ func (ds *DS) FindUser(passkey string) (*storage.User, bool, error) {
conn := ds.Get()
defer conn.Close()
key := ds.conf.Prefix + "User:" + passkey
reply, err := redis.Values(conn.Do("HGETALL", key))
key := ds.conf.Prefix + "user_" + passkey
reply, err := redis.String(conn.Do("GET", key))
if err != nil {
return nil, true, err
}
// If we get nothing back, the user isn't found.
if len(reply) == 0 {
return nil, false, nil
if err == redis.ErrNil {
return nil, false, nil
}
return nil, false, err
}
user := &storage.User{}
err = redis.ScanStruct(reply, user)
err = json.NewDecoder(strings.NewReader(reply)).Decode(user)
if err != nil {
return nil, true, err
}
@ -90,19 +95,17 @@ func (ds *DS) FindTorrent(infohash string) (*storage.Torrent, bool, error) {
conn := ds.Get()
defer conn.Close()
key := ds.conf.Prefix + "Torrent:" + infohash
reply, err := redis.Values(conn.Do("HGETALL", key))
key := ds.conf.Prefix + "torrent_" + infohash
reply, err := redis.String(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
return nil, false, nil
}
return nil, false, err
}
// If we get nothing back, the torrent isn't found.
if len(reply) == 0 {
return nil, false, nil
}
torrent := &storage.Torrent{}
err = redis.ScanStruct(reply, torrent)
err = json.NewDecoder(strings.NewReader(reply)).Decode(torrent)
if err != nil {
return nil, true, err
}
@ -113,8 +116,8 @@ func (ds *DS) ClientWhitelisted(peerID string) (bool, error) {
conn := ds.Get()
defer conn.Close()
key := ds.conf.Prefix + "Whitelist:" + peerID
exists, err := redis.Bool(conn.Do("EXISTS", key))
key := ds.conf.Prefix + "whitelist"
exists, err := redis.Bool(conn.Do("SISMEMBER", key, peerID))
if err != nil {
return false, err
}