forked from TrueCloudLab/frostfs-node
[#607] object/search: Make client constructor to work with group address
Make Object Search service to work with `AddressGroup` instead of `Address` in order to support multiple addresses of the storage node. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
ad14df07f6
commit
d0e48c949b
9 changed files with 54 additions and 28 deletions
|
@ -286,7 +286,7 @@ func initObjectService(c *cfg) {
|
||||||
sSearch := searchsvc.New(
|
sSearch := searchsvc.New(
|
||||||
searchsvc.WithLogger(c.log),
|
searchsvc.WithLogger(c.log),
|
||||||
searchsvc.WithLocalStorageEngine(ls),
|
searchsvc.WithLocalStorageEngine(ls),
|
||||||
searchsvc.WithClientConstructor(coreConstructor),
|
searchsvc.WithClientConstructor(groupConstructor),
|
||||||
searchsvc.WithTraverserGenerator(
|
searchsvc.WithTraverserGenerator(
|
||||||
traverseGen.WithTraverseOptions(
|
traverseGen.WithTraverseOptions(
|
||||||
placement.WithoutSuccessTracking(),
|
placement.WithoutSuccessTracking(),
|
||||||
|
|
|
@ -3,6 +3,7 @@ package searchsvc
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-node/pkg/network"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ func (exec *execCtx) processCurrentEpoch() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: consider parallel execution
|
// TODO: consider parallel execution
|
||||||
exec.processNode(ctx, addrs[i])
|
exec.processNode(ctx, network.GroupFromAddress(addrs[i]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,16 +117,14 @@ func (exec *execCtx) generateTraverser(cid *cid.ID) (*placement.Traverser, bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (exec execCtx) remoteClient(node network.Address) (searchClient, bool) {
|
func (exec execCtx) remoteClient(node network.AddressGroup) (searchClient, bool) {
|
||||||
log := exec.log.With(zap.Stringer("node", node))
|
|
||||||
|
|
||||||
c, err := exec.svc.clientConstructor.get(node)
|
c, err := exec.svc.clientConstructor.get(node)
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
exec.status = statusUndefined
|
exec.status = statusUndefined
|
||||||
exec.err = err
|
exec.err = err
|
||||||
|
|
||||||
log.Debug("could not construct remote node client")
|
exec.log.Debug("could not construct remote node client")
|
||||||
case err == nil:
|
case err == nil:
|
||||||
return c, true
|
return c, true
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ type IDListWriter interface {
|
||||||
|
|
||||||
// RequestForwarder is a callback for forwarding of the
|
// RequestForwarder is a callback for forwarding of the
|
||||||
// original Search requests.
|
// original Search requests.
|
||||||
type RequestForwarder func(network.Address, coreclient.Client) ([]*objectSDK.ID, error)
|
type RequestForwarder func(network.AddressGroup, coreclient.Client) ([]*objectSDK.ID, error)
|
||||||
|
|
||||||
// SetCommonParameters sets common parameters of the operation.
|
// SetCommonParameters sets common parameters of the operation.
|
||||||
func (p *Prm) SetCommonParameters(common *util.CommonPrm) {
|
func (p *Prm) SetCommonParameters(common *util.CommonPrm) {
|
||||||
|
|
|
@ -7,10 +7,8 @@ import (
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (exec *execCtx) processNode(ctx context.Context, addr network.Address) {
|
func (exec *execCtx) processNode(ctx context.Context, addr network.AddressGroup) {
|
||||||
log := exec.log.With(zap.Stringer("remote node", addr))
|
exec.log.Debug("processing node...")
|
||||||
|
|
||||||
log.Debug("processing node...")
|
|
||||||
|
|
||||||
client, ok := exec.remoteClient(addr)
|
client, ok := exec.remoteClient(addr)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -84,8 +84,8 @@ func (p *testPlacementBuilder) BuildPlacement(addr *objectSDK.Address, _ *netmap
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testClientCache) get(mAddr network.Address) (searchClient, error) {
|
func (c *testClientCache) get(mAddr network.AddressGroup) (searchClient, error) {
|
||||||
v, ok := c.clients[mAddr.HostAddr()]
|
v, ok := c.clients[network.StringifyGroup(mAddr)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("could not construct client")
|
return nil, errors.New("could not construct client")
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ func (s *testStorage) search(exec *execCtx) ([]*objectSDK.ID, error) {
|
||||||
return v.ids, v.err
|
return v.ids, v.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *testStorage) searchObjects(exec *execCtx, _ network.Address) ([]*objectSDK.ID, error) {
|
func (c *testStorage) searchObjects(exec *execCtx, _ network.AddressGroup) ([]*objectSDK.ID, error) {
|
||||||
v, ok := c.items[exec.containerID().String()]
|
v, ok := c.items[exec.containerID().String()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -200,16 +200,16 @@ func testNodeMatrix(t testing.TB, dim []int) ([]netmap.Nodes, [][]string) {
|
||||||
strconv.Itoa(60000+j),
|
strconv.Itoa(60000+j),
|
||||||
)
|
)
|
||||||
|
|
||||||
var na network.Address
|
|
||||||
|
|
||||||
err := na.FromString(a)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
as[j] = na.HostAddr()
|
|
||||||
|
|
||||||
ni := netmap.NewNodeInfo()
|
ni := netmap.NewNodeInfo()
|
||||||
ni.SetAddress(a)
|
ni.SetAddress(a)
|
||||||
|
|
||||||
|
var na network.AddressGroup
|
||||||
|
|
||||||
|
err := na.FromIterator(ni)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
as[j] = network.StringifyGroup(na)
|
||||||
|
|
||||||
ns[j] = *ni
|
ns[j] = *ni
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,11 @@ type Service struct {
|
||||||
type Option func(*cfg)
|
type Option func(*cfg)
|
||||||
|
|
||||||
type searchClient interface {
|
type searchClient interface {
|
||||||
searchObjects(*execCtx, network.Address) ([]*object.ID, error)
|
searchObjects(*execCtx, network.AddressGroup) ([]*object.ID, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClientConstructor interface {
|
type ClientConstructor interface {
|
||||||
Get(network.Address) (client.Client, error)
|
Get(network.AddressGroup) (client.Client, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type cfg struct {
|
type cfg struct {
|
||||||
|
@ -38,7 +38,7 @@ type cfg struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
clientConstructor interface {
|
clientConstructor interface {
|
||||||
get(network.Address) (searchClient, error)
|
get(network.AddressGroup) (searchClient, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
traverserGenerator interface {
|
traverserGenerator interface {
|
||||||
|
|
|
@ -68,7 +68,7 @@ func (w *uniqueIDWriter) WriteIDs(list []*objectSDK.ID) error {
|
||||||
return w.writer.WriteIDs(list)
|
return w.writer.WriteIDs(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *clientConstructorWrapper) get(addr network.Address) (searchClient, error) {
|
func (c *clientConstructorWrapper) get(addr network.AddressGroup) (searchClient, error) {
|
||||||
clt, err := c.constructor.Get(addr)
|
clt, err := c.constructor.Get(addr)
|
||||||
|
|
||||||
return &clientWrapper{
|
return &clientWrapper{
|
||||||
|
@ -76,7 +76,7 @@ func (c *clientConstructorWrapper) get(addr network.Address) (searchClient, erro
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *clientWrapper) searchObjects(exec *execCtx, addr network.Address) ([]*objectSDK.ID, error) {
|
func (c *clientWrapper) searchObjects(exec *execCtx, addr network.AddressGroup) ([]*objectSDK.ID, error) {
|
||||||
if exec.prm.forwarder != nil {
|
if exec.prm.forwarder != nil {
|
||||||
return exec.prm.forwarder(addr, c.client)
|
return exec.prm.forwarder(addr, c.client)
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ func (s *Service) toPrm(req *objectV2.SearchRequest, stream objectSvc.SearchStre
|
||||||
if !commonPrm.LocalOnly() {
|
if !commonPrm.LocalOnly() {
|
||||||
var onceResign sync.Once
|
var onceResign sync.Once
|
||||||
|
|
||||||
p.SetRequestForwarder(func(addr network.Address, c client.Client) ([]*objectSDK.ID, error) {
|
p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.Client) ([]*objectSDK.ID, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// once compose and resign forwarding request
|
// once compose and resign forwarding request
|
||||||
|
@ -101,7 +101,7 @@ func (s *Service) toPrm(req *objectV2.SearchRequest, stream objectSvc.SearchStre
|
||||||
}
|
}
|
||||||
|
|
||||||
return searchResult, nil
|
return searchResult, nil
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
body := req.GetBody()
|
body := req.GetBody()
|
||||||
|
@ -110,3 +110,32 @@ func (s *Service) toPrm(req *objectV2.SearchRequest, stream objectSvc.SearchStre
|
||||||
|
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func groupAddressRequestForwarder(f func(network.Address, client.Client) ([]*objectSDK.ID, error)) searchsvc.RequestForwarder {
|
||||||
|
return func(addrGroup network.AddressGroup, c client.Client) ([]*objectSDK.ID, error) {
|
||||||
|
var (
|
||||||
|
firstErr error
|
||||||
|
res []*objectSDK.ID
|
||||||
|
)
|
||||||
|
|
||||||
|
addrGroup.IterateAddresses(func(addr network.Address) (stop bool) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
stop = err == nil
|
||||||
|
|
||||||
|
if stop || firstErr == nil {
|
||||||
|
firstErr = err
|
||||||
|
}
|
||||||
|
|
||||||
|
// would be nice to log otherwise
|
||||||
|
}()
|
||||||
|
|
||||||
|
res, err = f(addr, c)
|
||||||
|
|
||||||
|
return
|
||||||
|
})
|
||||||
|
|
||||||
|
return res, firstErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue