[#328] container/load: Implement route builder based on placement
Implement route Builder interface on wrapper over the container placement builder, Component implies exactly one transfer to each of the most weight nodes of the container (according to some weighing algorithm). Implementation is planned for use when transferring local estimates of storage nodes. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
d48fb81193
commit
21133aee2f
3 changed files with 99 additions and 0 deletions
|
@ -0,0 +1,49 @@
|
|||
package placementrouter
|
||||
|
||||
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 {
|
||||
// Calculator of the container members.
|
||||
//
|
||||
// Must not be nil.
|
||||
PlacementBuilder PlacementBuilder
|
||||
}
|
||||
|
||||
// Builder represents component that routes used container space
|
||||
// values between nodes from the container.
|
||||
//
|
||||
// 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 {
|
||||
placementBuilder PlacementBuilder
|
||||
}
|
||||
|
||||
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.PlacementBuilder == nil:
|
||||
panicOnPrmValue("RemoteWriterProvider", prm.PlacementBuilder)
|
||||
}
|
||||
|
||||
return &Builder{
|
||||
placementBuilder: prm.PlacementBuilder,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package placementrouter
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
||||
loadroute "github.com/nspcc-dev/neofs-node/pkg/services/container/announcement/load/route"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// NextStage composes container nodes for the container and epoch from a,
|
||||
// and returns the list of nodes with maximum weight (one from each vector).
|
||||
//
|
||||
// If passed route has more than one point, then endpoint of the route is reached.
|
||||
//
|
||||
// The traversed route is not checked, it is assumed to be correct.
|
||||
func (b *Builder) NextStage(a container.UsedSpaceAnnouncement, passed []loadroute.ServerInfo) ([]loadroute.ServerInfo, error) {
|
||||
if len(passed) > 1 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
placement, err := b.placementBuilder.BuildPlacement(a.Epoch(), a.ContainerID())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not build placement %s", a.ContainerID())
|
||||
}
|
||||
|
||||
res := make([]loadroute.ServerInfo, 0, len(placement))
|
||||
|
||||
for i := range placement {
|
||||
if len(placement[i]) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
res = append(res, placement[i][0])
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package placementrouter
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/container"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
|
||||
)
|
||||
|
||||
// PlacementBuilder describes interface of NeoFS placement calculator.
|
||||
type PlacementBuilder interface {
|
||||
// BuildPlacement must compose and sort (according to a specific algorithm)
|
||||
// storage nodes from the container with identifier cid using network map
|
||||
// of particular epoch.
|
||||
BuildPlacement(epoch uint64, cid *container.ID) ([]netmap.Nodes, error)
|
||||
}
|
Loading…
Reference in a new issue