Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

peer and metadata: Implement the Stringer interface for Peer and Metadata #7137

Merged
merged 9 commits into from
May 6, 2024

Conversation

AnomalRoil
Copy link
Contributor

@AnomalRoil AnomalRoil commented Apr 17, 2024

Effectively allowing to print contextes containing a Peer properly.
Instead of printing with %v as:

context.Background.WithValue(type peer.peerKey, val <not Stringer>)

contexts containing a peer will now print as:

context.Background.WithValue(type peer.peerKey, val Peer{Addr: '1.2.3.4:1234', AuthInfo: 'testAuthInfo'})

This is also satisfying Stringer interface for Metadata, allowing to print them easily too. Since Metadata are basically a map, notice that String output is not stable. I could change it to print it in alphabetical order if you prefer.

RELEASE NOTES:

  • peer/peer: implement the Stringer interface for pretty printing Peer
  • metadata/metadata: implement the Stringer interface for pretty printing MD

Copy link

linux-foundation-easycla bot commented Apr 17, 2024

CLA Signed

The committers listed above are authorized under a signed CLA.

@AnomalRoil AnomalRoil force-pushed the master branch 2 times, most recently from bc88d17 to 5e7b8a3 Compare April 17, 2024 16:10
@aranjans aranjans self-requested a review April 17, 2024 17:00
peer/peer.go Outdated Show resolved Hide resolved
metadata/metadata.go Outdated Show resolved Hide resolved
peer/peer_test.go Outdated Show resolved Hide resolved
balancer_wrapper.go Outdated Show resolved Hide resolved
Effectively allowing to print context containing Peers properly

Also enabling logging of Metadata in an easier way

RELEASE NOTES:

 - peer/peer: implement the Stringer interface for pretty-printing Peers
 - metadata/metadata: implement the Stringer interface for pretty printing metadata

Signed-off-by: Yolan Romailler <anomalroil@users.noreply.github.com>
Signed-off-by: Yolan Romailler <anomalroil@users.noreply.github.com>
…fication of which SubConn is used

Protect access to curAddr with ac.mutex

Signed-off-by: Yolan Romailler <anomalroil@users.noreply.github.com>
Signed-off-by: Yolan Romailler <anomalroil@users.noreply.github.com>
…n identification of which SubConn is used"

This reverts commit 001f394.

Signed-off-by: Yolan Romailler <anomalroil@users.noreply.github.com>
Copy link
Member

@arvindbr8 arvindbr8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change overall looks good to me. I took a pass at it. please take a look

metadata/metadata.go Show resolved Hide resolved
metadata/metadata.go Show resolved Hide resolved
metadata/metadata_test.go Show resolved Hide resolved
peer/peer.go Show resolved Hide resolved
peer/peer.go Show resolved Hide resolved
peer/peer_test.go Outdated Show resolved Hide resolved
peer/peer_test.go Outdated Show resolved Hide resolved
peer/peer_test.go Outdated Show resolved Hide resolved
peer/peer_test.go Outdated Show resolved Hide resolved
metadata/metadata.go Outdated Show resolved Hide resolved
Copy link
Member

@arvindbr8 arvindbr8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change overall looks good to me. I took a pass at it. please take a look

@arvindbr8 arvindbr8 assigned aranjans and unassigned arvindbr8 Apr 24, 2024
@aranjans aranjans removed their assignment Apr 25, 2024
@aranjans aranjans added this to the 1.64 Release milestone Apr 29, 2024
@aranjans aranjans added the Type: Behavior Change Behavior changes not categorized as bugs label Apr 29, 2024
@AnomalRoil AnomalRoil requested a review from arvindbr8 May 1, 2024 16:54
@AnomalRoil AnomalRoil removed their assignment May 1, 2024
Signed-off-by: Yolan Romailler <anomalroil@users.noreply.github.com>
Copy link
Member

@arvindbr8 arvindbr8 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've responded to our conversations here. Please take a look

