(tested) split storage to data and peer interfaces,

add option for persisting (or not) torrent approval data
This commit is contained in:
Lawrence, Rendall
2022-04-16 18:50:19 +03:00
parent 965df2a9c3
commit 01064fd21a
21 changed files with 219 additions and 191 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ type hook struct {
unapproved map[ClientID]struct{}
}
func build(options conf.MapConfig, _ storage.Storage) (middleware.Hook, error) {
func build(options conf.MapConfig, _ storage.PeerStorage) (middleware.Hook, error) {
var cfg Config
if err := options.Unmarshal(&cfg); err != nil {
+2 -2
View File
@@ -27,7 +27,7 @@ type skipSwarmInteraction struct{}
var SkipSwarmInteractionKey = skipSwarmInteraction{}
type swarmInteractionHook struct {
store storage.Storage
store storage.PeerStorage
}
func (h *swarmInteractionHook) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest, _ *bittorrent.AnnounceResponse) (_ context.Context, err error) {
@@ -87,7 +87,7 @@ var SkipResponseHookKey = skipResponseHook{}
// var ScrapeIsIPv6Key = scrapeAddressType{}
type responseHook struct {
store storage.Storage
store storage.PeerStorage
}
func (h *responseHook) HandleAnnounce(ctx context.Context, req *bittorrent.AnnounceRequest, resp *bittorrent.AnnounceResponse) (_ context.Context, err error) {
+1 -1
View File
@@ -70,7 +70,7 @@ type hook struct {
closing chan struct{}
}
func build(options conf.MapConfig, _ storage.Storage) (middleware.Hook, error) {
func build(options conf.MapConfig, _ storage.PeerStorage) (middleware.Hook, error) {
var cfg Config
if err := options.Unmarshal(&cfg); err != nil {
+1 -1
View File
@@ -15,7 +15,7 @@ var _ frontend.TrackerLogic = &Logic{}
// NewLogic creates a new instance of a TrackerLogic that executes the provided
// middleware hooks.
func NewLogic(annInterval, minAnnInterval time.Duration, peerStore storage.Storage, preHooks, postHooks []Hook) *Logic {
func NewLogic(annInterval, minAnnInterval time.Duration, peerStore storage.PeerStorage, preHooks, postHooks []Hook) *Logic {
return &Logic{
announceInterval: annInterval,
minAnnounceInterval: minAnnInterval,
+3 -3
View File
@@ -23,7 +23,7 @@ var (
//
// The `options` parameter is map of parameters that should be unmarshalled into
// the hook's custom configuration.
type Builder func(options conf.MapConfig, storage storage.Storage) (Hook, error)
type Builder func(options conf.MapConfig, storage storage.PeerStorage) (Hook, error)
// RegisterBuilder makes a Builder available by the provided name.
//
@@ -51,7 +51,7 @@ func RegisterBuilder(name string, d Builder) {
// list of registered Builders.
//
// If a driver does not exist, returns ErrBuilderDoesNotExist.
func New(name string, options conf.MapConfig, storage storage.Storage) (Hook, error) {
func New(name string, options conf.MapConfig, storage storage.PeerStorage) (Hook, error) {
driversM.RLock()
defer driversM.RUnlock()
@@ -72,7 +72,7 @@ type Config struct {
// HooksFromHookConfigs is a utility function for initializing Hooks in bulk.
// each element of configs must contain pairs `name` - string and `options` - map[string]any
func HooksFromHookConfigs(configs []conf.MapConfig, storage storage.Storage) (hooks []Hook, err error) {
func HooksFromHookConfigs(configs []conf.MapConfig, storage storage.PeerStorage) (hooks []Hook, err error) {
for _, cfg := range configs {
var c Config
@@ -15,7 +15,7 @@ import (
const DefaultStorageCtxName = "MW_APPROVAL"
// Builder function that creates and configures specific container
type Builder func(conf.MapConfig, storage.Storage) (Container, error)
type Builder func(conf.MapConfig, storage.DataStorage) (Container, error)
var (
buildersMU sync.Mutex
@@ -45,7 +45,7 @@ type Container interface {
}
// GetContainer creates Container by its name and provided confBytes
func GetContainer(name string, config conf.MapConfig, storage storage.Storage) (Container, error) {
func GetContainer(name string, config conf.MapConfig, storage storage.DataStorage) (Container, error) {
buildersMU.Lock()
defer buildersMU.Unlock()
var err error
@@ -35,7 +35,7 @@ type Config struct {
Path string
}
func build(conf conf.MapConfig, st storage.Storage) (container.Container, error) {
func build(conf conf.MapConfig, st storage.DataStorage) (container.Container, error) {
c := new(Config)
if err := conf.Unmarshal(c); err != nil {
return nil, fmt.Errorf("unable to deserialise configuration: %w", err)
@@ -84,7 +84,7 @@ func build(conf conf.MapConfig, st storage.Storage) (container.Container, error)
if len(name) == 0 {
name = list.DUMMY
}
if err := d.Storage.BulkPut(d.StorageCtx,
if err := d.Storage.Put(d.StorageCtx,
storage.Entry{
Key: event.InfoHash.AsString(),
Value: name,
@@ -33,7 +33,7 @@ type Config struct {
// DUMMY used as value placeholder if storage needs some value with
const DUMMY = "_"
func build(conf conf.MapConfig, st storage.Storage) (container.Container, error) {
func build(conf conf.MapConfig, st storage.DataStorage) (container.Container, error) {
c := new(Config)
if err := conf.Unmarshal(c); err != nil {
return nil, fmt.Errorf("unable to deserialise configuration: %w", err)
@@ -61,7 +61,7 @@ func build(conf conf.MapConfig, st storage.Storage) (container.Container, error)
init = append(init, storage.Entry{Key: ih.TruncateV1().RawString(), Value: DUMMY})
}
}
if err := l.Storage.BulkPut(l.StorageCtx, init...); err != nil {
if err := l.Storage.Put(l.StorageCtx, init...); err != nil {
return nil, fmt.Errorf("unable to put initial data: %w", err)
}
}
@@ -73,7 +73,7 @@ type List struct {
// Invert see Config.Invert description.
Invert bool
// Storage implementation where hashes are stored for approval checks.
Storage storage.Storage
Storage storage.DataStorage
// StorageCtx see Config.StorageCtx description.
StorageCtx string
}
+11 -2
View File
@@ -10,6 +10,7 @@ import (
"github.com/sot-tech/mochi/middleware"
"github.com/sot-tech/mochi/middleware/torrentapproval/container"
"github.com/sot-tech/mochi/pkg/conf"
"github.com/sot-tech/mochi/storage/memory"
// import directory watcher to enable appropriate support
_ "github.com/sot-tech/mochi/middleware/torrentapproval/container/directory"
@@ -30,11 +31,14 @@ func init() {
type baseConfig struct {
// Source - name of container for initial values
Source string `cfg:"initial_source"`
// Preserve - if true, container will receive real registered storage if it is NOT `memory`
// if false - temporary in-memory storage will be used or created
Preserve bool
// Configuration depends on used container
Configuration conf.MapConfig
}
func build(options conf.MapConfig, storage storage.Storage) (h middleware.Hook, err error) {
func build(options conf.MapConfig, st storage.PeerStorage) (h middleware.Hook, err error) {
var cfg baseConfig
if err = options.Unmarshal(&cfg); err != nil {
return nil, fmt.Errorf("middleware %s: %w", Name, err)
@@ -48,8 +52,13 @@ func build(options conf.MapConfig, storage storage.Storage) (h middleware.Hook,
return nil, fmt.Errorf("invalid options for middleware %s: options not provided", Name)
}
var ds storage.DataStorage = st
if !cfg.Preserve && ds.Preservable() {
ds = memory.NewDataStore()
}
var c container.Container
if c, err = container.GetContainer(cfg.Source, cfg.Configuration, storage); err == nil {
if c, err = container.GetContainer(cfg.Source, cfg.Configuration, ds); err == nil {
h = &hook{c}
}
return h, err
@@ -67,7 +67,7 @@ var cases = []struct {
func TestHandleAnnounce(t *testing.T) {
config := memory.Config{}.Validate()
storage, err := memory.New(config)
storage, err := memory.NewPeerStorage(config)
require.Nil(t, err)
for _, tt := range cases {
t.Run(fmt.Sprintf("testing hash %s", tt.ih), func(t *testing.T) {
+1 -1
View File
@@ -22,7 +22,7 @@ func init() {
middleware.RegisterBuilder(Name, build)
}
func build(options conf.MapConfig, _ storage.Storage) (h middleware.Hook, err error) {
func build(options conf.MapConfig, _ storage.PeerStorage) (h middleware.Hook, err error) {
var cfg Config
if err = options.Unmarshal(&cfg); err != nil {