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

gRPC transport initial work with crossdock testing #863

Merged
merged 101 commits into from
Apr 18, 2017
Merged

gRPC transport initial work with crossdock testing #863

merged 101 commits into from
Apr 18, 2017

Conversation

bufdev
Copy link
Contributor

@bufdev bufdev commented Mar 30, 2017

Done so far:

  • end-to-end working including testing with a client and server using protobuf
  • end-to-end working including testing with a generated grpc-go client talking to a yarpc server using protobuf
  • end-to-end working with thrift and json including testing in examples
  • oneway working
  • crossdock testing for protobuf, and for grpc with all encodings (only on go), and with oneway testing, except for a bug with context propagation, there's an issue that the context gets cancelled after the oneway call, and i think this issue could affect all oneway implementations, but other implementations get around it by effectively creating a new context, see handlers.go

To do:

  • couple cleanup items
  • more testing (the testing in encoding/x/protobuf/testing actually covers about 76% of transport/x/grpc but ya)
  • examples with thrift, json, etc
  • use peer.Chooser etc
  • get all keys for transport.Request set from headers

Generally I want to get most of this in, and then iterate from there. This is a start, we can refine as we go, I want to get the basics committed to x/ and then I can add stuff with more granularity.

@bufdev
Copy link
Contributor Author

bufdev commented Apr 11, 2017 via email

Copy link
Contributor

@willhug willhug left a comment

Choose a reason for hiding this comment

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

Alright, I've gone through pretty deep on most of the code. For now I'm going to request changes, but I'll take another look tomorrow morning and approve after that.

Note I've made a few comments about linking "TODOs" to tasks/issues where we can follow-up. This will give people who stumble upon these TODOs a place to look for follow-ups/issues with the TODOs.

if err := request.ValidateUnaryContext(ctx); err != nil {
return nil, err
}
protobuf.SetRawResponse(transportRequest.Headers)
Copy link
Contributor

Choose a reason for hiding this comment

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

we seem to have pretty tight coupling between the GRPC transport and the Protobuf encoding. Is it possible for us to avoid this? It reduces the flexibility of both the transport and the encoding.


func (customCodec) String() string {
// TODO: faking this as proto to be compatible with existing grpc clients
return "proto"
Copy link
Contributor

Choose a reason for hiding this comment

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

for this todo, can we link to this task: #911

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// Package grpc implements the grpc transport.
Copy link
Contributor

Choose a reason for hiding this comment

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

We should elaborate here a bit more about how the structure, how this is experimental, and should not be used (yet).

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've added a comment about the experimental status, but note that existing x/ packages are inconsistent on this topic. This comment I know is a nit, but in the spirit of tracking issues, I've added #918 to track this

)

type handler struct {
procedureServiceName string
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we should prefix these with their "origin"

yarpcServiceName
grpcServiceName
grpcMethodName

I'm keep having to remind myself the difference between the three strings.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

}
}

