[#345] netmap: Implement an iterator over node endpoints

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2025-04-04 17:14:27 +03:00
parent 5be3415961
commit b27f172de9
Signed by: fyrchik
SSH key fingerprint: SHA256:m/TTwCzjnRkXgnzEx9X92ccxy1CcVeinOgDb3NPWWmg
3 changed files with 68 additions and 1 deletions

View file

@ -2,6 +2,7 @@ package netmap
import ( import (
"bytes" "bytes"
"iter"
"slices" "slices"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs"
@ -442,10 +443,22 @@ func (ni *NodeInfo) NumberOfAddresses() int {
return 0 return 0
} }
// Addresses returns an iterator over network addresses of the node.
func (ni NodeInfo) Addresses() iter.Seq[string] {
return func(yield func(string) bool) {
for i := range ni.addresses {
if !yield(ni.addresses[i]) {
break
}
}
}
}
// IterateAddresses iterates over network addresses of the node. // IterateAddresses iterates over network addresses of the node.
// Breaks iteration on f's true return. // Breaks iteration on f's true return.
// //
// Handler should not be nil. // Handler should not be nil.
// Deprecated: use [NodeInfo.Addresses] instead.
func (ni *NodeInfo) IterateAddresses(f func(string) bool) { func (ni *NodeInfo) IterateAddresses(f func(string) bool) {
if ni != nil { if ni != nil {
for i := range ni.addresses { for i := range ni.addresses {

View file

@ -3,6 +3,7 @@ package netmap
import ( import (
"errors" "errors"
"fmt" "fmt"
"iter"
"slices" "slices"
"strconv" "strconv"
"strings" "strings"
@ -200,12 +201,26 @@ func (x NodeInfo) NumberOfNetworkEndpoints() int {
// FrostFS system requirements. // FrostFS system requirements.
// //
// See also SetNetworkEndpoints. // See also SetNetworkEndpoints.
// Deprecated: use [NodeInfo.NetworkEndpoints] instead.
func (x NodeInfo) IterateNetworkEndpoints(f func(string) bool) { func (x NodeInfo) IterateNetworkEndpoints(f func(string) bool) {
x.m.IterateAddresses(f) for s := range x.NetworkEndpoints() {
if f(s) {
return
}
}
}
// NetworkEndpoints returns an iterator over network endpoints announced by the
// node.
//
// See also SetNetworkEndpoints.
func (x NodeInfo) NetworkEndpoints() iter.Seq[string] {
return x.m.Addresses()
} }
// IterateNetworkEndpoints is an extra-sugared function over IterateNetworkEndpoints // IterateNetworkEndpoints is an extra-sugared function over IterateNetworkEndpoints
// method which allows to unconditionally iterate over all node's network endpoints. // method which allows to unconditionally iterate over all node's network endpoints.
// Deprecated: use [NodeInfo.NetworkEndpoints] instead.
func IterateNetworkEndpoints(node NodeInfo, f func(string)) { func IterateNetworkEndpoints(node NodeInfo, f func(string)) {
node.IterateNetworkEndpoints(func(addr string) bool { node.IterateNetworkEndpoints(func(addr string) bool {
f(addr) f(addr)

View file

@ -7,6 +7,45 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestNodeInfo_NetworkEndpoints(t *testing.T) {
t.Run("empty", func(t *testing.T) {
var n NodeInfo
for range n.NetworkEndpoints() {
t.Fatalf("handler is called, but it shouldn't")
}
})
var n NodeInfo
n.SetNetworkEndpoints("1", "2", "3")
t.Run("break", func(t *testing.T) {
var res []string
for s := range n.NetworkEndpoints() {
if s == "2" {
break
}
res = append(res, s)
}
require.Equal(t, []string{"1"}, res)
})
t.Run("continue", func(t *testing.T) {
var res []string
for s := range n.NetworkEndpoints() {
if s == "2" {
continue
}
res = append(res, s)
}
require.Equal(t, []string{"1", "3"}, res)
})
var res []string
for s := range n.NetworkEndpoints() {
res = append(res, s)
}
require.Equal(t, []string{"1", "2", "3"}, res)
}
func TestNodeInfo_SetAttribute(t *testing.T) { func TestNodeInfo_SetAttribute(t *testing.T) {
var n NodeInfo var n NodeInfo