profile
viewpoint
If you are wondering where the data of this site comes from, please visit https://api.github.com/users/easwars/events. GitMemory does not store any data, but only uses NGINX to cache data for a period of time. The idea behind GitMemory is simply to give users a better reading experience.

easwars/grpc-go 1

The Go language implementation of gRPC. HTTP/2 based RPC

easwars/envoy 0

C++ front/service proxy

easwars/go-control-plane 0

Go implementation of data-plane-api

easwars/golang-samples 0

Sample apps and code written for Google Cloud in the Go programming language.

easwars/grpc 0

The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)

easwars/grpc-java 0

The Java gRPC implementation. HTTP/2 based RPC

push eventeaswars/grpc-go

Easwar Swaminathan

commit sha fb12d0787468f7bb7ff7ef210812cd0a1775a3d9

grpc: increase compliance with RFC 3986 while parsing the dial target

view details

push time in 5 hours

PR opened grpc/grpc-go

grpc: better RFC 3986 compliant target parsing

Summary of changes

  • Use url.Parse to parse dial target
    • If parsed scheme is not registered, or scheme is not found in the dial target, fallback to default scheme
  • As a result of using url.Parse, resolver.Target.Endpoint will contain a leading "/" in most cases
    • Updated existing resolver implementations to ignore this where appropriate
  • Stop overriding the channel's authority with the server name configured on the transport creds
    • transport creds are free to ignore the authority passed to them by gRPC during the handshake and use their own if required
  • Allow WithAuthority to override the :authority and serverName for cases where transport creds are used

Addresses https://github.com/grpc/grpc-go/issues/4717

RELEASE NOTES: TBD

+177 -182

0 comment

12 changed files

pr created time in 5 hours

push eventeaswars/grpc-go

Easwar Swaminathan

commit sha de6a1bd03e4b2d136bf5ede3c7a782f135448d1d

grpc: increase compliance with RFC 3986 while parsing the dial target

view details

push time in 5 hours

push eventeaswars/grpc-go

Doug Fawley

commit sha 6ff68b489ecba2884aff152835d745389598935a

