diff --git a/backend/backend.go b/backend/backend.go index 2e00989..0bc4425 100644 --- a/backend/backend.go +++ b/backend/backend.go @@ -20,8 +20,7 @@ package backend import ( "time" - "github.com/jzelinskie/trakr/bittorrent" - "golang.org/x/net/context" + "github.com/jzelinskie/trakr/frontends" ) // GenericConfig is a block of configuration who's structure is unknown. @@ -30,17 +29,22 @@ type GenericConfig struct { config interface{} `yaml:"config"` } -// Backend is a multi-protocol, customizable BitTorrent Tracker. -type Backend struct { +type BackendConfig struct { AnnounceInterval time.Duration `yaml:"announce_interval"` - GCInterval time.Duration `yaml:"gc_interval"` - GCExpiration time.Duration `yaml:"gc_expiration"` - PeerStoreConfig []GenericConfig `yaml:"storage"` PreHooks []GenericConfig `yaml:"prehooks"` PostHooks []GenericConfig `yaml:"posthooks"` +} - peerStore PeerStore - closing chan struct{} +func New(config BackendConfig, peerStore PeerStore) (*Backend, error) { + // Build TrackerFuncs from the PreHooks and PostHooks + return &Backend{peerStore: peerStore}, nil +} + +// Backend is a multi-protocol, customizable BitTorrent Tracker. +type Backend struct { + TrackerFuncs frontends.TrackerFuncs + peerStore PeerStore + closing chan struct{} } // Stop provides a thread-safe way to shutdown a currently running @@ -53,9 +57,6 @@ func (t *Backend) Stop() { // It blocks until t.Stop() is called or an error is returned. func (t *Backend) Start() error { t.closing = make(chan struct{}) - // Build an TrackerFuncs from the PreHooks and PostHooks. - // Create a PeerStore instance. - // Make TrackerFuncs available to be used by frontends. select { case <-t.closing: return nil @@ -63,27 +64,3 @@ func (t *Backend) Start() error { return nil } - -// 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 -} - -// 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) diff --git a/backend/storage.go b/backend/storage.go index 541742f..7761613 100644 --- a/backend/storage.go +++ b/backend/storage.go @@ -1,7 +1,6 @@ package backend import ( - "fmt" "time" "github.com/jzelinskie/trakr/bittorrent" @@ -63,35 +62,3 @@ type PeerStore interface { // For more details see the documentation in the stopper package. stopper.Stopper } - -// PeerStoreConstructor is a function used to create a new instance of a -// PeerStore. -type PeerStoreConstructor func(interface{}) (PeerStore, error) - -var peerStores = make(map[string]PeerStoreConstructor) - -// RegisterPeerStore makes a PeerStoreConstructor available by the provided -// name. -// -// If this function is called twice with the same name or if the -// PeerStoreConstructor is nil, it panics. -func RegisterPeerStore(name string, con PeerStoreConstructor) { - if con == nil { - panic("trakr: could not register nil PeerStoreConstructor") - } - - if _, dup := peerStores[name]; dup { - panic("trakr: could not register duplicate PeerStoreConstructor: " + name) - } - - peerStores[name] = con -} - -// NewPeerStore creates an instance of the given PeerStore by name. -func NewPeerStore(name string, config interface{}) (PeerStore, error) { - con, ok := peerStores[name] - if !ok { - return nil, fmt.Errorf("trakr: unknown PeerStore %q (forgotten import?)", name) - } - return con(config) -} diff --git a/cmd/trakr/main.go b/cmd/trakr/main.go index f44d764..1478023 100644 --- a/cmd/trakr/main.go +++ b/cmd/trakr/main.go @@ -23,7 +23,7 @@ import ( type ConfigFile struct { Config struct { PrometheusAddr string `yaml:"prometheus_addr"` - backend.Backend + backend.BackendConfig HTTPConfig httpfrontend.Config `yaml:"http"` UDPConfig udpfrontend.Config `yaml:"udp"` } `yaml:"trakr"` @@ -94,11 +94,17 @@ func main() { } }() + // TODO create PeerStore + trackerBackend, err := backend.New(configFile.Config.BackendConfig, nil) + if err != nil { + return err + } + errChan := make(chan error) closedChan := make(chan struct{}) go func() { - if err := configFile.Config.Backend.Start(); err != nil { + if err := trackerBackend.Start(); err != nil { errChan <- errors.New("failed to cleanly shutdown: " + err.Error()) } }() @@ -108,7 +114,7 @@ func main() { if configFile.Config.HTTPConfig.Addr != "" { // TODO get the real TrackerFuncs - hFrontend = httpfrontend.NewFrontend(backend.TrackerFuncs{}, configFile.Config.HTTPConfig) + hFrontend = httpfrontend.NewFrontend(trackerBackend.TrackerFuncs, configFile.Config.HTTPConfig) go func() { log.Println("started serving HTTP on", configFile.Config.HTTPConfig.Addr) @@ -120,7 +126,7 @@ func main() { if configFile.Config.UDPConfig.Addr != "" { // TODO get the real TrackerFuncs - uFrontend = udpfrontend.NewFrontend(backend.TrackerFuncs{}, configFile.Config.UDPConfig) + uFrontend = udpfrontend.NewFrontend(trackerBackend.TrackerFuncs, configFile.Config.UDPConfig) go func() { log.Println("started serving UDP on", configFile.Config.UDPConfig.Addr) @@ -143,7 +149,7 @@ func main() { hFrontend.Stop() } - configFile.Config.Backend.Stop() + trackerBackend.Stop() close(errChan) close(closedChan) diff --git a/frontends/frontends.go b/frontends/frontends.go new file mode 100644 index 0000000..4004a02 --- /dev/null +++ b/frontends/frontends.go @@ -0,0 +1,30 @@ +package frontends + +import ( + "github.com/jzelinskie/trakr/bittorrent" + "golang.org/x/net/context" +) + +// 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 +} + +// 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) diff --git a/frontends/http/frontend.go b/frontends/http/frontend.go index 716da66..3702f94 100644 --- a/frontends/http/frontend.go +++ b/frontends/http/frontend.go @@ -26,7 +26,7 @@ import ( "github.com/tylerb/graceful" "golang.org/x/net/context" - "github.com/jzelinskie/trakr/backend" + "github.com/jzelinskie/trakr/frontends" ) func init() { @@ -71,12 +71,12 @@ type Config struct { type Frontend struct { grace *graceful.Server - backend.TrackerFuncs + frontends.TrackerFuncs Config } // NewFrontend allocates a new instance of a Frontend. -func NewFrontend(funcs backend.TrackerFuncs, cfg Config) *Frontend { +func NewFrontend(funcs frontends.TrackerFuncs, cfg Config) *Frontend { return &Frontend{ TrackerFuncs: funcs, Config: cfg, diff --git a/frontends/udp/frontend.go b/frontends/udp/frontend.go index 7da88f7..424b3ff 100644 --- a/frontends/udp/frontend.go +++ b/frontends/udp/frontend.go @@ -27,8 +27,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "golang.org/x/net/context" - "github.com/jzelinskie/trakr/backend" "github.com/jzelinskie/trakr/bittorrent" + "github.com/jzelinskie/trakr/frontends" "github.com/jzelinskie/trakr/frontends/udp/bytepool" ) @@ -74,12 +74,12 @@ type Frontend struct { closing chan struct{} wg sync.WaitGroup - backend.TrackerFuncs + frontends.TrackerFuncs Config } // NewFrontend allocates a new instance of a Frontend. -func NewFrontend(funcs backend.TrackerFuncs, cfg Config) *Frontend { +func NewFrontend(funcs frontends.TrackerFuncs, cfg Config) *Frontend { return &Frontend{ closing: make(chan struct{}), TrackerFuncs: funcs,