make frontend.TrackerFuncs an interface
This commit is contained in:
parent
ae18d89627
commit
9a8cdccc6c
4 changed files with 71 additions and 47 deletions
|
@ -20,7 +20,11 @@ package backend
|
|||
import (
|
||||
"time"
|
||||
|
||||
"log"
|
||||
|
||||
"github.com/jzelinskie/trakr/bittorrent"
|
||||
"github.com/jzelinskie/trakr/frontend"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// GenericConfig is a block of configuration who's structure is unknown.
|
||||
|
@ -35,6 +39,8 @@ type BackendConfig struct {
|
|||
PostHooks []GenericConfig `yaml:"posthooks"`
|
||||
}
|
||||
|
||||
var _ frontend.TrackerFuncs = &Backend{}
|
||||
|
||||
func New(config BackendConfig, peerStore PeerStore) (*Backend, error) {
|
||||
// Build TrackerFuncs from the PreHooks and PostHooks
|
||||
return &Backend{peerStore: peerStore}, nil
|
||||
|
@ -42,6 +48,36 @@ func New(config BackendConfig, peerStore PeerStore) (*Backend, error) {
|
|||
|
||||
// Backend is a multi-protocol, customizable BitTorrent Tracker.
|
||||
type Backend struct {
|
||||
TrackerFuncs frontend.TrackerFuncs
|
||||
peerStore PeerStore
|
||||
peerStore PeerStore
|
||||
handleAnnounce func(context.Context, *bittorrent.AnnounceRequest) (*bittorrent.AnnounceResponse, error)
|
||||
afterAnnounce func(context.Context, *bittorrent.AnnounceRequest, *bittorrent.AnnounceResponse) error
|
||||
handleScrape func(context.Context, *bittorrent.ScrapeRequest) (*bittorrent.ScrapeResponse, error)
|
||||
afterScrape func(context.Context, *bittorrent.ScrapeRequest, *bittorrent.ScrapeResponse) error
|
||||
}
|
||||
|
||||
// HandleAnnounce generates a response for an Announce.
|
||||
func (b *Backend) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest) (*bittorrent.AnnounceResponse, error) {
|
||||
return b.handleAnnounce(ctx, req)
|
||||
}
|
||||
|
||||
// AfterAnnounce does something with the results of an Announce after it
|
||||
// has been completed.
|
||||
func (b *Backend) AfterAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest, resp *bittorrent.AnnounceResponse) {
|
||||
err := b.afterAnnounce(ctx, req, resp)
|
||||
if err != nil {
|
||||
log.Println("trakr: post-announce hooks failed:", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// HandleScrape generates a response for a Scrape.
|
||||
func (b *Backend) HandleScrape(ctx context.Context, req *bittorrent.ScrapeRequest) (*bittorrent.ScrapeResponse, error) {
|
||||
return b.handleScrape(ctx, req)
|
||||
}
|
||||
|
||||
// AfterScrape does something with the results of a Scrape after it has been completed.
|
||||
func (b *Backend) AfterScrape(ctx context.Context, req *bittorrent.ScrapeRequest, resp *bittorrent.ScrapeResponse) {
|
||||
err := b.afterScrape(ctx, req, resp)
|
||||
if err != nil {
|
||||
log.Println("trakr: post-scrape hooks failed:", err.Error())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,25 @@
|
|||
package frontend
|
||||
|
||||
import (
|
||||
"github.com/jzelinskie/trakr/bittorrent"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/jzelinskie/trakr/bittorrent"
|
||||
)
|
||||
|
||||
// TrackerFuncs is the collection of callback functions provided by the Backend
|
||||
// to (1) generate a response from a parsed request, and (2) observe anything
|
||||
// after the response has been delivered to the client.
|
||||
type TrackerFuncs struct {
|
||||
HandleAnnounce AnnounceHandler
|
||||
HandleScrape ScrapeHandler
|
||||
AfterAnnounce AnnounceCallback
|
||||
AfterScrape ScrapeCallback
|
||||
type TrackerFuncs interface {
|
||||
// HandleAnnounce generates a response for an Announce.
|
||||
HandleAnnounce(context.Context, *bittorrent.AnnounceRequest) (*bittorrent.AnnounceResponse, error)
|
||||
|
||||
// AfterAnnounce does something with the results of an Announce after it
|
||||
// has been completed.
|
||||
AfterAnnounce(context.Context, *bittorrent.AnnounceRequest, *bittorrent.AnnounceResponse)
|
||||
|
||||
// HandleScrape generates a response for a Scrape.
|
||||
HandleScrape(context.Context, *bittorrent.ScrapeRequest) (*bittorrent.ScrapeResponse, error)
|
||||
|
||||
// AfterScrape does something with the results of a Scrape after it has been completed.
|
||||
AfterScrape(context.Context, *bittorrent.ScrapeRequest, *bittorrent.ScrapeResponse)
|
||||
}
|
||||
|
||||
// AnnounceHandler is a function that generates a response for an Announce.
|
||||
type AnnounceHandler func(context.Context, *bittorrent.AnnounceRequest) (*bittorrent.AnnounceResponse, error)
|
||||
|
||||
// AnnounceCallback is a function that does something with the results of an
|
||||
// Announce after it has been completed.
|
||||
type AnnounceCallback func(*bittorrent.AnnounceRequest, *bittorrent.AnnounceResponse)
|
||||
|
||||
// ScrapeHandler is a function that generates a response for a Scrape.
|
||||
type ScrapeHandler func(context.Context, *bittorrent.ScrapeRequest) (*bittorrent.ScrapeResponse, error)
|
||||
|
||||
// ScrapeCallback is a function that does something with the results of a
|
||||
// Scrape after it has been completed.
|
||||
type ScrapeCallback func(*bittorrent.ScrapeRequest, *bittorrent.ScrapeResponse)
|
||||
|
|
|
@ -71,15 +71,15 @@ type Config struct {
|
|||
type Frontend struct {
|
||||
grace *graceful.Server
|
||||
|
||||
frontend.TrackerFuncs
|
||||
backend frontend.TrackerFuncs
|
||||
Config
|
||||
}
|
||||
|
||||
// NewFrontend allocates a new instance of a Frontend.
|
||||
func NewFrontend(funcs frontend.TrackerFuncs, cfg Config) *Frontend {
|
||||
func NewFrontend(backend frontend.TrackerFuncs, cfg Config) *Frontend {
|
||||
return &Frontend{
|
||||
TrackerFuncs: funcs,
|
||||
Config: cfg,
|
||||
backend: backend,
|
||||
Config: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ func (t *Frontend) announceRoute(w http.ResponseWriter, r *http.Request, _ httpr
|
|||
return
|
||||
}
|
||||
|
||||
resp, err := t.HandleAnnounce(context.TODO(), req)
|
||||
resp, err := t.backend.HandleAnnounce(context.TODO(), req)
|
||||
if err != nil {
|
||||
WriteError(w, err)
|
||||
return
|
||||
|
@ -162,9 +162,7 @@ func (t *Frontend) announceRoute(w http.ResponseWriter, r *http.Request, _ httpr
|
|||
return
|
||||
}
|
||||
|
||||
if t.AfterAnnounce != nil {
|
||||
go t.AfterAnnounce(req, resp)
|
||||
}
|
||||
go t.backend.AfterAnnounce(context.TODO(), req, resp)
|
||||
}
|
||||
|
||||
// scrapeRoute parses and responds to a Scrape by using t.TrackerFuncs.
|
||||
|
@ -179,7 +177,7 @@ func (t *Frontend) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprou
|
|||
return
|
||||
}
|
||||
|
||||
resp, err := t.HandleScrape(context.TODO(), req)
|
||||
resp, err := t.backend.HandleScrape(context.TODO(), req)
|
||||
if err != nil {
|
||||
WriteError(w, err)
|
||||
return
|
||||
|
@ -191,7 +189,5 @@ func (t *Frontend) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprou
|
|||
return
|
||||
}
|
||||
|
||||
if t.AfterScrape != nil {
|
||||
go t.AfterScrape(req, resp)
|
||||
}
|
||||
go t.backend.AfterScrape(context.TODO(), req, resp)
|
||||
}
|
||||
|
|
|
@ -74,16 +74,16 @@ type Frontend struct {
|
|||
closing chan struct{}
|
||||
wg sync.WaitGroup
|
||||
|
||||
frontend.TrackerFuncs
|
||||
backend frontend.TrackerFuncs
|
||||
Config
|
||||
}
|
||||
|
||||
// NewFrontend allocates a new instance of a Frontend.
|
||||
func NewFrontend(funcs frontend.TrackerFuncs, cfg Config) *Frontend {
|
||||
func NewFrontend(backend frontend.TrackerFuncs, cfg Config) *Frontend {
|
||||
return &Frontend{
|
||||
closing: make(chan struct{}),
|
||||
TrackerFuncs: funcs,
|
||||
Config: cfg,
|
||||
closing: make(chan struct{}),
|
||||
backend: backend,
|
||||
Config: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,7 +221,7 @@ func (t *Frontend) handleRequest(r Request, w ResponseWriter) (response []byte,
|
|||
}
|
||||
|
||||
var resp *bittorrent.AnnounceResponse
|
||||
resp, err = t.HandleAnnounce(context.TODO(), req)
|
||||
resp, err = t.backend.HandleAnnounce(context.TODO(), req)
|
||||
if err != nil {
|
||||
WriteError(w, txID, err)
|
||||
return
|
||||
|
@ -229,9 +229,8 @@ func (t *Frontend) handleRequest(r Request, w ResponseWriter) (response []byte,
|
|||
|
||||
WriteAnnounce(w, txID, resp)
|
||||
|
||||
if t.AfterAnnounce != nil {
|
||||
go t.AfterAnnounce(req, resp)
|
||||
}
|
||||
// TODO(mrd0ll4r): evaluate if it's worth spawning another goroutine.
|
||||
go t.backend.AfterAnnounce(context.TODO(), req, resp)
|
||||
|
||||
return
|
||||
|
||||
|
@ -246,7 +245,7 @@ func (t *Frontend) handleRequest(r Request, w ResponseWriter) (response []byte,
|
|||
}
|
||||
|
||||
var resp *bittorrent.ScrapeResponse
|
||||
resp, err = t.HandleScrape(context.TODO(), req)
|
||||
resp, err = t.backend.HandleScrape(context.TODO(), req)
|
||||
if err != nil {
|
||||
WriteError(w, txID, err)
|
||||
return
|
||||
|
@ -254,9 +253,7 @@ func (t *Frontend) handleRequest(r Request, w ResponseWriter) (response []byte,
|
|||
|
||||
WriteScrape(w, txID, resp)
|
||||
|
||||
if t.AfterScrape != nil {
|
||||
go t.AfterScrape(req, resp)
|
||||
}
|
||||
go t.backend.AfterScrape(context.TODO(), req, resp)
|
||||
|
||||
return
|
||||
|
||||
|
|
Loading…
Reference in a new issue