channelz: recommend using admin.Register instead (#4797)

view details

Doug Fawley

commit sha 11437f66f20f3473e09fcf3fb5c23d4388af936f

test: add option to make httpServer wait for END_STREAM; fix RetryStats race (#4811)

view details

Easwar Swaminathan

commit sha 64bcc473f465b6d12bf71bb0f098ae6be6047265

grpc: increase compliance with RFC 3986 while parsing the dial target

view details

push time in 6 hours

push eventeaswars/grpc-go

Doug Fawley

commit sha 6ff68b489ecba2884aff152835d745389598935a

channelz: recommend using admin.Register instead (#4797)

view details

Doug Fawley

commit sha 11437f66f20f3473e09fcf3fb5c23d4388af936f

test: add option to make httpServer wait for END_STREAM; fix RetryStats race (#4811)

view details

push time in 6 hours

push eventeaswars/grpc-go

Easwar Swaminathan

commit sha 9cde64b02acef960d64b535e33e9093640695f72

grpc: increase compliance with RFC 3986 while parsing the dial target

view details

push time in 7 hours

PullRequestReviewEvent

issue openedgrpc/grpc-go

Racy test: Test/UnixCustomDialer

https://github.com/grpc/grpc-go/pull/4813/checks?check_run_id=3702858717

==================
WARNING: DATA RACE
Read at 0x00c0001f0043 by goroutine 1585:
  testing.(*common).logDepth()
      /opt/hostedtoolcache/go/1.17.1/x64/src/testing/testing.go:768 +0xc4
  testing.(*common).log()
      /opt/hostedtoolcache/go/1.17.1/x64/src/testing/testing.go:761 +0x5a
  testing.(*common).Log()
      /opt/hostedtoolcache/go/1.17.1/x64/src/testing/testing.go:800 +0x14
  google.golang.org/grpc/internal/grpctest.(*tLogger).log()
      /home/runner/work/grpc-go/grpc-go/internal/grpctest/tlogger.go:116 +0x4c4
  google.golang.org/grpc/internal/grpctest.(*tLogger).InfoDepth()
      /home/runner/work/grpc-go/grpc-go/internal/grpctest/tlogger.go:210 +0x64
  google.golang.org/grpc/internal/grpclog.InfoDepth()
      /home/runner/work/grpc-go/grpc-go/internal/grpclog/grpclog.go:35 +0x85
  google.golang.org/grpc/grpclog.(*componentData).InfoDepth()
      /home/runner/work/grpc-go/grpc-go/grpclog/component.go:36 +0x1b2
  google.golang.org/grpc/grpclog.(*componentData).Infof()
      /home/runner/work/grpc-go/grpc-go/grpclog/component.go:71 +0x1d
  google.golang.org/grpc/internal/channelz.(*dummyEntry).deleteChild()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:68 +0x128
  google.golang.org/grpc/internal/channelz.(*subChannel).deleteSelfFromTree()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:357 +0x2e5
  google.golang.org/grpc/internal/channelz.(*subChannel).deleteSelfIfReady()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:389 +0x30
  google.golang.org/grpc/internal/channelz.(*channelMap).decrTraceRefCount()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/funcs.go:389 +0x275
  google.golang.org/grpc/internal/channelz.(*channelTrace).clear()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:663 +0xf8
  google.golang.org/grpc/internal/channelz.(*channel).deleteSelfIfReady()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:288 +0x284
  google.golang.org/grpc/internal/channelz.(*channel).deleteChild()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:224 +0x88
  google.golang.org/grpc/internal/channelz.(*subChannel).deleteSelfFromTree()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:357 +0x2e5
  google.golang.org/grpc/internal/channelz.(*subChannel).deleteSelfIfReady()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:389 +0x30
  google.golang.org/grpc/internal/channelz.(*subChannel).deleteChild()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:334 +0x5b
  google.golang.org/grpc/internal/channelz.(*normalSocket).triggerDelete()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/types.go:533 +0x4e1
  google.golang.org/grpc/internal/channelz.(*channelMap).removeEntry()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/funcs.go:380 +0x214
  google.golang.org/grpc/internal/channelz.RemoveEntry()
      /home/runner/work/grpc-go/grpc-go/internal/channelz/funcs.go:283 +0x3a
  google.golang.org/grpc/internal/transport.(*http2Client).Close()
      /home/runner/work/grpc-go/grpc-go/internal/transport/http2_client.go:893 +0x24b
  google.golang.org/grpc/internal/transport.(*http2Client).reader()
      /home/runner/work/grpc-go/grpc-go/internal/transport/http2_client.go:1518 +0xf3a
  google.golang.org/grpc/internal/transport.newHTTP2Client·dwrap·7()
      /home/runner/work/grpc-go/grpc-go/internal/transport/http2_client.go:355 +0x39

Previous write at 0x00c0001f0043 by goroutine 878:
  testing.tRunner.func1()
      /opt/hostedtoolcache/go/1.17.1/x64/src/testing/testing.go:1246 +0x584
  testing.tRunner()
      /opt/hostedtoolcache/go/1.17.1/x64/src/testing/testing.go:1265 +0x268
  testing.(*T).Run·dwrap·21()
      /opt/hostedtoolcache/go/1.17.1/x64/src/testing/testing.go:1306 +0x47

Goroutine 1585 (running) created at:
  google.golang.org/grpc/internal/transport.newHTTP2Client()
      /home/runner/work/grpc-go/grpc-go/internal/transport/http2_client.go:355 +0x265b
  google.golang.org/grpc/internal/transport.NewClientTransport()
      /home/runner/work/grpc-go/grpc-go/internal/transport/transport.go:576 +0x80a
  google.golang.org/grpc.(*addrConn).createTransport()
      /home/runner/work/grpc-go/grpc-go/clientconn.go:1322 +0x5a9
  google.golang.org/grpc.(*addrConn).tryAllAddrs()
      /home/runner/work/grpc-go/grpc-go/clientconn.go:1255 +0x4f8
  google.golang.org/grpc.(*addrConn).resetTransport()
      /home/runner/work/grpc-go/grpc-go/clientconn.go:1190 +0x20a
  google.golang.org/grpc.(*addrConn).connect()
      /home/runner/work/grpc-go/grpc-go/clientconn.go:868 +0xbb
  google.golang.org/grpc.(*acBalancerWrapper).Connect·dwrap·9()
      /home/runner/work/grpc-go/grpc-go/balancer_conn_wrappers.go:285 +0x39

Goroutine 878 (finished) created at:
  testing.(*T).Run()
      /opt/hostedtoolcache/go/1.17.1/x64/src/testing/testing.go:1306 +0x726
  google.golang.org/grpc/internal/grpctest.RunSubTests()
      /home/runner/work/grpc-go/grpc-go/internal/grpctest/grpctest.go:99 +0x54a
  google.golang.org/grpc/test.Test()
      /home/runner/work/grpc-go/grpc-go/test/end2end_test.go:90 +0x3c
  testing.tRunner()
      /opt/hostedtoolcache/go/1.17.1/x64/src/testing/testing.go:1259 +0x22f
  testing.(*T).Run·dwrap·21()
      /opt/hostedtoolcache/go/1.17.1/x64/src/testing/testing.go:1306 +0x47
==================

created time in 10 hours

issue commentgrpc/grpc-go

Flaky test: Test/RetryStats

One more: https://github.com/grpc/grpc-go/pull/4813/checks?check_run_id=3702858717

easwars

comment created time in 10 hours

push eventGoogleCloudPlatform/traffic-director-grpc-bootstrap

Richard Belleville

commit sha ea8146fe7f821d269c13d3f338d886d640f7a251

Add --config-scope-experimental flag (#22)

view details

push time in 14 hours

PR merged GoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

The AppNet APIs introduce a scope field independent of VPC network. This PR introduces a flag enabling the bootstrap file to select a particular scope.

+185 -3

9 comments

2 changed files

gnossen

pr closed time in 14 hours

PullRequestReviewEvent

Pull request review commentGoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

 package main  import ( 	"context"+	"fmt" 	"math/rand" 	"net" 	"net/http" 	"net/http/httptest"+	"strings" 	"testing"  	"github.com/google/go-cmp/cmp" 	"github.com/google/uuid" ) +func TestValidate(t *testing.T) {+	tests := []struct {+		desc      string+		input     configInput+		wantError string+	}{+		{+			desc: "fails when config-scope has too many characters",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       strings.Repeat("a", 65),+			},+			wantError: "config-scope may only contain letters, numbers, and '-'. It must begin with a letter and must not exceed 64 characters in length",+		},+		{+			desc: "fails when config-scope does not start with an alphabetic letter",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       "4foo",+			},+			wantError: "config-scope may only contain letters, numbers, and '-'. It must begin with a letter and must not exceed 64 characters in length",+		},+		{+			desc: "fails when config-scope contains characters besides letters, numbers, and hyphens.",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       "h*x8",+			},+			wantError: "config-scope may only contain letters, numbers, and '-'. It must begin with a letter and must not exceed 64 characters in length",+		},+	}++	for _, test := range tests {+		t.Run(test.desc, func(t *testing.T) {+			err := validate(test.input)+			if test.wantError != fmt.Sprint(err) {

I would use err.Error() instead of fmt.Sprintf(err).

And the more common way to print an err here would be: t.Fatalf("blah foo: %v", err) https://tour.golang.org/methods/19

gnossen

comment created time in a day

Pull request review commentGoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

 package main  import ( 	"context"+	"fmt" 	"math/rand" 	"net" 	"net/http" 	"net/http/httptest"+	"strings" 	"testing"  	"github.com/google/go-cmp/cmp" 	"github.com/google/uuid" ) +func TestValidate(t *testing.T) {+	tests := []struct {+		desc      string+		input     configInput+		wantError string+	}{+		{+			desc: "fails when config-scope has too many characters",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       strings.Repeat("a", 65),+			},+			wantError: "config-scope may only contain letters, numbers, and '-'. It must begin with a letter and must not exceed 64 characters in length",+		},+		{+			desc: "fails when config-scope does not start with an alphabetic letter",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       "4foo",+			},+			wantError: "config-scope may only contain letters, numbers, and '-'. It must begin with a letter and must not exceed 64 characters in length",+		},+		{+			desc: "fails when config-scope contains characters besides letters, numbers, and hyphens.",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       "h*x8",+			},+			wantError: "config-scope may only contain letters, numbers, and '-'. It must begin with a letter and must not exceed 64 characters in length",+		},+	}++	for _, test := range tests {+		t.Run(test.desc, func(t *testing.T) {+			err := validate(test.input)+			if test.wantError != fmt.Sprint(err) {+				t.Fatalf("validate(%+v) returned output does not match expected:\nWant: \"%s\"\nGot: \"%s\"", test.input, test.wantError, fmt.Sprint(err))

It's always got before want. go/go-style/decisions#got-before-want

gnossen

comment created time in a day

PullRequestReviewEvent

Pull request review commentGoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

 func generate(in configInput) ([]byte, error) { 		}, 	} +	if in.configScope != "" {+		c.Node.Metadata["TRAFFICDIRECTOR_SCOPE_NAME"] = in.configScope+	}+ 	for k, v := range in.metadataLabels { 		c.Node.Metadata[k] = v 	} 	if in.includeV3Features { 		// xDS v2 implementation in TD expects the projectNumber and networkName in 		// the metadata field while the v3 implementation expects these in the id 		// field.-		c.Node.Id = fmt.Sprintf("projects/%d/networks/%s/nodes/%s", in.gcpProjectNumber, in.vpcNetworkName, uuid.New().String())+		var networkIdentifier string

One more small nit. This is more idiomatic Go.

networkIdentifier := in.vpcNetworkName
if in.configScope != "" {
	networkIdentifier = fmt.Sprintf("scope:%s", in.configScope)
}
gnossen

comment created time in a day

PullRequestReviewEvent
PullRequestReviewEvent

pull request commentGoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

@easwars, does it look good to you? (You are more well-versed in Go readability and such.)

I thought this behavior of failing to hit the final reply button, and your comments sitting in pending state happens only on critique. Proved wrong today.

Just made some minor nit comments. Otherwise, the changes look good to me. Will approve once the nits are taken care of.

gnossen

comment created time in a day

Pull request review commentGoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

 type configInput struct { 	secretsDir         string 	metadataLabels     map[string]string 	deploymentInfo     map[string]string+	configScope        string+}++func isLetter(b byte) bool {+	return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')+}++func isNumber(b byte) bool {+	return b >= '0' && b <= '9'+}++func validate(in configInput) error {+	if in.configScope != "" {+		maxLen := 64+		configScopeLen := len(in.configScope)+		if configScopeLen > maxLen {+			return fmt.Errorf("config-scope must not exceed %d characters. Current length: %d\n", maxLen, configScopeLen)+		}++		if !isLetter(in.configScope[0]) {+			return fmt.Errorf("config-scope must begin with a letter\n")+		}++		for i := 1; i < configScopeLen; i++ {

And if you do what Eric suggested, the following

configScopeLen := len(in.configScope)
if configScopeLen > maxLen {
	return fmt.Errorf("config-scope must not exceed %d characters. Current length: %d\n", maxLen, configScopeLen)
}

can be changed to

if l := len(configScope); l > maxLen {
	return fmt.Errorf("config-scope must not exceed %d characters. Current length: %d\n", maxLen, l)
}
gnossen

comment created time in 2 days

Pull request review commentGoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

 type configInput struct { 	secretsDir         string 	metadataLabels     map[string]string 	deploymentInfo     map[string]string+	configScope        string+}++func validate(in configInput) error {+	re := regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9-]{0,63}$`)+	if in.configScope != "" && !re.MatchString(in.configScope) {+		return fmt.Errorf("config-scope may only contain letters, numbers, and '-'. " +

Nit: It's totally acceptable to have insanely long lines in Go. Prefer not splitting lines up unless it improves readability. Thanks.

gnossen

comment created time in a day

Pull request review commentGoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

 import ( 	"github.com/google/uuid" ) +func TestValidate(t *testing.T) {+	tests := []struct {+		desc      string+		input     configInput+		wantError error+	}{+		{+			desc: "fails when config-scope has too many characters",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",+			},+			wantError: errors.New("config-scope must not exceed 64 characters. Current length: 67\n"),+		},+		{+			desc: "fails when config-scope does not start with an alphabetic letter",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       "4foo",+			},+			wantError: errors.New("config-scope must begin with a letter\n"),+		},+		{+			desc: "fails when config-scope contains characters besides letters, numbers, and hyphens.",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       "h*x8",+			},+			wantError: errors.New("config-scope must only contain letters, numbers, or '-'. Found '*'.\n"),+		},+	}++	for _, test := range tests {+		t.Run(test.desc, func(t *testing.T) {+			validationErr := validate(test.input)+			if fmt.Sprint(test.wantError) != fmt.Sprint(validationErr) {+				diff := cmp.Diff(fmt.Sprint(test.wantError), fmt.Sprint(validationErr))+				t.Fatalf("validate(%+v) returned output does not match expected (-want +got):\n%s", test.input, diff)+			}

Not sure cmp.Diff is very useful here since we are only going to be seeing two error msgs.

Change the type of wantError to be string.

if err := validate(test.input); err == nil || !strings.Contains(err.Error(), test.wantErr) {
  t.Fatalf(...)
}
gnossen

comment created time in 2 days

Pull request review commentGoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

 import ( 	"github.com/google/uuid" ) +func TestValidate(t *testing.T) {+	tests := []struct {+		desc      string+		input     configInput+		wantError error+	}{+		{+			desc: "fails when config-scope has too many characters",+			input: configInput{+				xdsServerUri:      "example.com:443",+				gcpProjectNumber:  123456789012345,+				vpcNetworkName:    "thedefault",+				ip:                "10.9.8.7",+				zone:              "uscentral-5",+				metadataLabels:    map[string]string{"k1": "v1", "k2": "v2"},+				includeV3Features: true,+				configScope:       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",

Maybe use https://pkg.go.dev/strings#Repeat?

gnossen

comment created time in 2 days

Pull request review commentGoogleCloudPlatform/traffic-director-grpc-bootstrap

Add --config-scope-experimental flag

 type configInput struct { 	secretsDir         string 	metadataLabels     map[string]string 	deploymentInfo     map[string]string+	configScope        string+}++func isLetter(b byte) bool {+	return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')+}++func isNumber(b byte) bool {+	return b >= '0' && b <= '9'+}++func validate(in configInput) error {+	if in.configScope != "" {+		maxLen := 64

const

gnossen

comment created time in 2 days

PullRequestReviewEvent
PullRequestReviewEvent

pull request commentGoogleCloudPlatform/traffic-director-grpc-examples

java/wallet: create Dockerfile and also update dependency to 1.41.0

@easwars are you okay with the changes in this PR?

I'm mostly OK with the changes, except the size issue which I commented about on the other thread.

sanjaypujare

comment created time in a day

pull request commentGoogleCloudPlatform/traffic-director-grpc-examples

java/wallet: create Dockerfile and also update dependency to 1.41.0

Do you have an idea of the size of your docker image? You can find the virtual size on pantheon. The Go image is 50.4 MB.

354.2 MB. Is the size going to cause any problem?

If it is possible to easily reduce the size, then we should do it. You can look at the Go Dockerfile where I only copy the binaries on to the final image. It would be nice if the image that we ask users to download and use is as small as reasonably possible.

sanjaypujare

comment created time in a day

PullRequestReviewEvent

delete branch easwars/traffic-director-grpc-examples

delete branch : golang_single_dockerfile

delete time in a day