func (h *handler) handle(
Copy link
Contributor

Choose a reason for hiding this comment

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

can we add a comment about how the GRPC handler does not put context first, and therefore has invalid lint?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

// CreateTransport creates an RPC from the given parameters or fails the whole behavior.
//
// If trans is non-empty, this will be used instead of the behavior transport.
func CreateTransport(t crossdock.T, trans string) *yarpc.Dispatcher {
Copy link
Contributor

Choose a reason for hiding this comment

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

CreateDispatcherForTransport?

Transport is already a top-level object, so it's a bit confusing that a "CreateTransport" function returns a dispatcher.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ya for sure, updated

// useGrpc checks to see if a grpc server is expected to be
// available
func useGrpc() bool {
return os.Getenv("GRPC") == "enabled"
Copy link
Contributor

Choose a reason for hiding this comment

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

is this envVar limited to just the oneway tests? And, if so, should we make the envVar more explicit? (Additionally, I'm not sure how I feel about gating this test based on whether an environment variable is set, I could see some weird "i don't see the error" cases shrug)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is something I don't like either, but it's how the existing setup is. I agree with you, I think this could lead to misleading errors, and that we should fail if a transport is not able to come up, without having any conditionals in environment variables. I'm making a tracking issue for this as a cleanup task #916.

@@ -45,13 +48,18 @@ func Start() {
if err != nil {
log.Panicf("failed to build ChannelTransport: %v", err)
}
grpcListener, err := net.Listen("tcp", ":8089")
Copy link
Contributor

Choose a reason for hiding this comment

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

can we share tcp connections in grpc? If not, should we be exposing it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will comment more on this later, but this is re #866 and #897

@@ -102,6 +104,12 @@ func do() error {
return err
}
inbound = tchannelTransport.NewInbound()
case "grpc":
listener, err := net.Listen("tcp", "127.0.0.1:24038")
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need the 127.0.0.1? Not blocking, just curious

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a recommendation that Prashant had previously. I don't actually think it makes a difference, but I'm trying to do it for new connections I make.

@@ -159,6 +159,16 @@ type Service struct {
Methods []*Method
}

// FQSN returns a fully qualified service name of this service.
Copy link
Contributor

Choose a reason for hiding this comment

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

can we add that to the comment here? Just for clarity in the code when someone else comes along.

Copy link
Contributor

@willhug willhug left a comment

Choose a reason for hiding this comment

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

whoops, requesting changes

@bufdev
Copy link
Contributor Author

bufdev commented Apr 11, 2017

I've responded to all comments, and I've tried to make sure I have linked to current discussions and/or issues where I should, I hope this helps

caller, callerErr := getFromMetadata(md, callerHeader)
request.Caller = caller
encoding, encodingErr := getFromMetadata(md, encodingHeader)
request.Encoding = transport.Encoding(encoding)
Copy link
Contributor

Choose a reason for hiding this comment

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

does this cast work if the encoding is null/empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, the cast is fine regardless

Copy link
Contributor

@willhug willhug left a comment

Choose a reason for hiding this comment

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

That was a doozy, close enough

ocf4myu

return o.tracer
}

func defaultOnewayErrorHandler(err error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

shrug emoji

Copy link
Contributor

@HelloGrayson HelloGrayson left a comment

Choose a reason for hiding this comment

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

This is really exciting.

We'll want to follow up with Crossdock tests that verify:

  • a gRPC client can call a YARPC server
  • a YARPC client can call a gRPC server

environment:
- REDIS=enabled
- CHERAMI=enabled
- GRPC=enabled
Copy link
Contributor

Choose a reason for hiding this comment

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

I understand why Redis and Cherami need to be toggleable, but why GRPC?

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 just following the pattern, I will remove, also note #916

@@ -10,6 +10,10 @@ import:
version: ~0.4
- package: github.com/golang/mock
version: master
- package: github.com/grpc-ecosystem/grpc-opentracing
version: master
Copy link
Contributor

Choose a reason for hiding this comment

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

No semver here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

grpc-opentracing isn't doing releases unfortunately :( we need to evaluate grpc-opentracing more anyways before grpc can get out of the x/ package

}

// ProtobufTransport implements the 'protobuf' behavior for the given transport or behavior transport.
func ProtobufTransport(t crossdock.T, transport string) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not wild about the naming of this func... think you can introduce a verb in here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to ProtobufForTransport, also updated this for json/raw/thrift

@bufdev
Copy link
Contributor Author

bufdev commented Apr 12, 2017

@breerly ya I want to add those crossdock tests as well, also in one other non-common language if possible, filed #934

Copy link
Contributor

@HelloGrayson HelloGrayson left a comment

Choose a reason for hiding this comment

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

Great start - it's exciting to start iterating from here with the goal of getting gRPC and protobuf out of x/ and into peoples hands.

@bufdev bufdev merged commit 36f9f63 into dev Apr 18, 2017
@bufdev bufdev deleted the pgrpc branch April 18, 2017 23:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants