You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pegasus.apache.org by wa...@apache.org on 2026/02/11 09:42:33 UTC

(incubator-pegasus) branch master updated: feat(go-client): introduce Equal APIs for HostPort and RPCAddress (#2360)

This is an automated email from the ASF dual-hosted git repository.

wangdan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git


The following commit(s) were added to refs/heads/master by this push:
     new fcab87d96 feat(go-client): introduce Equal APIs for HostPort and RPCAddress (#2360)
fcab87d96 is described below

commit fcab87d96b7f5451dbb70c8f12ac33cfd3eca8b3
Author: Dan Wang <wa...@apache.org>
AuthorDate: Wed Feb 11 17:42:28 2026 +0800

    feat(go-client): introduce Equal APIs for HostPort and RPCAddress (#2360)
    
    https://github.com/apache/incubator-pegasus/issues/2358
    
    Add `Equal` interfaces for the `HostPort` and `RPCAddress` structures to enable
    equality comparisons based on attributes such as host and port.
---
 go-client/idl/base/host_port.go        | 59 +++++++++++++++------
 go-client/idl/base/host_port_test.go   | 94 ++++++++++++++++++++++++++++------
 go-client/idl/base/rpc_address.go      | 34 ++++++------
 go-client/idl/base/rpc_address_test.go | 59 ++++++++++++++++++---
 4 files changed, 192 insertions(+), 54 deletions(-)

diff --git a/go-client/idl/base/host_port.go b/go-client/idl/base/host_port.go
index 22b721815..8fc1981ea 100644
--- a/go-client/idl/base/host_port.go
+++ b/go-client/idl/base/host_port.go
@@ -48,7 +48,7 @@ func NewHostPort(host string, port uint16) *HostPort {
 	}
 }
 
-func (r *HostPort) Read(iprot thrift.TProtocol) error {
+func (hp *HostPort) Read(iprot thrift.TProtocol) error {
 	host, err := iprot.ReadString()
 	if err != nil {
 		return err
@@ -62,43 +62,68 @@ func (r *HostPort) Read(iprot thrift.TProtocol) error {
 		return err
 	}
 
-	r.host = host
-	r.port = uint16(port)
-	r.hpType = HostPortType(hpType)
+	hp.host = host
+	hp.port = uint16(port)
+	hp.hpType = HostPortType(hpType)
 	return nil
 }
 
-func (r *HostPort) Write(oprot thrift.TProtocol) error {
-	err := oprot.WriteString(r.host)
+func (hp *HostPort) Write(oprot thrift.TProtocol) error {
+	err := oprot.WriteString(hp.host)
 	if err != nil {
 		return err
 	}
-	err = oprot.WriteI16(int16(r.port))
+	err = oprot.WriteI16(int16(hp.port))
 	if err != nil {
 		return err
 	}
-	err = oprot.WriteByte(int8(r.hpType))
+	err = oprot.WriteByte(int8(hp.hpType))
 	if err != nil {
 		return err
 	}
 	return nil
 }
 
-func (r *HostPort) GetHost() string {
-	return r.host
+func (hp *HostPort) GetHost() string {
+	return hp.host
 }
 
-func (r *HostPort) GetPort() uint16 {
-	return r.port
+func (hp *HostPort) GetPort() uint16 {
+	return hp.port
 }
 
-func (r *HostPort) String() string {
-	if r == nil {
+func (hp *HostPort) String() string {
+	if hp == nil {
 		return "<nil>"
 	}
-	return fmt.Sprintf("HostPort(%s:%d)", r.host, r.port)
+	return fmt.Sprintf("HostPort(%s:%d)", hp.host, hp.port)
 }
 
-func (r *HostPort) GetHostPort() string {
-	return fmt.Sprintf("%s:%d", r.host, r.port)
+func (hp *HostPort) GetHostPort() string {
+	return fmt.Sprintf("%s:%d", hp.host, hp.port)
+}
+
+func (hp *HostPort) Equal(other *HostPort) bool {
+	if hp == other {
+		return true
+	}
+
+	if hp == nil || other == nil {
+		return false
+	}
+
+	if hp.hpType != other.hpType {
+		return false
+	}
+
+	switch hp.hpType {
+	case HOST_TYPE_IPV4:
+		return hp.host == other.host &&
+			hp.port == other.port
+	case HOST_TYPE_GROUP:
+		// TODO(wangdan): support HOST_TYPE_GROUP.
+		return false
+	default:
+		return true
+	}
 }
diff --git a/go-client/idl/base/host_port_test.go b/go-client/idl/base/host_port_test.go
index e07d3f02f..28f42fded 100644
--- a/go-client/idl/base/host_port_test.go
+++ b/go-client/idl/base/host_port_test.go
@@ -20,32 +20,96 @@
 package base
 
 import (
+	"fmt"
 	"testing"
 
 	"github.com/apache/thrift/lib/go/thrift"
 	"github.com/stretchr/testify/assert"
 )
 
+func testNewHostPort(t *testing.T, host string, port uint16) *HostPort {
+	hp := NewHostPort(host, port)
+	assert.Equal(t, host, hp.GetHost())
+	assert.Equal(t, port, hp.GetPort())
+	assert.True(t, hp.Equal(hp))
+
+	return hp
+}
+
+func stringify(host string, port uint16) string {
+	return fmt.Sprintf("<%s:%d>", host, port)
+}
+
 func TestHostPort(t *testing.T) {
-	testCases := map[string]uint16{
-		"localhost": 8080,
+	tests := map[string]uint16{
+		"localhost":          8080,
+		"pegasus.apache.org": 443,
 	}
 
-	for host, port := range testCases {
-		hp := NewHostPort(host, port)
-		assert.Equal(t, host, hp.GetHost())
-		assert.Equal(t, port, hp.GetPort())
+	runner := func(host string, port uint16) func(t *testing.T) {
+		return func(t *testing.T) {
+			t.Parallel()
+
+			hp := testNewHostPort(t, host, port)
 
-		// test HostPort serialize
-		buf := thrift.NewTMemoryBuffer()
-		oprot := thrift.NewTBinaryProtocolTransport(buf)
-		hp.Write(oprot)
+			// Test serialization.
+			buf := thrift.NewTMemoryBuffer()
+			oprot := thrift.NewTBinaryProtocolTransport(buf)
+			assert.NoError(t, hp.Write(oprot))
 
-		// test HostPort deserialize
-		readHostPort := NewHostPort("", 0)
-		readHostPort.Read(oprot)
+			// Test deserialization.
+			peer := NewHostPort("", 0)
+			assert.NoError(t, peer.Read(oprot))
+			assert.True(t, peer.Equal(peer))
+
+			// Test equality.
+			assert.Equal(t, hp, peer)
+			assert.True(t, hp.Equal(peer))
+			assert.True(t, peer.Equal(hp))
+		}
+	}
+
+	for host, port := range tests {
+		t.Run(stringify(host, port), runner(host, port))
+	}
+}
+
+func TestHostPortEquality(t *testing.T) {
+	type hpCase struct {
+		host string
+		port uint16
+	}
+	type testCase struct {
+		x     hpCase
+		y     hpCase
+		equal bool
+	}
+	tests := []testCase{
+		{hpCase{"localhost", 8080}, hpCase{"localhost", 8080}, true},
+		{hpCase{"localhost", 8080}, hpCase{"pegasus.apache.org", 8080}, false},
+		{hpCase{"localhost", 8080}, hpCase{"localhost", 8081}, false},
+	}
+
+	testName := func(hpX hpCase, hpY hpCase) string {
+		hpName := func(hp hpCase) string {
+			return stringify(hp.host, hp.port)
+		}
+		return fmt.Sprintf("%s-vs-%s", hpName(hpX), hpName(hpY))
+	}
+
+	runner := func(test testCase) func(t *testing.T) {
+		return func(t *testing.T) {
+			t.Parallel()
+
+			hpX := testNewHostPort(t, test.x.host, test.x.port)
+			hpY := testNewHostPort(t, test.y.host, test.y.port)
+
+			assert.Equal(t, test.equal, hpX.Equal(hpY))
+			assert.Equal(t, test.equal, hpY.Equal(hpX))
+		}
+	}
 
-		// check equals
-		assert.Equal(t, readHostPort, hp)
+	for _, test := range tests {
+		t.Run(testName(test.x, test.y), runner(test))
 	}
 }
diff --git a/go-client/idl/base/rpc_address.go b/go-client/idl/base/rpc_address.go
index d451c4228..16d4da83a 100644
--- a/go-client/idl/base/rpc_address.go
+++ b/go-client/idl/base/rpc_address.go
@@ -37,38 +37,42 @@ func NewRPCAddress(ip net.IP, port int) *RPCAddress {
 	}
 }
 
-func (r *RPCAddress) Read(iprot thrift.TProtocol) error {
+func (a *RPCAddress) Read(iprot thrift.TProtocol) error {
 	address, err := iprot.ReadI64()
 	if err != nil {
 		return err
 	}
-	r.address = address
+	a.address = address
 	return nil
 }
 
-func (r *RPCAddress) Write(oprot thrift.TProtocol) error {
-	return oprot.WriteI64(r.address)
+func (a *RPCAddress) Write(oprot thrift.TProtocol) error {
+	return oprot.WriteI64(a.address)
 }
 
-func (r *RPCAddress) String() string {
-	if r == nil {
+func (a *RPCAddress) String() string {
+	if a == nil {
 		return "<nil>"
 	}
-	return fmt.Sprintf("RPCAddress(%s)", r.GetAddress())
+	return fmt.Sprintf("RPCAddress(%s)", a.GetAddress())
 }
 
-func (r *RPCAddress) GetIP() net.IP {
-	return net.IPv4(byte(0xff&(r.address>>56)), byte(0xff&(r.address>>48)), byte(0xff&(r.address>>40)), byte(0xff&(r.address>>32)))
+func (a *RPCAddress) GetIP() net.IP {
+	return net.IPv4(byte(0xff&(a.address>>56)), byte(0xff&(a.address>>48)), byte(0xff&(a.address>>40)), byte(0xff&(a.address>>32)))
 }
 
-func (r *RPCAddress) GetPort() int {
-	return int(0xffff & (r.address >> 16))
+func (a *RPCAddress) GetPort() int {
+	return int(0xffff & (a.address >> 16))
 }
 
-func (r *RPCAddress) GetAddress() string {
-	return fmt.Sprintf("%s:%d", r.GetIP(), r.GetPort())
+func (a *RPCAddress) GetAddress() string {
+	return fmt.Sprintf("%s:%d", a.GetIP(), a.GetPort())
 }
 
-func (r *RPCAddress) GetRawAddress() int64 {
-	return r.address
+func (a *RPCAddress) GetRawAddress() int64 {
+	return a.address
+}
+
+func (a *RPCAddress) Equal(other *RPCAddress) bool {
+	return a.address == other.address
 }
diff --git a/go-client/idl/base/rpc_address_test.go b/go-client/idl/base/rpc_address_test.go
index fbb86210e..1df85c065 100644
--- a/go-client/idl/base/rpc_address_test.go
+++ b/go-client/idl/base/rpc_address_test.go
@@ -20,25 +20,70 @@
 package base
 
 import (
+	"fmt"
 	"net"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
 )
 
+func testNewRPCAddress(t *testing.T, addrStr string) *RPCAddress {
+	addr, err := net.ResolveTCPAddr("tcp", addrStr)
+	assert.NoError(t, err)
+
+	rpcAddr := NewRPCAddress(addr.IP, addr.Port)
+	assert.Equal(t, addrStr, rpcAddr.GetAddress())
+	assert.True(t, rpcAddr.Equal(rpcAddr))
+
+	return rpcAddr
+}
+
 func TestRPCAddress(t *testing.T) {
-	testCases := []string{
+	tests := []string{
 		"127.0.0.1:8080",
 		"192.168.0.1:123",
 		"0.0.0.0:12345",
 	}
 
-	for _, ts := range testCases {
-		tcpAddrStr := ts
-		addr, err := net.ResolveTCPAddr("tcp", tcpAddrStr)
-		assert.NoError(t, err)
+	runner := func(test string) func(t *testing.T) {
+		return func(t *testing.T) {
+			t.Parallel()
+
+			testNewRPCAddress(t, test)
+		}
+	}
+
+	for _, test := range tests {
+		name := fmt.Sprintf("<%s>", test)
+		t.Run(name, runner(test))
+	}
+}
+
+func TestRPCAddressEquality(t *testing.T) {
+	tests := []struct {
+		x     string
+		y     string
+		equal bool
+	}{
+		{"127.0.0.1:8080", "127.0.0.1:8080", true},
+		{"127.0.0.1:8080", "192.168.0.1:8080", false},
+		{"127.0.0.1:8080", "127.0.0.1:8081", false},
+	}
+
+	runner := func(x string, y string, equal bool) func(t *testing.T) {
+		return func(t *testing.T) {
+			t.Parallel()
+
+			rpcAddrX := testNewRPCAddress(t, x)
+			rpcAddrY := testNewRPCAddress(t, y)
+
+			assert.Equal(t, equal, rpcAddrX.Equal(rpcAddrY))
+			assert.Equal(t, equal, rpcAddrY.Equal(rpcAddrX))
+		}
+	}
 
-		rpcAddr := NewRPCAddress(addr.IP, addr.Port)
-		assert.Equal(t, rpcAddr.GetAddress(), tcpAddrStr)
+	for _, test := range tests {
+		name := fmt.Sprintf("<%s>-vs-<%s>", test.x, test.y)
+		t.Run(name, runner(test.x, test.y, test.equal))
 	}
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pegasus.apache.org
For additional commands, e-mail: commits-help@pegasus.apache.org