[#460] reputation/local: Declare Managers

Declare interfaces for building list of
managers of certain peer in certain epoch.
Implement `Builder` struct that aggregates
fields that are necessary for building
list of managers.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2021-04-03 09:11:12 +03:00 committed by Leonard Lyubich
parent 91825a0162
commit 5970a5e6ae
5 changed files with 103 additions and 3 deletions

View file

@ -65,11 +65,13 @@ func (r *Router) InitWriter(ctx reputationcontroller.Context) (reputationcontrol
}, nil }, nil
} }
func (w *trustWriter) Write(a reputation.Trust) error { func (w *trustWriter) Write(t reputation.Trust) error {
w.routeMtx.Lock() w.routeMtx.Lock()
defer w.routeMtx.Unlock() defer w.routeMtx.Unlock()
route, err := w.router.routeBuilder.NextStage(w.ctx.Epoch(), w.ctx.passedRoute) localPeerID := reputation.PeerIDFromBytes(w.router.localSrvInfo.PublicKey())
route, err := w.router.routeBuilder.NextStage(w.ctx.Epoch(), localPeerID, w.ctx.passedRoute)
if err != nil { if err != nil {
return err return err
} else if len(route) == 0 { } else if len(route) == 0 {
@ -106,7 +108,7 @@ func (w *trustWriter) Write(a reputation.Trust) error {
w.mServers[endpoint] = remoteWriter w.mServers[endpoint] = remoteWriter
} }
err := remoteWriter.Write(a) err := remoteWriter.Write(t)
if err != nil { if err != nil {
w.router.log.Debug("could not write the value", w.router.log.Debug("could not write the value",
zap.String("error", err.Error()), zap.String("error", err.Error()),

View file

@ -1,6 +1,7 @@
package reputationroute package reputationroute
import ( import (
"github.com/nspcc-dev/neofs-node/pkg/services/reputation"
reputationcontroller "github.com/nspcc-dev/neofs-node/pkg/services/reputation/local/controller" reputationcontroller "github.com/nspcc-dev/neofs-node/pkg/services/reputation/local/controller"
) )
@ -18,6 +19,18 @@ type ServerInfo interface {
Address() string Address() string
} }
// Builder groups methods to route values in the network.
type Builder interface {
// NextStage must return next group of route points
// for passed epoch and PeerID of the current route point.
// Implementation must take into account already passed route points.
//
// Empty passed list means being at the starting point of the route.
//
// Must return empty list and no error if the endpoint of the route is reached.
NextStage(epoch uint64, p reputation.PeerID, passed []ServerInfo) ([]ServerInfo, error)
}
// RemoteWriterProvider describes the component // RemoteWriterProvider describes the component
// for sending values to a fixed route point. // for sending values to a fixed route point.
type RemoteWriterProvider interface { type RemoteWriterProvider interface {

View file

@ -0,0 +1,48 @@
package managers
import "fmt"
// Prm groups the required parameters of the Builder's constructor.
//
// All values must comply with the requirements imposed on them.
// Passing incorrect parameter values will result in constructor
// failure (error or panic depending on the implementation).
type Prm struct {
// Manager builder for current node.
//
// Must not be nil.
ManagerBuilder ManagerBuilder
}
// Builder represents component that routes node to its managers.
//
// For correct operation, Builder must be created using
// the constructor (New) based on the required parameters
// and optional components. After successful creation,
// the Builder is immediately ready to work through API.
type Builder struct {
managerBuilder ManagerBuilder
}
const invalidPrmValFmt = "invalid parameter %s (%T):%v"
func panicOnPrmValue(n string, v interface{}) {
panic(fmt.Sprintf(invalidPrmValFmt, n, v, v))
}
// New creates a new instance of the Builder.
//
// Panics if at least one value of the parameters is invalid.
//
// The created Builder does not require additional
// initialization and is completely ready for work.
func New(prm Prm) *Builder {
switch {
case prm.ManagerBuilder == nil:
panicOnPrmValue("ManagerBuilder", prm.ManagerBuilder)
}
return &Builder{
managerBuilder: prm.ManagerBuilder,
}
}

View file

@ -0,0 +1,23 @@
package managers
import (
"github.com/nspcc-dev/neofs-node/pkg/services/reputation"
reputationroute "github.com/nspcc-dev/neofs-node/pkg/services/reputation/local/route"
"github.com/pkg/errors"
)
// NextStage builds Manager list for node and returns it directly.
//
// If passed route has more than one point, then endpoint of the route is reached.
func (b *Builder) NextStage(epoch uint64, p reputation.PeerID, passed []reputationroute.ServerInfo) ([]reputationroute.ServerInfo, error) {
if len(passed) > 1 {
return nil, nil
}
route, err := b.managerBuilder.BuildManagers(epoch, p)
if err != nil {
return nil, errors.Wrapf(err, "could not build managers for epoch: %d", epoch)
}
return route, nil
}

View file

@ -0,0 +1,14 @@
package managers
import (
"github.com/nspcc-dev/neofs-node/pkg/services/reputation"
reputationroute "github.com/nspcc-dev/neofs-node/pkg/services/reputation/local/route"
)
// ManagerBuilder defines an interface for providing a list
// of Managers for specific epoch. Implementation depends on trust value.
type ManagerBuilder interface {
// BuildManagers must compose list of managers. It depends on
// particular epoch and PeerID of the current route point.
BuildManagers(epoch uint64, p reputation.PeerID) ([]reputationroute.ServerInfo, error)
}