From b27f172de9dbb3079c3106b41beac14c32071402 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 4 Apr 2025 17:14:27 +0300 Subject: [PATCH] [#345] netmap: Implement an iterator over node endpoints Signed-off-by: Evgenii Stratonikov --- api/netmap/types.go | 13 +++++++++++++ netmap/node_info.go | 17 ++++++++++++++++- netmap/node_info_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/api/netmap/types.go b/api/netmap/types.go index 38810ab..67c3e01 100644 --- a/api/netmap/types.go +++ b/api/netmap/types.go @@ -2,6 +2,7 @@ package netmap import ( "bytes" + "iter" "slices" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs" @@ -442,10 +443,22 @@ func (ni *NodeInfo) NumberOfAddresses() int { 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. // Breaks iteration on f's true return. // // Handler should not be nil. +// Deprecated: use [NodeInfo.Addresses] instead. func (ni *NodeInfo) IterateAddresses(f func(string) bool) { if ni != nil { for i := range ni.addresses { diff --git a/netmap/node_info.go b/netmap/node_info.go index a792337..a596b2b 100644 --- a/netmap/node_info.go +++ b/netmap/node_info.go @@ -3,6 +3,7 @@ package netmap import ( "errors" "fmt" + "iter" "slices" "strconv" "strings" @@ -200,12 +201,26 @@ func (x NodeInfo) NumberOfNetworkEndpoints() int { // FrostFS system requirements. // // See also SetNetworkEndpoints. +// Deprecated: use [NodeInfo.NetworkEndpoints] instead. 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 // method which allows to unconditionally iterate over all node's network endpoints. +// Deprecated: use [NodeInfo.NetworkEndpoints] instead. func IterateNetworkEndpoints(node NodeInfo, f func(string)) { node.IterateNetworkEndpoints(func(addr string) bool { f(addr) diff --git a/netmap/node_info_test.go b/netmap/node_info_test.go index 965213e..8ef9516 100644 --- a/netmap/node_info_test.go +++ b/netmap/node_info_test.go @@ -7,6 +7,45 @@ import ( "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) { var n NodeInfo