metadata/metadata.go Show resolved Hide resolved
peer/peer.go Show resolved Hide resolved
peer/peer.go Show resolved Hide resolved
metadata/metadata.go Show resolved Hide resolved
metadata/metadata_test.go Show resolved Hide resolved
peer/peer_test.go Outdated Show resolved Hide resolved
peer/peer_test.go Outdated Show resolved Hide resolved
peer/peer_test.go Show resolved Hide resolved
metadata/metadata_test.go Outdated Show resolved Hide resolved
metadata/metadata_test.go Outdated Show resolved Hide resolved
metadata/metadata_test.go Outdated Show resolved Hide resolved
AnomalRoil and others added 2 commits May 2, 2024 12:36
Co-authored-by: Arvind Bright <arvind.bright100@gmail.com>
Signed-off-by: Yolan Romailler <anomalroil@users.noreply.github.com>
Signed-off-by: Yolan Romailler <anomalroil@users.noreply.github.com>
@AnomalRoil AnomalRoil requested a review from arvindbr8 May 2, 2024 11:22
want string
}{
{
name: "+Addr-LocalAddr+ValidAuth",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI, go test std library already does something similar by replacing \ss with _s.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to convey information about whether the test case included + or didn't include - that specific field.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of + and - to convey the presence or absence of certain fields within the Peer isn't very readable. How about the following:

  • withAddrAndValidAuth
  • withAddrLocalAddrAndValidAuth
  • withAddrAndEmptyAuth
  • withAddrLocalAddrAndEmptyAuth
  • nilPeer

The above names in the test output are more readable I feel.

@arvindbr8
Copy link
Member

Per policy we need one more review before we can check this in. I will ping a co-maintainer to take a look at this.

@arvindbr8 arvindbr8 removed their assignment May 2, 2024
@arvindbr8 arvindbr8 requested a review from zasweq May 6, 2024 17:13
Copy link
Contributor

@zasweq zasweq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for the contribution.

@zasweq zasweq changed the title Satisfy the Stringer interface for Peer and Metadata peer/ and metadata/:Implement the Stringer interface for Peer and Metadata May 6, 2024
@zasweq zasweq changed the title peer/ and metadata/:Implement the Stringer interface for Peer and Metadata peer and metadata:Implement the Stringer interface for Peer and Metadata May 6, 2024
@zasweq zasweq changed the title peer and metadata:Implement the Stringer interface for Peer and Metadata peer and metadata: Implement the Stringer interface for Peer and Metadata May 6, 2024
@zasweq zasweq merged commit 9d9a96f into grpc:master May 6, 2024
12 checks passed
@serathius
Copy link

serathius commented Jun 26, 2024

Making String() non-deterministic broke etcd stream selection mechanism.

@dims
Copy link
Contributor

dims commented Jun 26, 2024

@serathius @zasweq the following patch to make the string deterministic solves our issue:

diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go
index 6c01a9b359cc..ec1055f6ccf0 100644
--- a/vendor/google.golang.org/grpc/metadata/metadata.go
+++ b/vendor/google.golang.org/grpc/metadata/metadata.go
@@ -24,6 +24,7 @@ package metadata // import "google.golang.org/grpc/metadata"
 import (
 	"context"
 	"fmt"
+	"sort"
 	"strings"
 
 	"google.golang.org/grpc/internal"
@@ -95,11 +96,16 @@ func Pairs(kv ...string) MD {
 func (md MD) String() string {
 	var sb strings.Builder
 	fmt.Fprintf(&sb, "MD{")
-	for k, v := range md {
+	keys := make([]string, 0, len(md))
+	for k := range md {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	for _, k := range keys {
 		if sb.Len() > 3 {
 			fmt.Fprintf(&sb, ", ")
 		}
-		fmt.Fprintf(&sb, "%s=[%s]", k, strings.Join(v, ", "))
+		fmt.Fprintf(&sb, "%s=[%s]", k, strings.Join(md[k], ", "))
 	}
 	fmt.Fprintf(&sb, "}")
 	return sb.String()

@serathius
Copy link

serathius commented Jun 26, 2024

Context why deterministic String() is important for etcd.

Etcd uses grpc metadata to change properties of the bi-directional watch stream. Example of that is WithRequireLeader() which will ask server to break the stream if leader is no longer available in the cluster. As client can make multiple watch requests within a bi-directional stream, we need to create a separate stream for clients that provide different metadata in the request context. Etcd client get the identifiers of stream by formatting the context metadata, so it's crucial to have deterministic stringer to properly reuse the streams.

Code: https://github.com/etcd-io/etcd/blob/21e5876f7f0539509c277b4c2a3ba1b1599b1721/client/v3/watch.go#L1038-L1043

@@ -90,6 +90,21 @@ func Pairs(kv ...string) MD {
return md
}

// String implements the Stringer interface for pretty-printing a MD.
// Ordering of the values is non-deterministic as it ranges over a map.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about sorting the keys before generating the string representation and ensuring that the output is deterministic. This will also make the unit test much simpler than what it is currently.

var sb strings.Builder
fmt.Fprintf(&sb, "MD{")
for k, v := range md {
if sb.Len() > 3 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about defining a bool first and using that as the conditional here, instead of this magic check which took me sometime to understand.

want string
}{
{
name: "+Addr-LocalAddr+ValidAuth",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of + and - to convey the presence or absence of certain fields within the Peer isn't very readable. How about the following:

  • withAddrAndValidAuth
  • withAddrLocalAddrAndValidAuth
  • withAddrAndEmptyAuth
  • withAddrLocalAddrAndEmptyAuth
  • nilPeer

The above names in the test output are more readable I feel.

@easwars
Copy link
Contributor

easwars commented Jun 26, 2024

Phew.... Didn't realize that the PR was already approved and merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Behavior Change Behavior changes not categorized as bugs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants