From a93fe5d6b4623155311407975bf55fdec25fe08f Mon Sep 17 00:00:00 2001 From: Can Guler Date: Mon, 3 Dec 2018 18:07:36 -0800 Subject: [PATCH 01/10] Deadliner service --- examples/deadline/client/client.go | 58 ++++++ examples/deadline/deadline/deadline.pb.go | 204 ++++++++++++++++++++++ examples/deadline/deadline/deadline.proto | 34 ++++ examples/deadline/server/server.go | 77 ++++++++ 4 files changed, 373 insertions(+) create mode 100644 examples/deadline/client/client.go create mode 100644 examples/deadline/deadline/deadline.pb.go create mode 100644 examples/deadline/deadline/deadline.proto create mode 100644 examples/deadline/server/server.go diff --git a/examples/deadline/client/client.go b/examples/deadline/client/client.go new file mode 100644 index 000000000000..417c7c3ff2ed --- /dev/null +++ b/examples/deadline/client/client.go @@ -0,0 +1,58 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "context" + "log" + "time" + + "google.golang.org/grpc" + pb "google.golang.org/grpc/examples/deadline/deadline" +) + +const ( + address = "localhost:50052" +) + +func makeRequest(c pb.DeadlinerClient, request *pb.DeadlinerRequest) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + r, err := c.MakeRequest(ctx, request) + if err != nil { + log.Printf("could not greet: %v", err) + return + } + log.Printf("Reply: %s", r.Message) +} + +func main() { + // Set up a connection to the server. + conn, err := grpc.Dial(address, grpc.WithInsecure()) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + c := pb.NewDeadlinerClient(conn) + + makeRequest(c, &pb.DeadlinerRequest{}) + makeRequest(c, &pb.DeadlinerRequest{Message: "delay"}) + makeRequest(c, &pb.DeadlinerRequest{Hops: 3}) + makeRequest(c, &pb.DeadlinerRequest{Hops: 4}) +} diff --git a/examples/deadline/deadline/deadline.pb.go b/examples/deadline/deadline/deadline.pb.go new file mode 100644 index 000000000000..ded94f34f2cf --- /dev/null +++ b/examples/deadline/deadline/deadline.pb.go @@ -0,0 +1,204 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: deadline.proto + +package deadline + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// The request message +type DeadlinerRequest struct { + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Hops uint32 `protobuf:"varint,2,opt,name=hops,proto3" json:"hops,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeadlinerRequest) Reset() { *m = DeadlinerRequest{} } +func (m *DeadlinerRequest) String() string { return proto.CompactTextString(m) } +func (*DeadlinerRequest) ProtoMessage() {} +func (*DeadlinerRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_deadline_578d33b6dbdb6ddb, []int{0} +} +func (m *DeadlinerRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeadlinerRequest.Unmarshal(m, b) +} +func (m *DeadlinerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeadlinerRequest.Marshal(b, m, deterministic) +} +func (dst *DeadlinerRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeadlinerRequest.Merge(dst, src) +} +func (m *DeadlinerRequest) XXX_Size() int { + return xxx_messageInfo_DeadlinerRequest.Size(m) +} +func (m *DeadlinerRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeadlinerRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeadlinerRequest proto.InternalMessageInfo + +func (m *DeadlinerRequest) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func (m *DeadlinerRequest) GetHops() uint32 { + if m != nil { + return m.Hops + } + return 0 +} + +// The response message +type DeadlinerReply struct { + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeadlinerReply) Reset() { *m = DeadlinerReply{} } +func (m *DeadlinerReply) String() string { return proto.CompactTextString(m) } +func (*DeadlinerReply) ProtoMessage() {} +func (*DeadlinerReply) Descriptor() ([]byte, []int) { + return fileDescriptor_deadline_578d33b6dbdb6ddb, []int{1} +} +func (m *DeadlinerReply) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeadlinerReply.Unmarshal(m, b) +} +func (m *DeadlinerReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeadlinerReply.Marshal(b, m, deterministic) +} +func (dst *DeadlinerReply) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeadlinerReply.Merge(dst, src) +} +func (m *DeadlinerReply) XXX_Size() int { + return xxx_messageInfo_DeadlinerReply.Size(m) +} +func (m *DeadlinerReply) XXX_DiscardUnknown() { + xxx_messageInfo_DeadlinerReply.DiscardUnknown(m) +} + +var xxx_messageInfo_DeadlinerReply proto.InternalMessageInfo + +func (m *DeadlinerReply) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func init() { + proto.RegisterType((*DeadlinerRequest)(nil), "deadline.DeadlinerRequest") + proto.RegisterType((*DeadlinerReply)(nil), "deadline.DeadlinerReply") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// DeadlinerClient is the client API for Deadliner service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type DeadlinerClient interface { + // Sends a greeting + MakeRequest(ctx context.Context, in *DeadlinerRequest, opts ...grpc.CallOption) (*DeadlinerReply, error) +} + +type deadlinerClient struct { + cc *grpc.ClientConn +} + +func NewDeadlinerClient(cc *grpc.ClientConn) DeadlinerClient { + return &deadlinerClient{cc} +} + +func (c *deadlinerClient) MakeRequest(ctx context.Context, in *DeadlinerRequest, opts ...grpc.CallOption) (*DeadlinerReply, error) { + out := new(DeadlinerReply) + err := c.cc.Invoke(ctx, "/deadline.Deadliner/MakeRequest", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DeadlinerServer is the server API for Deadliner service. +type DeadlinerServer interface { + // Sends a greeting + MakeRequest(context.Context, *DeadlinerRequest) (*DeadlinerReply, error) +} + +func RegisterDeadlinerServer(s *grpc.Server, srv DeadlinerServer) { + s.RegisterService(&_Deadliner_serviceDesc, srv) +} + +func _Deadliner_MakeRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeadlinerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DeadlinerServer).MakeRequest(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/deadline.Deadliner/MakeRequest", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DeadlinerServer).MakeRequest(ctx, req.(*DeadlinerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Deadliner_serviceDesc = grpc.ServiceDesc{ + ServiceName: "deadline.Deadliner", + HandlerType: (*DeadlinerServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "MakeRequest", + Handler: _Deadliner_MakeRequest_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "deadline.proto", +} + +func init() { proto.RegisterFile("deadline.proto", fileDescriptor_deadline_578d33b6dbdb6ddb) } + +var fileDescriptor_deadline_578d33b6dbdb6ddb = []byte{ + // 144 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0x49, 0x4d, 0x4c, + 0xc9, 0xc9, 0xcc, 0x4b, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x80, 0xf1, 0x95, 0x1c, + 0xb8, 0x04, 0x5c, 0xa0, 0xec, 0xa2, 0xa0, 0xd4, 0xc2, 0xd2, 0xd4, 0xe2, 0x12, 0x21, 0x09, 0x2e, + 0xf6, 0xdc, 0xd4, 0xe2, 0xe2, 0xc4, 0xf4, 0x54, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20, 0x18, + 0x57, 0x48, 0x88, 0x8b, 0x25, 0x23, 0xbf, 0xa0, 0x58, 0x82, 0x49, 0x81, 0x51, 0x83, 0x37, 0x08, + 0xcc, 0x56, 0xd2, 0xe2, 0xe2, 0x43, 0x32, 0xa1, 0x20, 0xa7, 0x12, 0xb7, 0x7e, 0xa3, 0x20, 0x2e, + 0x4e, 0xb8, 0x5a, 0x21, 0x57, 0x2e, 0x6e, 0xdf, 0xc4, 0xec, 0x54, 0x98, 0xad, 0x52, 0x7a, 0x70, + 0x47, 0xa2, 0xbb, 0x48, 0x4a, 0x02, 0xab, 0x5c, 0x41, 0x4e, 0xa5, 0x12, 0x43, 0x12, 0x1b, 0xd8, + 0x4b, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xee, 0x18, 0xcc, 0x16, 0xe4, 0x00, 0x00, 0x00, +} diff --git a/examples/deadline/deadline/deadline.proto b/examples/deadline/deadline/deadline.proto new file mode 100644 index 000000000000..2b72761d7cf5 --- /dev/null +++ b/examples/deadline/deadline/deadline.proto @@ -0,0 +1,34 @@ +// Copyright 2018 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package deadline; + +// The deadliner service definition. +service Deadliner { + // Sends a greeting + rpc MakeRequest (DeadlinerRequest) returns (DeadlinerReply) {} +} + +// The request message +message DeadlinerRequest { + string message = 1; + uint32 hops = 2; +} + +// The response message +message DeadlinerReply { + string message = 1; +} diff --git a/examples/deadline/server/server.go b/examples/deadline/server/server.go new file mode 100644 index 000000000000..5ae6aa05aa86 --- /dev/null +++ b/examples/deadline/server/server.go @@ -0,0 +1,77 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "context" + "log" + "net" + "time" + + "google.golang.org/grpc" + pb "google.golang.org/grpc/examples/deadline/deadline" +) + +const ( + address = "localhost:50052" +) +const ( + port = ":50052" +) + +type server struct{} + +// SayHello implements helloworld.GreeterServer +func (s *server) MakeRequest(ctx context.Context, in *pb.DeadlinerRequest) (*pb.DeadlinerReply, error) { + if in.Hops > 0 { + conn, err := grpc.Dial(address, grpc.WithInsecure()) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + c := pb.NewDeadlinerClient(conn) + + in.Hops-- + time.Sleep(300 * time.Millisecond) + r, err := c.MakeRequest(ctx, in) + if err != nil { + log.Printf("could not greet: %v", err) + return nil, err + } + return r, nil + } + + if in.Message == "delay" { + time.Sleep(2 * time.Second) + } + + return &pb.DeadlinerReply{Message: "pong "}, nil +} + +func main() { + lis, err := net.Listen("tcp", port) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterDeadlinerServer(s, &server{}) + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} From 6cb1dd44c909b257b7b926e7ce0e350508817f53 Mon Sep 17 00:00:00 2001 From: Can Guler Date: Tue, 4 Dec 2018 11:01:55 -0800 Subject: [PATCH 02/10] Works. --- examples/deadline/client/client.go | 35 +++++++++---------- examples/deadline/clientmain/main.go | 35 +++++++++++++++++++ .../deadline/{server => servermain}/server.go | 27 ++++---------- 3 files changed, 58 insertions(+), 39 deletions(-) create mode 100644 examples/deadline/clientmain/main.go rename examples/deadline/{server => servermain}/server.go (72%) diff --git a/examples/deadline/client/client.go b/examples/deadline/client/client.go index 417c7c3ff2ed..214deb543f89 100644 --- a/examples/deadline/client/client.go +++ b/examples/deadline/client/client.go @@ -16,7 +16,7 @@ * */ -package main +package client import ( "context" @@ -31,28 +31,27 @@ const ( address = "localhost:50052" ) -func makeRequest(c pb.DeadlinerClient, request *pb.DeadlinerRequest) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - r, err := c.MakeRequest(ctx, request) - if err != nil { - log.Printf("could not greet: %v", err) - return - } - log.Printf("Reply: %s", r.Message) -} - -func main() { - // Set up a connection to the server. +// ConnectAndRequest sets up a connection to the server, +// makes a request and returns, if successful, the reply. +func ConnectAndRequest(out *pb.DeadlinerRequest) (*pb.DeadlinerReply, error) { conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() + c := pb.NewDeadlinerClient(conn) - makeRequest(c, &pb.DeadlinerRequest{}) - makeRequest(c, &pb.DeadlinerRequest{Message: "delay"}) - makeRequest(c, &pb.DeadlinerRequest{Hops: 3}) - makeRequest(c, &pb.DeadlinerRequest{Hops: 4}) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + log.Println("# NEW REQUEST #") + log.Printf("Request: { %+v}", out) + r, err := c.MakeRequest(ctx, out) + if err != nil { + log.Printf("No reply: %v", err) + return nil, err + } + log.Printf("Reply: { %+v}", r) + return r, nil } diff --git a/examples/deadline/clientmain/main.go b/examples/deadline/clientmain/main.go new file mode 100644 index 000000000000..52cf5422fd54 --- /dev/null +++ b/examples/deadline/clientmain/main.go @@ -0,0 +1,35 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "google.golang.org/grpc/examples/deadline/client" + pb "google.golang.org/grpc/examples/deadline/deadline" +) + +func main() { + // A successful request + client.ConnectAndRequest(&pb.DeadlinerRequest{}) + // Exceeds deadline + client.ConnectAndRequest(&pb.DeadlinerRequest{Message: "delay"}) + // A successful request with propagated deadline + client.ConnectAndRequest(&pb.DeadlinerRequest{Hops: 3}) + // Exceeds propagated deadline + client.ConnectAndRequest(&pb.DeadlinerRequest{Hops: 4}) +} diff --git a/examples/deadline/server/server.go b/examples/deadline/servermain/server.go similarity index 72% rename from examples/deadline/server/server.go rename to examples/deadline/servermain/server.go index 5ae6aa05aa86..36302b06b691 100644 --- a/examples/deadline/server/server.go +++ b/examples/deadline/servermain/server.go @@ -24,44 +24,29 @@ import ( "net" "time" + "google.golang.org/grpc/examples/deadline/client" + "google.golang.org/grpc" pb "google.golang.org/grpc/examples/deadline/deadline" ) -const ( - address = "localhost:50052" -) -const ( - port = ":50052" -) +const port = ":50052" type server struct{} -// SayHello implements helloworld.GreeterServer +// MakeRequest implements deadline.DeadlinerServer func (s *server) MakeRequest(ctx context.Context, in *pb.DeadlinerRequest) (*pb.DeadlinerReply, error) { if in.Hops > 0 { - conn, err := grpc.Dial(address, grpc.WithInsecure()) - if err != nil { - log.Fatalf("did not connect: %v", err) - } - defer conn.Close() - c := pb.NewDeadlinerClient(conn) - in.Hops-- time.Sleep(300 * time.Millisecond) - r, err := c.MakeRequest(ctx, in) - if err != nil { - log.Printf("could not greet: %v", err) - return nil, err - } - return r, nil + return client.ConnectAndRequest(in) } if in.Message == "delay" { time.Sleep(2 * time.Second) } - return &pb.DeadlinerReply{Message: "pong "}, nil + return &pb.DeadlinerReply{Message: "pong"}, nil } func main() { From 4aa5ae24853e5851ac28a24a820bd11dc4de6a71 Mon Sep 17 00:00:00 2001 From: Can Guler Date: Tue, 4 Dec 2018 11:19:38 -0800 Subject: [PATCH 03/10] Uses helloworld.proto. --- examples/deadline/client/client.go | 16 +- examples/deadline/clientmain/main.go | 9 +- examples/deadline/deadline/deadline.pb.go | 204 ---------------------- examples/deadline/deadline/deadline.proto | 34 ---- examples/deadline/servermain/server.go | 22 +-- 5 files changed, 25 insertions(+), 260 deletions(-) delete mode 100644 examples/deadline/deadline/deadline.pb.go delete mode 100644 examples/deadline/deadline/deadline.proto diff --git a/examples/deadline/client/client.go b/examples/deadline/client/client.go index 214deb543f89..aafbe33ecb48 100644 --- a/examples/deadline/client/client.go +++ b/examples/deadline/client/client.go @@ -24,7 +24,7 @@ import ( "time" "google.golang.org/grpc" - pb "google.golang.org/grpc/examples/deadline/deadline" + pb "google.golang.org/grpc/examples/helloworld/helloworld" ) const ( @@ -33,25 +33,27 @@ const ( // ConnectAndRequest sets up a connection to the server, // makes a request and returns, if successful, the reply. -func ConnectAndRequest(out *pb.DeadlinerRequest) (*pb.DeadlinerReply, error) { +func ConnectAndRequest(name string) (*pb.HelloReply, error) { conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() - c := pb.NewDeadlinerClient(conn) + c := pb.NewGreeterClient(conn) ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() + req := &pb.HelloRequest{Name: name} + log.Println("# NEW REQUEST #") - log.Printf("Request: { %+v}", out) - r, err := c.MakeRequest(ctx, out) + log.Printf("Request: { %+v}", req) + rep, err := c.SayHello(ctx, req) if err != nil { log.Printf("No reply: %v", err) return nil, err } - log.Printf("Reply: { %+v}", r) - return r, nil + log.Printf("Reply: { %+v}", rep) + return rep, nil } diff --git a/examples/deadline/clientmain/main.go b/examples/deadline/clientmain/main.go index 52cf5422fd54..fdb32bcc7d95 100644 --- a/examples/deadline/clientmain/main.go +++ b/examples/deadline/clientmain/main.go @@ -20,16 +20,15 @@ package main import ( "google.golang.org/grpc/examples/deadline/client" - pb "google.golang.org/grpc/examples/deadline/deadline" ) func main() { // A successful request - client.ConnectAndRequest(&pb.DeadlinerRequest{}) + client.ConnectAndRequest("world") // Exceeds deadline - client.ConnectAndRequest(&pb.DeadlinerRequest{Message: "delay"}) + client.ConnectAndRequest("delay") // A successful request with propagated deadline - client.ConnectAndRequest(&pb.DeadlinerRequest{Hops: 3}) + client.ConnectAndRequest("[propagate me]world") // Exceeds propagated deadline - client.ConnectAndRequest(&pb.DeadlinerRequest{Hops: 4}) + client.ConnectAndRequest("[propagate me][propagate me]world") } diff --git a/examples/deadline/deadline/deadline.pb.go b/examples/deadline/deadline/deadline.pb.go deleted file mode 100644 index ded94f34f2cf..000000000000 --- a/examples/deadline/deadline/deadline.pb.go +++ /dev/null @@ -1,204 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: deadline.proto - -package deadline - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// The request message -type DeadlinerRequest struct { - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - Hops uint32 `protobuf:"varint,2,opt,name=hops,proto3" json:"hops,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DeadlinerRequest) Reset() { *m = DeadlinerRequest{} } -func (m *DeadlinerRequest) String() string { return proto.CompactTextString(m) } -func (*DeadlinerRequest) ProtoMessage() {} -func (*DeadlinerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_deadline_578d33b6dbdb6ddb, []int{0} -} -func (m *DeadlinerRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DeadlinerRequest.Unmarshal(m, b) -} -func (m *DeadlinerRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DeadlinerRequest.Marshal(b, m, deterministic) -} -func (dst *DeadlinerRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_DeadlinerRequest.Merge(dst, src) -} -func (m *DeadlinerRequest) XXX_Size() int { - return xxx_messageInfo_DeadlinerRequest.Size(m) -} -func (m *DeadlinerRequest) XXX_DiscardUnknown() { - xxx_messageInfo_DeadlinerRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_DeadlinerRequest proto.InternalMessageInfo - -func (m *DeadlinerRequest) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func (m *DeadlinerRequest) GetHops() uint32 { - if m != nil { - return m.Hops - } - return 0 -} - -// The response message -type DeadlinerReply struct { - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *DeadlinerReply) Reset() { *m = DeadlinerReply{} } -func (m *DeadlinerReply) String() string { return proto.CompactTextString(m) } -func (*DeadlinerReply) ProtoMessage() {} -func (*DeadlinerReply) Descriptor() ([]byte, []int) { - return fileDescriptor_deadline_578d33b6dbdb6ddb, []int{1} -} -func (m *DeadlinerReply) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_DeadlinerReply.Unmarshal(m, b) -} -func (m *DeadlinerReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_DeadlinerReply.Marshal(b, m, deterministic) -} -func (dst *DeadlinerReply) XXX_Merge(src proto.Message) { - xxx_messageInfo_DeadlinerReply.Merge(dst, src) -} -func (m *DeadlinerReply) XXX_Size() int { - return xxx_messageInfo_DeadlinerReply.Size(m) -} -func (m *DeadlinerReply) XXX_DiscardUnknown() { - xxx_messageInfo_DeadlinerReply.DiscardUnknown(m) -} - -var xxx_messageInfo_DeadlinerReply proto.InternalMessageInfo - -func (m *DeadlinerReply) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func init() { - proto.RegisterType((*DeadlinerRequest)(nil), "deadline.DeadlinerRequest") - proto.RegisterType((*DeadlinerReply)(nil), "deadline.DeadlinerReply") -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// DeadlinerClient is the client API for Deadliner service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type DeadlinerClient interface { - // Sends a greeting - MakeRequest(ctx context.Context, in *DeadlinerRequest, opts ...grpc.CallOption) (*DeadlinerReply, error) -} - -type deadlinerClient struct { - cc *grpc.ClientConn -} - -func NewDeadlinerClient(cc *grpc.ClientConn) DeadlinerClient { - return &deadlinerClient{cc} -} - -func (c *deadlinerClient) MakeRequest(ctx context.Context, in *DeadlinerRequest, opts ...grpc.CallOption) (*DeadlinerReply, error) { - out := new(DeadlinerReply) - err := c.cc.Invoke(ctx, "/deadline.Deadliner/MakeRequest", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// DeadlinerServer is the server API for Deadliner service. -type DeadlinerServer interface { - // Sends a greeting - MakeRequest(context.Context, *DeadlinerRequest) (*DeadlinerReply, error) -} - -func RegisterDeadlinerServer(s *grpc.Server, srv DeadlinerServer) { - s.RegisterService(&_Deadliner_serviceDesc, srv) -} - -func _Deadliner_MakeRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeadlinerRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DeadlinerServer).MakeRequest(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/deadline.Deadliner/MakeRequest", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DeadlinerServer).MakeRequest(ctx, req.(*DeadlinerRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Deadliner_serviceDesc = grpc.ServiceDesc{ - ServiceName: "deadline.Deadliner", - HandlerType: (*DeadlinerServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "MakeRequest", - Handler: _Deadliner_MakeRequest_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "deadline.proto", -} - -func init() { proto.RegisterFile("deadline.proto", fileDescriptor_deadline_578d33b6dbdb6ddb) } - -var fileDescriptor_deadline_578d33b6dbdb6ddb = []byte{ - // 144 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0x49, 0x4d, 0x4c, - 0xc9, 0xc9, 0xcc, 0x4b, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x80, 0xf1, 0x95, 0x1c, - 0xb8, 0x04, 0x5c, 0xa0, 0xec, 0xa2, 0xa0, 0xd4, 0xc2, 0xd2, 0xd4, 0xe2, 0x12, 0x21, 0x09, 0x2e, - 0xf6, 0xdc, 0xd4, 0xe2, 0xe2, 0xc4, 0xf4, 0x54, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20, 0x18, - 0x57, 0x48, 0x88, 0x8b, 0x25, 0x23, 0xbf, 0xa0, 0x58, 0x82, 0x49, 0x81, 0x51, 0x83, 0x37, 0x08, - 0xcc, 0x56, 0xd2, 0xe2, 0xe2, 0x43, 0x32, 0xa1, 0x20, 0xa7, 0x12, 0xb7, 0x7e, 0xa3, 0x20, 0x2e, - 0x4e, 0xb8, 0x5a, 0x21, 0x57, 0x2e, 0x6e, 0xdf, 0xc4, 0xec, 0x54, 0x98, 0xad, 0x52, 0x7a, 0x70, - 0x47, 0xa2, 0xbb, 0x48, 0x4a, 0x02, 0xab, 0x5c, 0x41, 0x4e, 0xa5, 0x12, 0x43, 0x12, 0x1b, 0xd8, - 0x4b, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xee, 0x18, 0xcc, 0x16, 0xe4, 0x00, 0x00, 0x00, -} diff --git a/examples/deadline/deadline/deadline.proto b/examples/deadline/deadline/deadline.proto deleted file mode 100644 index 2b72761d7cf5..000000000000 --- a/examples/deadline/deadline/deadline.proto +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -package deadline; - -// The deadliner service definition. -service Deadliner { - // Sends a greeting - rpc MakeRequest (DeadlinerRequest) returns (DeadlinerReply) {} -} - -// The request message -message DeadlinerRequest { - string message = 1; - uint32 hops = 2; -} - -// The response message -message DeadlinerReply { - string message = 1; -} diff --git a/examples/deadline/servermain/server.go b/examples/deadline/servermain/server.go index 36302b06b691..1a44af101791 100644 --- a/examples/deadline/servermain/server.go +++ b/examples/deadline/servermain/server.go @@ -22,12 +22,13 @@ import ( "context" "log" "net" + "strings" "time" "google.golang.org/grpc/examples/deadline/client" "google.golang.org/grpc" - pb "google.golang.org/grpc/examples/deadline/deadline" + pb "google.golang.org/grpc/examples/helloworld/helloworld" ) const port = ":50052" @@ -35,18 +36,19 @@ const port = ":50052" type server struct{} // MakeRequest implements deadline.DeadlinerServer -func (s *server) MakeRequest(ctx context.Context, in *pb.DeadlinerRequest) (*pb.DeadlinerReply, error) { - if in.Hops > 0 { - in.Hops-- - time.Sleep(300 * time.Millisecond) - return client.ConnectAndRequest(in) +func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { + name := in.Name + if strings.HasPrefix(name, "[propagate me]") { + time.Sleep(800 * time.Millisecond) + name = strings.TrimPrefix(name, "[propagate me]") + return client.ConnectAndRequest(name) } - if in.Message == "delay" { - time.Sleep(2 * time.Second) + if name == "delay" { + time.Sleep(1500 * time.Millisecond) } - return &pb.DeadlinerReply{Message: "pong"}, nil + return &pb.HelloReply{Message: "Hello " + name}, nil } func main() { @@ -55,7 +57,7 @@ func main() { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - pb.RegisterDeadlinerServer(s, &server{}) + pb.RegisterGreeterServer(s, &server{}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } From d3048383dc44e57d128f59b53a51fddfe8b3db06 Mon Sep 17 00:00:00 2001 From: Can Guler Date: Tue, 4 Dec 2018 11:39:22 -0800 Subject: [PATCH 04/10] Style fix --- examples/deadline/client/client.go | 6 +----- examples/deadline/servermain/server.go | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/examples/deadline/client/client.go b/examples/deadline/client/client.go index aafbe33ecb48..13c4298f217f 100644 --- a/examples/deadline/client/client.go +++ b/examples/deadline/client/client.go @@ -27,14 +27,10 @@ import ( pb "google.golang.org/grpc/examples/helloworld/helloworld" ) -const ( - address = "localhost:50052" -) - // ConnectAndRequest sets up a connection to the server, // makes a request and returns, if successful, the reply. func ConnectAndRequest(name string) (*pb.HelloReply, error) { - conn, err := grpc.Dial(address, grpc.WithInsecure()) + conn, err := grpc.Dial("localhost:50052", grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } diff --git a/examples/deadline/servermain/server.go b/examples/deadline/servermain/server.go index 1a44af101791..74cb63ead5c2 100644 --- a/examples/deadline/servermain/server.go +++ b/examples/deadline/servermain/server.go @@ -31,8 +31,6 @@ import ( pb "google.golang.org/grpc/examples/helloworld/helloworld" ) -const port = ":50052" - type server struct{} // MakeRequest implements deadline.DeadlinerServer @@ -52,7 +50,7 @@ func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloRe } func main() { - lis, err := net.Listen("tcp", port) + lis, err := net.Listen("tcp", ":50052") if err != nil { log.Fatalf("failed to listen: %v", err) } From 2cce673acbdce1b7f56ff4480783b3b52a29741c Mon Sep 17 00:00:00 2001 From: Can Guler Date: Tue, 4 Dec 2018 11:40:28 -0800 Subject: [PATCH 05/10] Comments --- examples/deadline/servermain/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/deadline/servermain/server.go b/examples/deadline/servermain/server.go index 74cb63ead5c2..0dfd4b092291 100644 --- a/examples/deadline/servermain/server.go +++ b/examples/deadline/servermain/server.go @@ -33,7 +33,7 @@ import ( type server struct{} -// MakeRequest implements deadline.DeadlinerServer +// SayHello implements helloworld.GreeterServer func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { name := in.Name if strings.HasPrefix(name, "[propagate me]") { From d6ccca5565d5b39e0c1c86de3aae41831a4783a8 Mon Sep 17 00:00:00 2001 From: Can Guler Date: Thu, 6 Dec 2018 15:42:58 -0800 Subject: [PATCH 06/10] Uses Echo service and adds streaming example. --- examples/deadline/client/client.go | 55 ---------- examples/deadline/clientmain/main.go | 34 ------ examples/deadline/servermain/server.go | 62 ----------- examples/features/deadline/client/main.go | 94 +++++++++++++++++ examples/features/deadline/server/main.go | 123 ++++++++++++++++++++++ 5 files changed, 217 insertions(+), 151 deletions(-) delete mode 100644 examples/deadline/client/client.go delete mode 100644 examples/deadline/clientmain/main.go delete mode 100644 examples/deadline/servermain/server.go create mode 100644 examples/features/deadline/client/main.go create mode 100644 examples/features/deadline/server/main.go diff --git a/examples/deadline/client/client.go b/examples/deadline/client/client.go deleted file mode 100644 index 13c4298f217f..000000000000 --- a/examples/deadline/client/client.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package client - -import ( - "context" - "log" - "time" - - "google.golang.org/grpc" - pb "google.golang.org/grpc/examples/helloworld/helloworld" -) - -// ConnectAndRequest sets up a connection to the server, -// makes a request and returns, if successful, the reply. -func ConnectAndRequest(name string) (*pb.HelloReply, error) { - conn, err := grpc.Dial("localhost:50052", grpc.WithInsecure()) - if err != nil { - log.Fatalf("did not connect: %v", err) - } - defer conn.Close() - - c := pb.NewGreeterClient(conn) - - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - - req := &pb.HelloRequest{Name: name} - - log.Println("# NEW REQUEST #") - log.Printf("Request: { %+v}", req) - rep, err := c.SayHello(ctx, req) - if err != nil { - log.Printf("No reply: %v", err) - return nil, err - } - log.Printf("Reply: { %+v}", rep) - return rep, nil -} diff --git a/examples/deadline/clientmain/main.go b/examples/deadline/clientmain/main.go deleted file mode 100644 index fdb32bcc7d95..000000000000 --- a/examples/deadline/clientmain/main.go +++ /dev/null @@ -1,34 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package main - -import ( - "google.golang.org/grpc/examples/deadline/client" -) - -func main() { - // A successful request - client.ConnectAndRequest("world") - // Exceeds deadline - client.ConnectAndRequest("delay") - // A successful request with propagated deadline - client.ConnectAndRequest("[propagate me]world") - // Exceeds propagated deadline - client.ConnectAndRequest("[propagate me][propagate me]world") -} diff --git a/examples/deadline/servermain/server.go b/examples/deadline/servermain/server.go deleted file mode 100644 index 0dfd4b092291..000000000000 --- a/examples/deadline/servermain/server.go +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package main - -import ( - "context" - "log" - "net" - "strings" - "time" - - "google.golang.org/grpc/examples/deadline/client" - - "google.golang.org/grpc" - pb "google.golang.org/grpc/examples/helloworld/helloworld" -) - -type server struct{} - -// SayHello implements helloworld.GreeterServer -func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { - name := in.Name - if strings.HasPrefix(name, "[propagate me]") { - time.Sleep(800 * time.Millisecond) - name = strings.TrimPrefix(name, "[propagate me]") - return client.ConnectAndRequest(name) - } - - if name == "delay" { - time.Sleep(1500 * time.Millisecond) - } - - return &pb.HelloReply{Message: "Hello " + name}, nil -} - -func main() { - lis, err := net.Listen("tcp", ":50052") - if err != nil { - log.Fatalf("failed to listen: %v", err) - } - s := grpc.NewServer() - pb.RegisterGreeterServer(s, &server{}) - if err := s.Serve(lis); err != nil { - log.Fatalf("failed to serve: %v", err) - } -} diff --git a/examples/features/deadline/client/main.go b/examples/features/deadline/client/main.go new file mode 100644 index 000000000000..863696212ce1 --- /dev/null +++ b/examples/features/deadline/client/main.go @@ -0,0 +1,94 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "context" + "log" + "time" + + "google.golang.org/grpc/status" + + "google.golang.org/grpc/codes" + pb "google.golang.org/grpc/examples/features/proto/echo" + + "google.golang.org/grpc" +) + +func unaryCall(c pb.EchoClient, requestID int, message string, want codes.Code) { + // Creates a context with a one second deadline for the RPC. + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + req := &pb.EchoRequest{Message: message} + + _, err := c.UnaryEcho(ctx, req) + got := status.Code(err) + if got != want { + log.Fatalf("[%v] wanted = %v, got = %v (error code)", requestID, want, got) + } +} + +func streamingCall(c pb.EchoClient, requestID int, message string, want codes.Code) { + // Creates a context with a one second deadline for the RPC. + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + stream, err := c.BidirectionalStreamingEcho(ctx) + if err != nil { + log.Printf("Stream err: %v", err) + return + } + + err = stream.Send(&pb.EchoRequest{Message: message}) + if err != nil { + log.Printf("Send error: %v", err) + return + } + + _, err = stream.Recv() + + got := status.Code(err) + if got != want { + log.Fatalf("[%v] wanted = %v, got = %v (error code)", requestID, want, got) + } +} + +func main() { + conn, err := grpc.Dial("localhost:50052", grpc.WithInsecure()) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + + c := pb.NewEchoClient(conn) + + // A successful request + unaryCall(c, 1, "world", codes.OK) + // Exceeds deadline + unaryCall(c, 2, "delay", codes.DeadlineExceeded) + // A successful request with propagated deadline + unaryCall(c, 3, "[propagate me]world", codes.OK) + // Exceeds propagated deadline + unaryCall(c, 4, "[propagate me][propagate me]world", codes.DeadlineExceeded) + // Receives a response from the stream successfully. + streamingCall(c, 5, "[propagate me]world", codes.OK) + // Exceeds propagated deadline before receiving a response + streamingCall(c, 6, "[propagate me][propagate me]world", codes.DeadlineExceeded) +} diff --git a/examples/features/deadline/server/main.go b/examples/features/deadline/server/main.go new file mode 100644 index 000000000000..868809c5c0c4 --- /dev/null +++ b/examples/features/deadline/server/main.go @@ -0,0 +1,123 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "context" + "io" + "log" + "net" + "strings" + "time" + + "google.golang.org/grpc" + pb "google.golang.org/grpc/examples/features/proto/echo" +) + +var c pb.EchoClient + +// server is used to implement EchoServer. +type server struct{} + +func (s *server) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { + message := req.Message + if strings.HasPrefix(message, "[propagate me]") { + time.Sleep(800 * time.Millisecond) + message = strings.TrimPrefix(message, "[propagate me]") + return c.UnaryEcho(ctx, &pb.EchoRequest{Message: message}) + } + + if message == "delay" { + time.Sleep(1500 * time.Millisecond) + } + + return &pb.EchoResponse{Message: req.Message}, nil +} + +func (s *server) ServerStreamingEcho(req *pb.EchoRequest, stream pb.Echo_ServerStreamingEchoServer) error { + for i := 0; i < 10; i++ { + if err := stream.Send(&pb.EchoResponse{Message: req.Message}); err != nil { + return err + } + } + return nil +} + +func (s *server) ClientStreamingEcho(stream pb.Echo_ClientStreamingEchoServer) error { + var lastMessage string + for { + req, err := stream.Recv() + if err == io.EOF { + return stream.SendAndClose(&pb.EchoResponse{Message: lastMessage}) + } + if err != nil { + return err + } + lastMessage = req.Message + } +} + +func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { + for { + req, err := stream.Recv() + if err == io.EOF { + return nil + } + if err != nil { + return err + } + + message := req.Message + if strings.HasPrefix(message, "[propagate me]") { + time.Sleep(800 * time.Millisecond) + message = strings.TrimPrefix(message, "[propagate me]") + res, err := c.UnaryEcho(stream.Context(), &pb.EchoRequest{Message: message}) + if err != nil { + return err + } + stream.Send(res) + } + + if message == "delay" { + time.Sleep(1500 * time.Millisecond) + } + stream.Send(&pb.EchoResponse{Message: message}) + } +} + +func main() { + lis, err := net.Listen("tcp", ":50052") + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + pb.RegisterEchoServer(s, &server{}) + + conn, err := grpc.Dial("localhost:50052", grpc.WithInsecure()) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + + c = pb.NewEchoClient(conn) + + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} From 02af476056c26e743b48e6ecebc87fdd3bd5c7ef Mon Sep 17 00:00:00 2001 From: Can Guler Date: Wed, 12 Dec 2018 12:37:41 -0800 Subject: [PATCH 07/10] Addresses the comments. --- examples/features/deadline/client/main.go | 23 ++++---- examples/features/deadline/server/main.go | 68 ++++++++++++----------- 2 files changed, 48 insertions(+), 43 deletions(-) diff --git a/examples/features/deadline/client/main.go b/examples/features/deadline/client/main.go index 863696212ce1..d19178cc2d29 100644 --- a/examples/features/deadline/client/main.go +++ b/examples/features/deadline/client/main.go @@ -16,19 +16,20 @@ * */ +// Binary client is an example client. package main import ( "context" + "flag" + "fmt" "log" "time" - "google.golang.org/grpc/status" - + "google.golang.org/grpc" "google.golang.org/grpc/codes" pb "google.golang.org/grpc/examples/features/proto/echo" - - "google.golang.org/grpc" + "google.golang.org/grpc/status" ) func unaryCall(c pb.EchoClient, requestID int, message string, want codes.Code) { @@ -40,9 +41,7 @@ func unaryCall(c pb.EchoClient, requestID int, message string, want codes.Code) _, err := c.UnaryEcho(ctx, req) got := status.Code(err) - if got != want { - log.Fatalf("[%v] wanted = %v, got = %v (error code)", requestID, want, got) - } + fmt.Printf("[%v] wanted = %v, got = %v\n", requestID, want, got) } func streamingCall(c pb.EchoClient, requestID int, message string, want codes.Code) { @@ -65,13 +64,15 @@ func streamingCall(c pb.EchoClient, requestID int, message string, want codes.Co _, err = stream.Recv() got := status.Code(err) - if got != want { - log.Fatalf("[%v] wanted = %v, got = %v (error code)", requestID, want, got) - } + fmt.Printf("[%v] wanted = %v, got = %v\n", requestID, want, got) } func main() { - conn, err := grpc.Dial("localhost:50052", grpc.WithInsecure()) + port := flag.Int("port", 50052, "port number") + flag.Parse() + + target := fmt.Sprintf("localhost:%v", *port) + conn, err := grpc.Dial(target, grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } diff --git a/examples/features/deadline/server/main.go b/examples/features/deadline/server/main.go index 868809c5c0c4..37dbdd71a0a6 100644 --- a/examples/features/deadline/server/main.go +++ b/examples/features/deadline/server/main.go @@ -16,10 +16,13 @@ * */ +// Binary server is an example server. package main import ( "context" + "flag" + "fmt" "io" "log" "net" @@ -27,20 +30,23 @@ import ( "time" "google.golang.org/grpc" + "google.golang.org/grpc/codes" pb "google.golang.org/grpc/examples/features/proto/echo" + "google.golang.org/grpc/status" ) -var c pb.EchoClient - // server is used to implement EchoServer. -type server struct{} +type server struct { + client pb.EchoClient + ccClose func() error +} func (s *server) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { message := req.Message if strings.HasPrefix(message, "[propagate me]") { time.Sleep(800 * time.Millisecond) message = strings.TrimPrefix(message, "[propagate me]") - return c.UnaryEcho(ctx, &pb.EchoRequest{Message: message}) + return s.client.UnaryEcho(ctx, &pb.EchoRequest{Message: message}) } if message == "delay" { @@ -51,26 +57,11 @@ func (s *server) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoRe } func (s *server) ServerStreamingEcho(req *pb.EchoRequest, stream pb.Echo_ServerStreamingEchoServer) error { - for i := 0; i < 10; i++ { - if err := stream.Send(&pb.EchoResponse{Message: req.Message}); err != nil { - return err - } - } - return nil + return status.Error(codes.Unimplemented, "RPC unimplemented") } func (s *server) ClientStreamingEcho(stream pb.Echo_ClientStreamingEchoServer) error { - var lastMessage string - for { - req, err := stream.Recv() - if err == io.EOF { - return stream.SendAndClose(&pb.EchoResponse{Message: lastMessage}) - } - if err != nil { - return err - } - lastMessage = req.Message - } + return status.Error(codes.Unimplemented, "RPC unimplemented") } func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { @@ -87,7 +78,7 @@ func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamin if strings.HasPrefix(message, "[propagate me]") { time.Sleep(800 * time.Millisecond) message = strings.TrimPrefix(message, "[propagate me]") - res, err := c.UnaryEcho(stream.Context(), &pb.EchoRequest{Message: message}) + res, err := s.client.UnaryEcho(stream.Context(), &pb.EchoRequest{Message: message}) if err != nil { return err } @@ -101,23 +92,36 @@ func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamin } } -func main() { - lis, err := net.Listen("tcp", ":50052") +func (s *server) Close() { + defer s.ccClose() +} + +func newEchoServer(port int) *server { + target := fmt.Sprintf("localhost:%v", port) + cc, err := grpc.Dial(target, grpc.WithInsecure()) if err != nil { - log.Fatalf("failed to listen: %v", err) + log.Fatalf("did not connect: %v", err) } - s := grpc.NewServer() - pb.RegisterEchoServer(s, &server{}) + return &server{client: pb.NewEchoClient(cc), ccClose: cc.Close} +} + +func main() { + port := flag.Int("port", 50052, "port number") + flag.Parse() - conn, err := grpc.Dial("localhost:50052", grpc.WithInsecure()) + address := fmt.Sprintf(":%v", *port) + lis, err := net.Listen("tcp", address) if err != nil { - log.Fatalf("did not connect: %v", err) + log.Fatalf("failed to listen: %v", err) } - defer conn.Close() - c = pb.NewEchoClient(conn) + echoServer := newEchoServer(*port) + defer echoServer.Close() + + grpcServer := grpc.NewServer() + pb.RegisterEchoServer(grpcServer, echoServer) - if err := s.Serve(lis); err != nil { + if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } From 65956ea824a3f6f21e0b2408ec3251bb76399d72 Mon Sep 17 00:00:00 2001 From: Can Guler Date: Wed, 12 Dec 2018 13:03:44 -0800 Subject: [PATCH 08/10] Adds an error. --- examples/features/deadline/server/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/features/deadline/server/main.go b/examples/features/deadline/server/main.go index 37dbdd71a0a6..23b1ceea3259 100644 --- a/examples/features/deadline/server/main.go +++ b/examples/features/deadline/server/main.go @@ -68,7 +68,7 @@ func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamin for { req, err := stream.Recv() if err == io.EOF { - return nil + return status.Error(codes.InvalidArgument, "request message not received") } if err != nil { return err From d935df3ce9ea2b28a529564fb28a6b7767ae6e35 Mon Sep 17 00:00:00 2001 From: Can Guler Date: Fri, 14 Dec 2018 12:55:13 -0800 Subject: [PATCH 09/10] Addresses PR comments. --- examples/features/deadline/server/main.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/features/deadline/server/main.go b/examples/features/deadline/server/main.go index 23b1ceea3259..e41489d27a37 100644 --- a/examples/features/deadline/server/main.go +++ b/examples/features/deadline/server/main.go @@ -35,10 +35,12 @@ import ( "google.golang.org/grpc/status" ) +var port = flag.Int("port", 50052, "port number") + // server is used to implement EchoServer. type server struct { - client pb.EchoClient - ccClose func() error + client pb.EchoClient + cc *grpc.ClientConn } func (s *server) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { @@ -93,7 +95,7 @@ func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamin } func (s *server) Close() { - defer s.ccClose() + s.cc.Close() } func newEchoServer(port int) *server { @@ -102,11 +104,10 @@ func newEchoServer(port int) *server { if err != nil { log.Fatalf("did not connect: %v", err) } - return &server{client: pb.NewEchoClient(cc), ccClose: cc.Close} + return &server{client: pb.NewEchoClient(cc), cc: cc} } func main() { - port := flag.Int("port", 50052, "port number") flag.Parse() address := fmt.Sprintf(":%v", *port) From 5dbf1890b4e18527f858c2125d087cf67142cad8 Mon Sep 17 00:00:00 2001 From: Can Guler Date: Fri, 14 Dec 2018 13:20:00 -0800 Subject: [PATCH 10/10] Removes port parameter from a function. --- examples/features/deadline/server/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/features/deadline/server/main.go b/examples/features/deadline/server/main.go index e41489d27a37..63044b542b5f 100644 --- a/examples/features/deadline/server/main.go +++ b/examples/features/deadline/server/main.go @@ -98,8 +98,8 @@ func (s *server) Close() { s.cc.Close() } -func newEchoServer(port int) *server { - target := fmt.Sprintf("localhost:%v", port) +func newEchoServer() *server { + target := fmt.Sprintf("localhost:%v", *port) cc, err := grpc.Dial(target, grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) @@ -116,7 +116,7 @@ func main() { log.Fatalf("failed to listen: %v", err) } - echoServer := newEchoServer(*port) + echoServer := newEchoServer() defer echoServer.Close() grpcServer := grpc.NewServer()