remove PeerStore registration logic, move TrackerFuncs
This commit is contained in:
parent
736026d9d3
commit
98a7c42ab3
6 changed files with 60 additions and 80 deletions
|
@ -20,8 +20,7 @@ package backend
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jzelinskie/trakr/bittorrent"
|
"github.com/jzelinskie/trakr/frontends"
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenericConfig is a block of configuration who's structure is unknown.
|
// GenericConfig is a block of configuration who's structure is unknown.
|
||||||
|
@ -30,15 +29,20 @@ type GenericConfig struct {
|
||||||
config interface{} `yaml:"config"`
|
config interface{} `yaml:"config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backend is a multi-protocol, customizable BitTorrent Tracker.
|
type BackendConfig struct {
|
||||||
type Backend struct {
|
|
||||||
AnnounceInterval time.Duration `yaml:"announce_interval"`
|
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"`
|
PreHooks []GenericConfig `yaml:"prehooks"`
|
||||||
PostHooks []GenericConfig `yaml:"posthooks"`
|
PostHooks []GenericConfig `yaml:"posthooks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
peerStore PeerStore
|
||||||
closing chan struct{}
|
closing chan struct{}
|
||||||
}
|
}
|
||||||
|
@ -53,9 +57,6 @@ func (t *Backend) Stop() {
|
||||||
// It blocks until t.Stop() is called or an error is returned.
|
// It blocks until t.Stop() is called or an error is returned.
|
||||||
func (t *Backend) Start() error {
|
func (t *Backend) Start() error {
|
||||||
t.closing = make(chan struct{})
|
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 {
|
select {
|
||||||
case <-t.closing:
|
case <-t.closing:
|
||||||
return nil
|
return nil
|
||||||
|
@ -63,27 +64,3 @@ func (t *Backend) Start() error {
|
||||||
|
|
||||||
return nil
|
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)
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package backend
|
package backend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jzelinskie/trakr/bittorrent"
|
"github.com/jzelinskie/trakr/bittorrent"
|
||||||
|
@ -63,35 +62,3 @@ type PeerStore interface {
|
||||||
// For more details see the documentation in the stopper package.
|
// For more details see the documentation in the stopper package.
|
||||||
stopper.Stopper
|
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)
|
|
||||||
}
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
type ConfigFile struct {
|
type ConfigFile struct {
|
||||||
Config struct {
|
Config struct {
|
||||||
PrometheusAddr string `yaml:"prometheus_addr"`
|
PrometheusAddr string `yaml:"prometheus_addr"`
|
||||||
backend.Backend
|
backend.BackendConfig
|
||||||
HTTPConfig httpfrontend.Config `yaml:"http"`
|
HTTPConfig httpfrontend.Config `yaml:"http"`
|
||||||
UDPConfig udpfrontend.Config `yaml:"udp"`
|
UDPConfig udpfrontend.Config `yaml:"udp"`
|
||||||
} `yaml:"trakr"`
|
} `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)
|
errChan := make(chan error)
|
||||||
closedChan := make(chan struct{})
|
closedChan := make(chan struct{})
|
||||||
|
|
||||||
go func() {
|
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())
|
errChan <- errors.New("failed to cleanly shutdown: " + err.Error())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -108,7 +114,7 @@ func main() {
|
||||||
|
|
||||||
if configFile.Config.HTTPConfig.Addr != "" {
|
if configFile.Config.HTTPConfig.Addr != "" {
|
||||||
// TODO get the real TrackerFuncs
|
// TODO get the real TrackerFuncs
|
||||||
hFrontend = httpfrontend.NewFrontend(backend.TrackerFuncs{}, configFile.Config.HTTPConfig)
|
hFrontend = httpfrontend.NewFrontend(trackerBackend.TrackerFuncs, configFile.Config.HTTPConfig)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Println("started serving HTTP on", configFile.Config.HTTPConfig.Addr)
|
log.Println("started serving HTTP on", configFile.Config.HTTPConfig.Addr)
|
||||||
|
@ -120,7 +126,7 @@ func main() {
|
||||||
|
|
||||||
if configFile.Config.UDPConfig.Addr != "" {
|
if configFile.Config.UDPConfig.Addr != "" {
|
||||||
// TODO get the real TrackerFuncs
|
// TODO get the real TrackerFuncs
|
||||||
uFrontend = udpfrontend.NewFrontend(backend.TrackerFuncs{}, configFile.Config.UDPConfig)
|
uFrontend = udpfrontend.NewFrontend(trackerBackend.TrackerFuncs, configFile.Config.UDPConfig)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Println("started serving UDP on", configFile.Config.UDPConfig.Addr)
|
log.Println("started serving UDP on", configFile.Config.UDPConfig.Addr)
|
||||||
|
@ -143,7 +149,7 @@ func main() {
|
||||||
hFrontend.Stop()
|
hFrontend.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
configFile.Config.Backend.Stop()
|
trackerBackend.Stop()
|
||||||
|
|
||||||
close(errChan)
|
close(errChan)
|
||||||
close(closedChan)
|
close(closedChan)
|
||||||
|
|
30
frontends/frontends.go
Normal file
30
frontends/frontends.go
Normal file
|
@ -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)
|
|
@ -26,7 +26,7 @@ import (
|
||||||
"github.com/tylerb/graceful"
|
"github.com/tylerb/graceful"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/jzelinskie/trakr/backend"
|
"github.com/jzelinskie/trakr/frontends"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -71,12 +71,12 @@ type Config struct {
|
||||||
type Frontend struct {
|
type Frontend struct {
|
||||||
grace *graceful.Server
|
grace *graceful.Server
|
||||||
|
|
||||||
backend.TrackerFuncs
|
frontends.TrackerFuncs
|
||||||
Config
|
Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFrontend allocates a new instance of a Frontend.
|
// 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{
|
return &Frontend{
|
||||||
TrackerFuncs: funcs,
|
TrackerFuncs: funcs,
|
||||||
Config: cfg,
|
Config: cfg,
|
||||||
|
|
|
@ -27,8 +27,8 @@ import (
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
"github.com/jzelinskie/trakr/backend"
|
|
||||||
"github.com/jzelinskie/trakr/bittorrent"
|
"github.com/jzelinskie/trakr/bittorrent"
|
||||||
|
"github.com/jzelinskie/trakr/frontends"
|
||||||
"github.com/jzelinskie/trakr/frontends/udp/bytepool"
|
"github.com/jzelinskie/trakr/frontends/udp/bytepool"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -74,12 +74,12 @@ type Frontend struct {
|
||||||
closing chan struct{}
|
closing chan struct{}
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
|
||||||
backend.TrackerFuncs
|
frontends.TrackerFuncs
|
||||||
Config
|
Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFrontend allocates a new instance of a Frontend.
|
// 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{
|
return &Frontend{
|
||||||
closing: make(chan struct{}),
|
closing: make(chan struct{}),
|
||||||
TrackerFuncs: funcs,
|
TrackerFuncs: funcs,
|
||||||
|
|
Loading…
Reference in a new issue