Skip to content
This repository has been archived by the owner on Sep 1, 2023. It is now read-only.

Commit

Permalink
Optimize Peer lookups (connectrpc#447)
Browse files Browse the repository at this point in the history
Peer() is nearly always called, often more than once. Because Peer is a returned as a value and all fields are immutable strings, it's safe to create it once and memoize it. Along the way, this PR also cuts down on repeated URL parsing.

---------

Co-authored-by: Akshay Shah <[email protected]>
  • Loading branch information
mattrobenolt and akshayjshah authored Jan 28, 2023
1 parent 5999752 commit e0629a7
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 20 deletions.
9 changes: 4 additions & 5 deletions connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,11 @@ type Peer struct {
Protocol string
}

func newPeerFromURL(urlString, protocol string) Peer {
peer := Peer{Protocol: protocol}
if u, err := url.Parse(urlString); err == nil {
peer.Addr = u.Host
func newPeerFromURL(url *url.URL, protocol string) Peer {
return Peer{
Addr: url.Host,
Protocol: protocol,
}
return peer
}

// handlerConnCloser extends HandlerConn with a method for handlers to
Expand Down
12 changes: 6 additions & 6 deletions protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,20 +238,20 @@ func discard(reader io.Reader) error {
return err
}

func validateRequestURL(uri string) *Error {
_, err := url.ParseRequestURI(uri)
func validateRequestURL(rawURL string) (*url.URL, *Error) {
url, err := url.ParseRequestURI(rawURL)
if err == nil {
return nil
return url, nil
}
if !strings.Contains(uri, "://") {
if !strings.Contains(rawURL, "://") {
// URL doesn't have a scheme, so the user is likely accustomed to
// grpc-go's APIs.
err = fmt.Errorf(
"URL %q missing scheme: use http:// or https:// (unlike grpc-go)",
uri,
rawURL,
)
}
return NewError(CodeUnavailable, err)
return nil, NewError(CodeUnavailable, err)
}

// negotiateCompression determines and validates the request compression and
Expand Down
12 changes: 9 additions & 3 deletions protocol_connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,14 @@ func (*protocolConnect) NewHandler(params *protocolHandlerParams) protocolHandle

// NewClient implements protocol, so it must return an interface.
func (*protocolConnect) NewClient(params *protocolClientParams) (protocolClient, error) {
if err := validateRequestURL(params.URL); err != nil {
url, err := validateRequestURL(params.URL)
if err != nil {
return nil, err
}
return &connectClient{protocolClientParams: *params}, nil
return &connectClient{
protocolClientParams: *params,
peer: newPeerFromURL(url, ProtocolConnect),
}, nil
}

type connectHandler struct {
Expand Down Expand Up @@ -238,10 +242,12 @@ func (h *connectHandler) NewConn(

type connectClient struct {
protocolClientParams

peer Peer
}

func (c *connectClient) Peer() Peer {
return newPeerFromURL(c.URL, ProtocolConnect)
return c.peer
}

func (c *connectClient) WriteRequestHeader(streamType StreamType, header http.Header) {
Expand Down
16 changes: 10 additions & 6 deletions protocol_grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,18 @@ func (g *protocolGRPC) NewHandler(params *protocolHandlerParams) protocolHandler

// NewClient implements protocol, so it must return an interface.
func (g *protocolGRPC) NewClient(params *protocolClientParams) (protocolClient, error) {
if err := validateRequestURL(params.URL); err != nil {
url, err := validateRequestURL(params.URL)
if err != nil {
return nil, err
}
peer := newPeerFromURL(url, ProtocolGRPC)
if g.web {
peer = newPeerFromURL(url, ProtocolGRPCWeb)
}
return &grpcClient{
protocolClientParams: *params,
web: g.web,
peer: peer,
}, nil
}

Expand Down Expand Up @@ -224,14 +230,12 @@ func (g *grpcHandler) NewConn(
type grpcClient struct {
protocolClientParams

web bool
web bool
peer Peer
}

func (g *grpcClient) Peer() Peer {
if g.web {
return newPeerFromURL(g.URL, ProtocolGRPCWeb)
}
return newPeerFromURL(g.URL, ProtocolGRPC)
return g.peer
}

func (g *grpcClient) WriteRequestHeader(_ StreamType, header http.Header) {
Expand Down

0 comments on commit e0629a7

Please sign in to comment.