├── .travis.yml ├── CONTRIBUTING.md ├── Documentation ├── gomock-example.md ├── grpc-auth-support.md ├── grpc-metadata.md └── server-reflection-tutorial.md ├── LICENSE ├── Makefile ├── PATENTS ├── README.md ├── backoff.go ├── backoff_test.go ├── balancer.go ├── balancer_test.go ├── benchmark ├── benchmark.go ├── benchmark_test.go ├── client │ └── main.go ├── grpc_testing │ ├── control.pb.go │ ├── control.proto │ ├── messages.pb.go │ ├── messages.proto │ ├── payloads.pb.go │ ├── payloads.proto │ ├── services.pb.go │ ├── services.proto │ ├── stats.pb.go │ └── stats.proto ├── server │ ├── main.go │ └── testdata │ │ ├── ca.pem │ │ ├── server1.key │ │ └── server1.pem ├── stats │ ├── histogram.go │ ├── stats.go │ └── util.go └── worker │ ├── benchmark_client.go │ ├── benchmark_server.go │ ├── main.go │ └── util.go ├── call.go ├── call_test.go ├── clientconn.go ├── clientconn_test.go ├── codegen.sh ├── codes ├── code_string.go └── codes.go ├── coverage.sh ├── credentials ├── credentials.go ├── credentials_test.go ├── credentials_util_go17.go ├── credentials_util_go18.go ├── credentials_util_pre_go17.go └── oauth │ └── oauth.go ├── doc.go ├── examples ├── README.md ├── gotutorial.md ├── helloworld │ ├── greeter_client │ │ └── main.go │ ├── greeter_server │ │ └── main.go │ ├── helloworld │ │ ├── helloworld.pb.go │ │ └── helloworld.proto │ └── mock │ │ ├── hw_test.go │ │ └── mock_helloworld │ │ └── hw_mock.go └── route_guide │ ├── README.md │ ├── client │ └── client.go │ ├── routeguide │ ├── route_guide.pb.go │ └── route_guide.proto │ ├── server │ └── server.go │ └── testdata │ ├── ca.pem │ ├── route_guide_db.json │ ├── server1.key │ └── server1.pem ├── grpclb ├── grpc_lb_v1 │ ├── grpclb.pb.go │ └── grpclb.proto ├── grpclb.go └── grpclb_test.go ├── grpclog ├── glogger │ └── glogger.go └── logger.go ├── health ├── grpc_health_v1 │ ├── health.pb.go │ └── health.proto └── health.go ├── interceptor.go ├── internal └── internal.go ├── interop ├── client │ ├── client.go │ └── testdata │ │ ├── ca.pem │ │ ├── server1.key │ │ └── server1.pem ├── grpc_testing │ ├── test.pb.go │ └── test.proto ├── http2 │ └── negative_http2_client.go ├── server │ ├── server.go │ └── testdata │ │ ├── ca.pem │ │ ├── server1.key │ │ └── server1.pem └── test_utils.go ├── metadata ├── metadata.go └── metadata_test.go ├── naming └── naming.go ├── peer └── peer.go ├── reflection ├── README.md ├── grpc_reflection_v1alpha │ ├── reflection.pb.go │ └── reflection.proto ├── grpc_testing │ ├── proto2.pb.go │ ├── proto2.proto │ ├── proto2_ext.pb.go │ ├── proto2_ext.proto │ ├── proto2_ext2.pb.go │ ├── proto2_ext2.proto │ ├── test.pb.go │ └── test.proto ├── serverreflection.go └── serverreflection_test.go ├── rpc_util.go ├── rpc_util_test.go ├── server.go ├── server_test.go ├── stats ├── grpc_testing │ ├── test.pb.go │ └── test.proto ├── handlers.go ├── stats.go └── stats_test.go ├── stream.go ├── stress ├── client │ ├── main.go │ └── testdata │ │ ├── ca.pem │ │ ├── server1.key │ │ └── server1.pem ├── grpc_testing │ ├── metrics.pb.go │ └── metrics.proto └── metrics_client │ └── main.go ├── tap └── tap.go ├── test ├── codec_perf │ ├── perf.pb.go │ └── perf.proto ├── end2end_test.go ├── grpc_testing │ ├── test.pb.go │ └── test.proto ├── race_test.go ├── servertester_test.go └── testdata │ ├── ca.pem │ ├── server1.key │ └── server1.pem ├── testdata ├── ca.pem ├── server1.key └── server1.pem ├── trace.go └── transport ├── control.go ├── go16.go ├── go17.go ├── handler_server.go ├── handler_server_test.go ├── http2_client.go ├── http2_server.go ├── http_util.go ├── http_util_test.go ├── pre_go16.go ├── testdata ├── ca.pem ├── server1.key └── server1.pem ├── transport.go └── transport_test.go /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.5.4 5 | - 1.6.3 6 | - 1.7 7 | - 1.8 8 | 9 | go_import_path: google.golang.org/grpc 10 | 11 | before_install: 12 | - if [[ $TRAVIS_GO_VERSION != 1.5* ]]; then go get github.com/golang/lint/golint; fi 13 | - go get -u golang.org/x/tools/cmd/goimports github.com/axw/gocov/gocov github.com/mattn/goveralls golang.org/x/tools/cmd/cover 14 | 15 | script: 16 | - '! gofmt -s -d -l . 2>&1 | read' 17 | - '! goimports -l . | read' 18 | - 'if [[ $TRAVIS_GO_VERSION != 1.5* ]]; then ! golint ./... | grep -vE "(_mock|_string|\.pb)\.go:"; fi' 19 | - '! go tool vet -all . 2>&1 | grep -vE "constant [0-9]+ not a string in call to Errorf" | grep -vF .pb.go:' # https://github.com/golang/protobuf/issues/214 20 | - make test testrace 21 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We definitely welcome patches and contribution to grpc! Here are some guidelines 4 | and information about how to do so. 5 | 6 | ## Sending patches 7 | 8 | ### Getting started 9 | 10 | 1. Check out the code: 11 | 12 | $ go get google.golang.org/grpc 13 | $ cd $GOPATH/src/google.golang.org/grpc 14 | 15 | 1. Create a fork of the grpc-go repository. 16 | 1. Add your fork as a remote: 17 | 18 | $ git remote add fork git@github.com:$YOURGITHUBUSERNAME/grpc-go.git 19 | 20 | 1. Make changes, commit them. 21 | 1. Run the test suite: 22 | 23 | $ make test 24 | 25 | 1. Push your changes to your fork: 26 | 27 | $ git push fork ... 28 | 29 | 1. Open a pull request. 30 | 31 | ## Legal requirements 32 | 33 | In order to protect both you and ourselves, you will need to sign the 34 | [Contributor License Agreement](https://cla.developers.google.com/clas). 35 | 36 | ## Filing Issues 37 | When filing an issue, make sure to answer these five questions: 38 | 39 | 1. What version of Go are you using (`go version`)? 40 | 2. What operating system and processor architecture are you using? 41 | 3. What did you do? 42 | 4. What did you expect to see? 43 | 5. What did you see instead? 44 | 45 | ### Contributing code 46 | Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file. 47 | -------------------------------------------------------------------------------- /Documentation/gomock-example.md: -------------------------------------------------------------------------------- 1 | # Mocking Service for gRPC 2 | 3 | [Example code](https://github.com/grpc/grpc-go/tree/master/examples/helloworld/mock) 4 | 5 | ## Why? 6 | 7 | To test client-side logic without the overhead of connecting to a real server. Mocking enables users to write light-weight unit tests to check functionalities on client-side without invoking RPC calls to a server. 8 | 9 | ## Idea: Mock the client stub that connects to the server. 10 | 11 | We use Gomock to mock the client interface (in the generated code) and programmatically set its methods to expect and return pre-determined values. This enables users to write tests around the client logic and use this mocked stub while making RPC calls. 12 | 13 | ## How to use Gomock? 14 | 15 | Documentation on Gomock can be found [here](https://github.com/golang/mock). 16 | A quick reading of the documentation should enable users to follow the code below. 17 | 18 | Consider a gRPC service based on following proto file: 19 | 20 | ```proto 21 | //helloworld.proto 22 | 23 | package helloworld; 24 | 25 | message HelloRequest { 26 | string name = 1; 27 | } 28 | 29 | message HelloReply { 30 | string name = 1; 31 | } 32 | 33 | service Greeter { 34 | rpc SayHello (HelloRequest) returns (HelloReply) {} 35 | } 36 | ``` 37 | 38 | The generated file helloworld.pb.go will have a client interface for each service defined in the proto file. This interface will have methods corresponding to each rpc inside that service. 39 | 40 | ```Go 41 | type GreeterClient interface { 42 | SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) 43 | } 44 | ``` 45 | 46 | The generated code also contains a struct that implements this interface. 47 | 48 | ```Go 49 | type greeterClient struct { 50 | cc *grpc.ClientConn 51 | } 52 | func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error){ 53 | // ... 54 | // gRPC specific code here 55 | // ... 56 | } 57 | ``` 58 | 59 | Along with this the generated code has a method to create an instance of this struct. 60 | ```Go 61 | func NewGreeterClient(cc *grpc.ClientConn) GreeterClient 62 | ``` 63 | 64 | The user code uses this function to create an instance of the struct greeterClient which then can be used to make rpc calls to the server. 65 | We will mock this interface GreeterClient and use an instance of that mock to make rpc calls. These calls instead of going to server will return pre-determined values. 66 | 67 | To create a mock we’ll use [mockgen](https://github.com/golang/mock#running-mockgen). 68 | From the directory ``` examples/helloworld/mock/ ``` run ``` mockgen google.golang.org/grpc/examples/helloworld/helloworld GreeterClient > mock_helloworld/hw_mock.go ``` 69 | 70 | Notice that in the above command we specify GreeterClient as the interface to be mocked. 71 | 72 | The user test code can import the package generated by mockgen along with library package gomock to write unit tests around client-side logic. 73 | ```Go 74 | import "github.com/golang/mock/gomock" 75 | import hwmock "google.golang.org/grpc/examples/helloworld/mock/mock_helloworld" 76 | ``` 77 | 78 | An instance of the mocked interface can be created as: 79 | ```Go 80 | mockGreeterClient := hwmock.NewMockGreeterClient(ctrl) 81 | ``` 82 | This mocked object can be programmed to expect calls to its methods and return pre-determined values. For instance, we can program mockGreeterClient to expect a call to its method SayHello and return a HelloReply with message “Mocked RPC”. 83 | 84 | ```Go 85 | mockGreeterClient.EXPECT().SayHello( 86 | gomock.Any(), // expect any value for first parameter 87 | gomock.Any(), // expect any value for second parameter 88 | ).Return(&helloworld.HelloReply{Message: “Mocked RPC”}, nil) 89 | ``` 90 | 91 | gomock.Any() indicates that the parameter can have any value or type. We can indicate specific values for built-in types with gomock.Eq(). 92 | However, if the test code needs to specify the parameter to have a proto message type, we can replace gomock.Any() with an instance of a struct that implements gomock.Matcher interface. 93 | 94 | ```Go 95 | type rpcMsg struct { 96 | msg proto.Message 97 | } 98 | 99 | func (r *rpcMsg) Matches(msg interface{}) bool { 100 | m, ok := msg.(proto.Message) 101 | if !ok { 102 | return false 103 | } 104 | return proto.Equal(m, r.msg) 105 | } 106 | 107 | func (r *rpcMsg) String() string { 108 | return fmt.Sprintf("is %s", r.msg) 109 | } 110 | 111 | ... 112 | 113 | req := &helloworld.HelloRequest{Name: "unit_test"} 114 | mockGreeterClient.EXPECT().SayHello( 115 | gomock.Any(), 116 | &rpcMsg{msg: req}, 117 | ).Return(&helloworld.HelloReply{Message: "Mocked Interface"}, nil) 118 | ``` 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /Documentation/grpc-auth-support.md: -------------------------------------------------------------------------------- 1 | # Authentication 2 | 3 | As outlined in the [gRPC authentication guide](http://www.grpc.io/docs/guides/auth.html) there are a number of different mechanisms for asserting identity between an client and server. We'll present some code-samples here demonstrating how to provide TLS support encryption and identity assertions as well as passing OAuth2 tokens to services that support it. 4 | 5 | # Enabling TLS on a gRPC client 6 | 7 | ```Go 8 | conn, err := grpc.Dial(serverAddr, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, ""))) 9 | ``` 10 | 11 | # Enabling TLS on a gRPC server 12 | 13 | ```Go 14 | creds, err := credentials.NewServerTLSFromFile(certFile, keyFile) 15 | if err != nil { 16 | log.Fatalf("Failed to generate credentials %v", err) 17 | } 18 | lis, err := net.Listen("tcp", ":0") 19 | server := grpc.NewServer(grpc.Creds(creds)) 20 | ... 21 | server.Serve(lis) 22 | ``` 23 | 24 | # Authenticating with Google 25 | 26 | ## Google Compute Engine (GCE) 27 | 28 | ```Go 29 | conn, err := grpc.Dial(serverAddr, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), grpc.WithPerRPCCredentials(oauth.NewComputeEngine())) 30 | ``` 31 | 32 | ## JWT 33 | 34 | ```Go 35 | jwtCreds, err := oauth.NewServiceAccountFromFile(*serviceAccountKeyFile, *oauthScope) 36 | if err != nil { 37 | log.Fatalf("Failed to create JWT credentials: %v", err) 38 | } 39 | conn, err := grpc.Dial(serverAddr, grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")), grpc.WithPerRPCCredentials(jwtCreds)) 40 | ``` 41 | 42 | -------------------------------------------------------------------------------- /Documentation/server-reflection-tutorial.md: -------------------------------------------------------------------------------- 1 | # gRPC Server Reflection Tutorial 2 | 3 | gRPC Server Reflection provides information about publicly-accessible gRPC 4 | services on a server, and assists clients at runtime to construct RPC 5 | requests and responses without precompiled service information. It is used by 6 | gRPC CLI, which can be used to introspect server protos and send/receive test 7 | RPCs. 8 | 9 | ## Enable Server Reflection 10 | 11 | gRPC-go Server Reflection is implemented in package [reflection](https://github.com/grpc/grpc-go/tree/master/reflection). To enable server reflection, you need to import this package and register reflection service on your gRPC server. 12 | 13 | For example, to enable server reflection in `example/helloworld`, we need to make the following changes: 14 | 15 | ```diff 16 | --- a/examples/helloworld/greeter_server/main.go 17 | +++ b/examples/helloworld/greeter_server/main.go 18 | @@ -40,6 +40,7 @@ import ( 19 | "golang.org/x/net/context" 20 | "google.golang.org/grpc" 21 | pb "google.golang.org/grpc/examples/helloworld/helloworld" 22 | + "google.golang.org/grpc/reflection" 23 | ) 24 | 25 | const ( 26 | @@ -61,6 +62,8 @@ func main() { 27 | } 28 | s := grpc.NewServer() 29 | pb.RegisterGreeterServer(s, &server{}) 30 | + // Register reflection service on gRPC server. 31 | + reflection.Register(s) 32 | if err := s.Serve(lis); err != nil { 33 | log.Fatalf("failed to serve: %v", err) 34 | } 35 | ``` 36 | 37 | We have made this change in `example/helloworld`, and we will use it as an example to show the use of gRPC server reflection and gRPC CLI in this tutorial. 38 | 39 | ## gRPC CLI 40 | 41 | After enabling Server Reflection in a server application, you can use gRPC CLI to check its services. 42 | gRPC CLI is only available in c++. Instructions on how to use gRPC CLI can be found at [command_line_tool.md](https://github.com/grpc/grpc/blob/master/doc/command_line_tool.md). 43 | 44 | To build gRPC CLI: 45 | 46 | ```sh 47 | git clone https://github.com/grpc/grpc 48 | cd grpc 49 | make grpc_cli 50 | cd bins/opt # grpc_cli is in directory bins/opt/ 51 | ``` 52 | 53 | ## Use gRPC CLI to check services 54 | 55 | First, start the helloworld server in grpc-go directory: 56 | 57 | ```sh 58 | $ cd 59 | $ go run examples/helloworld/greeter_server/main.go 60 | ``` 61 | 62 | Open a new terminal and make sure you are in the directory where grpc_cli lives: 63 | 64 | ```sh 65 | $ cd /bins/opt 66 | ``` 67 | 68 | ### List services 69 | 70 | `grpc_cli ls` command lists services and methods exposed at a given port: 71 | 72 | - List all the services exposed at a given port 73 | 74 | ```sh 75 | $ ./grpc_cli ls localhost:50051 76 | ``` 77 | 78 | output: 79 | ```sh 80 | helloworld.Greeter 81 | grpc.reflection.v1alpha.ServerReflection 82 | ``` 83 | 84 | - List one service with details 85 | 86 | `grpc_cli ls` command inspects a service given its full name (in the format of 87 | \.\). It can print information with a long listing format 88 | when `-l` flag is set. This flag can be used to get more details about a 89 | service. 90 | 91 | ```sh 92 | $ ./grpc_cli ls localhost:50051 helloworld.Greeter -l 93 | ``` 94 | 95 | output: 96 | ```sh 97 | filename: helloworld.proto 98 | package: helloworld; 99 | service Greeter { 100 | rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {} 101 | } 102 | 103 | ``` 104 | 105 | ### List methods 106 | 107 | - List one method with details 108 | 109 | `grpc_cli ls` command also inspects a method given its full name (in the 110 | format of \.\.\). 111 | 112 | ```sh 113 | $ ./grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l 114 | ``` 115 | 116 | output: 117 | ```sh 118 | rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {} 119 | ``` 120 | 121 | ### Inspect message types 122 | 123 | We can use`grpc_cli type` command to inspect request/response types given the 124 | full name of the type (in the format of \.\). 125 | 126 | - Get information about the request type 127 | 128 | ```sh 129 | $ ./grpc_cli type localhost:50051 helloworld.HelloRequest 130 | ``` 131 | 132 | output: 133 | ```sh 134 | message HelloRequest { 135 | optional string name = 1[json_name = "name"]; 136 | } 137 | ``` 138 | 139 | ### Call a remote method 140 | 141 | We can send RPCs to a server and get responses using `grpc_cli call` command. 142 | 143 | - Call a unary method 144 | 145 | ```sh 146 | $ ./grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'" 147 | ``` 148 | 149 | output: 150 | ```sh 151 | message: "Hello gRPC CLI" 152 | ``` 153 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014, Google Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Google Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: test testrace 2 | 3 | deps: 4 | go get -d -v google.golang.org/grpc/... 5 | 6 | updatedeps: 7 | go get -d -v -u -f google.golang.org/grpc/... 8 | 9 | testdeps: 10 | go get -d -v -t google.golang.org/grpc/... 11 | 12 | updatetestdeps: 13 | go get -d -v -t -u -f google.golang.org/grpc/... 14 | 15 | build: deps 16 | go build google.golang.org/grpc/... 17 | 18 | proto: 19 | @ if ! which protoc > /dev/null; then \ 20 | echo "error: protoc not installed" >&2; \ 21 | exit 1; \ 22 | fi 23 | go get -u -v github.com/golang/protobuf/protoc-gen-go 24 | # use $$dir as the root for all proto files in the same directory 25 | for dir in $$(git ls-files '*.proto' | xargs -n1 dirname | uniq); do \ 26 | protoc -I $$dir --go_out=plugins=grpc:$$dir $$dir/*.proto; \ 27 | done 28 | 29 | test: testdeps 30 | go test -v -cpu 1,4 google.golang.org/grpc/... 31 | 32 | testrace: testdeps 33 | go test -v -race -cpu 1,4 google.golang.org/grpc/... 34 | 35 | clean: 36 | go clean -i google.golang.org/grpc/... 37 | 38 | coverage: testdeps 39 | ./coverage.sh --coveralls 40 | 41 | .PHONY: \ 42 | all \ 43 | deps \ 44 | updatedeps \ 45 | testdeps \ 46 | updatetestdeps \ 47 | build \ 48 | proto \ 49 | test \ 50 | testrace \ 51 | clean \ 52 | coverage 53 | -------------------------------------------------------------------------------- /PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the gRPC project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of gRPC, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of gRPC. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of gRPC or any code incorporated within this 19 | implementation of gRPC constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of gRPC 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 源码注解 2 | 3 | 基于34384f34de585705f1a6783a158d2ec8af29f618 4 | 5 | 切换到note分支 6 | 建议使用ide的代码提示和跳转等功能阅读, 所以目录结构要正确 7 | 可以: 8 | ``` 9 | cd $GOPATH/google.golang.org/ 10 | git clone https://github.com/liangzhiyang/annotate-grpc-go.git 11 | mv annotate-grpc-go grpc 12 | ``` 13 | 如果 grpc 已经存在 14 | ``` 15 | cd $GOPATH/google.golang.org/grpc 16 | git remote add lzy https://github.com/liangzhiyang/annotate-grpc-go.git 17 | git fetch --all 18 | git checkout -b note lzy/note 19 | ``` 20 | 21 | ## 建议阅读顺序(细节不列) 22 | * grpc.Dial() //建立连接的过程 23 | ``` 24 | (cc *ClientConn) resetAddrConn 25 | (ac *addrConn) resetTransport 26 | (ac *addrConn) transportMonitor //单独的goroutine,管理transport 27 | transport.newHTTP2Client 28 | (t *http2Client) reader() //单独的goroutine,读取服务端的帧数据 29 | ``` 30 | 31 | * grpc.Invoke() //一次rpc请求的过程 32 | 33 | ``` 34 | (cc *ClientConn) getTransport 35 | (ac *addrConn) wait 36 | sendRequest() 37 | recvResponse() 38 | 39 | ``` 40 | 41 | 持续更新~~~~ 42 | 43 | 准备接下来列举几种情况说明client端遇到意外情况的代码执行流程(使用balancer) 44 | 45 | [grpc源码注解(golang)](http://blog.csdn.net/liangzhiyang/article/details/60963025) 46 | 47 | [grpc的dial正常执行流程](http://blog.csdn.net/liangzhiyang/article/details/61921764) 48 | 49 | [grpc服务异常情况的执行流程](http://blog.csdn.net/liangzhiyang/article/details/61921843) 50 | 51 | [grpc的invoke(一次请求)正常执行流程](http://blog.csdn.net/liangzhiyang/article/details/62230971) 52 | 53 | 54 | 55 | 56 | ## Golang gRPC实践:https://github.com/Jergoo/go-grpc-example 57 | 58 | ## 个人源码学习总结: 59 | 1、负载均衡https://segmentfault.com/a/1190000015231956 60 | 61 | 2、transport 62 | 63 | 2.1流控https://segmentfault.com/a/1190000015232494 64 | 65 | 2.2客户端 服务端https://segmentfault.com/a/1190000015237382?_ea=3846950 66 | -------------------------------------------------------------------------------- /backoff.go: -------------------------------------------------------------------------------- 1 | package grpc 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | ) 7 | 8 | // 这个是backoffStrategy 指 任何一个连接失败后,会一直重试,每次重试的间隔会增加,由此策略决定 9 | //默认是DefaultBackoffConfig, 根据重试次数的不同会从1s到120s递增,每次乘以1.6, 并且会增加一些抖动增加[-0.2,0.2]倍 10 | // DefaultBackoffConfig uses values specified for backoff in 11 | // https://github.com/grpc/grpc/blob/master/doc/connection-backoff.md. 12 | var ( 13 | DefaultBackoffConfig = BackoffConfig{ 14 | MaxDelay: 120 * time.Second, 15 | baseDelay: 1.0 * time.Second, 16 | factor: 1.6, 17 | jitter: 0.2, 18 | } 19 | ) 20 | // backoffStrategy defines the methodology for backing off after a grpc 21 | // connection failure. 22 | // 23 | // This is unexported until the gRPC project decides whether or not to allow 24 | // alternative backoff strategies. Once a decision is made, this type and its 25 | // method may be exported. 26 | //这是小写字母开头的,即未导出的,直到gRPC项目决定是否允许替代退避策略。 一旦做出决定,就可以导出该类型及其方法。 27 | type backoffStrategy interface { 28 | // backoff returns the amount of time to wait before the next retry given 29 | // the number of consecutive failures. 30 | //retries是连续失败的次数,返回 这次失败后下次重试等待的间隔 31 | backoff(retries int) time.Duration 32 | } 33 | 34 | // BackoffConfig defines the parameters for the default gRPC backoff strategy. 35 | type BackoffConfig struct { 36 | // MaxDelay is the upper bound of backoff delay. 37 | MaxDelay time.Duration 38 | 39 | // TODO(stevvooe): The following fields are not exported, as allowing 40 | // changes would violate the current gRPC specification for backoff. If 41 | // gRPC decides to allow more interesting backoff strategies, these fields 42 | // may be opened up in the future. 43 | 44 | // baseDelay is the amount of time to wait before retrying after the first 45 | // failure. 46 | baseDelay time.Duration 47 | 48 | // factor is applied to the backoff after each retry. 49 | //每次重试间隔都会乘以factor 递增 50 | factor float64 51 | 52 | // jitter provides a range to randomize backoff delays. 53 | //计算出间隔时间后,加上一些抖动时间,防止多个链接重试的时候都跑到一起 54 | jitter float64 55 | } 56 | 57 | func setDefaults(bc *BackoffConfig) { 58 | md := bc.MaxDelay 59 | *bc = DefaultBackoffConfig 60 | 61 | if md > 0 { 62 | bc.MaxDelay = md 63 | } 64 | } 65 | 66 | func (bc BackoffConfig) backoff(retries int) time.Duration { 67 | if retries == 0 { 68 | return bc.baseDelay//第一次重试的间隔是baseDelay 69 | } 70 | //计算公式backoff=baseDelay*pow(factor,retries) 71 | backoff, max := float64(bc.baseDelay), float64(bc.MaxDelay) 72 | for backoff < max && retries > 0 { 73 | backoff *= bc.factor 74 | retries-- 75 | } 76 | if backoff > max { 77 | backoff = max //重试的最大间隔是MaxDelay 78 | } 79 | // Randomize backoff delays so that if a cluster of requests start at 80 | // the same time, they won't operate in lockstep. 81 | backoff *= 1 + bc.jitter*(rand.Float64()*2-1) 82 | if backoff < 0 { 83 | return 0 84 | } 85 | return time.Duration(backoff) 86 | } 87 | -------------------------------------------------------------------------------- /backoff_test.go: -------------------------------------------------------------------------------- 1 | package grpc 2 | 3 | import "testing" 4 | 5 | func TestBackoffConfigDefaults(t *testing.T) { 6 | b := BackoffConfig{} 7 | setDefaults(&b) 8 | if b != DefaultBackoffConfig { 9 | t.Fatalf("expected BackoffConfig to pickup default parameters: %v != %v", b, DefaultBackoffConfig) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /benchmark/benchmark_test.go: -------------------------------------------------------------------------------- 1 | package benchmark 2 | 3 | import ( 4 | "os" 5 | "sync" 6 | "testing" 7 | "time" 8 | 9 | "golang.org/x/net/context" 10 | "google.golang.org/grpc" 11 | testpb "google.golang.org/grpc/benchmark/grpc_testing" 12 | "google.golang.org/grpc/benchmark/stats" 13 | "google.golang.org/grpc/grpclog" 14 | ) 15 | 16 | func runUnary(b *testing.B, maxConcurrentCalls int) { 17 | s := stats.AddStats(b, 38) 18 | b.StopTimer() 19 | target, stopper := StartServer(ServerInfo{Addr: "localhost:0", Type: "protobuf"}) 20 | defer stopper() 21 | conn := NewClientConn(target, grpc.WithInsecure()) 22 | tc := testpb.NewBenchmarkServiceClient(conn) 23 | 24 | // Warm up connection. 25 | for i := 0; i < 10; i++ { 26 | unaryCaller(tc) 27 | } 28 | ch := make(chan int, maxConcurrentCalls*4) 29 | var ( 30 | mu sync.Mutex 31 | wg sync.WaitGroup 32 | ) 33 | wg.Add(maxConcurrentCalls) 34 | 35 | // Distribute the b.N calls over maxConcurrentCalls workers. 36 | for i := 0; i < maxConcurrentCalls; i++ { 37 | go func() { 38 | for range ch { 39 | start := time.Now() 40 | unaryCaller(tc) 41 | elapse := time.Since(start) 42 | mu.Lock() 43 | s.Add(elapse) 44 | mu.Unlock() 45 | } 46 | wg.Done() 47 | }() 48 | } 49 | b.StartTimer() 50 | for i := 0; i < b.N; i++ { 51 | ch <- i 52 | } 53 | b.StopTimer() 54 | close(ch) 55 | wg.Wait() 56 | conn.Close() 57 | } 58 | 59 | func runStream(b *testing.B, maxConcurrentCalls int) { 60 | s := stats.AddStats(b, 38) 61 | b.StopTimer() 62 | target, stopper := StartServer(ServerInfo{Addr: "localhost:0", Type: "protobuf"}) 63 | defer stopper() 64 | conn := NewClientConn(target, grpc.WithInsecure()) 65 | tc := testpb.NewBenchmarkServiceClient(conn) 66 | 67 | // Warm up connection. 68 | stream, err := tc.StreamingCall(context.Background()) 69 | if err != nil { 70 | b.Fatalf("%v.StreamingCall(_) = _, %v", tc, err) 71 | } 72 | for i := 0; i < 10; i++ { 73 | streamCaller(stream) 74 | } 75 | 76 | ch := make(chan int, maxConcurrentCalls*4) 77 | var ( 78 | mu sync.Mutex 79 | wg sync.WaitGroup 80 | ) 81 | wg.Add(maxConcurrentCalls) 82 | 83 | // Distribute the b.N calls over maxConcurrentCalls workers. 84 | for i := 0; i < maxConcurrentCalls; i++ { 85 | go func() { 86 | stream, err := tc.StreamingCall(context.Background()) 87 | if err != nil { 88 | b.Fatalf("%v.StreamingCall(_) = _, %v", tc, err) 89 | } 90 | for range ch { 91 | start := time.Now() 92 | streamCaller(stream) 93 | elapse := time.Since(start) 94 | mu.Lock() 95 | s.Add(elapse) 96 | mu.Unlock() 97 | } 98 | wg.Done() 99 | }() 100 | } 101 | b.StartTimer() 102 | for i := 0; i < b.N; i++ { 103 | ch <- i 104 | } 105 | b.StopTimer() 106 | close(ch) 107 | wg.Wait() 108 | conn.Close() 109 | } 110 | func unaryCaller(client testpb.BenchmarkServiceClient) { 111 | if err := DoUnaryCall(client, 1, 1); err != nil { 112 | grpclog.Fatalf("DoUnaryCall failed: %v", err) 113 | } 114 | } 115 | 116 | func streamCaller(stream testpb.BenchmarkService_StreamingCallClient) { 117 | if err := DoStreamingRoundTrip(stream, 1, 1); err != nil { 118 | grpclog.Fatalf("DoStreamingRoundTrip failed: %v", err) 119 | } 120 | } 121 | 122 | func BenchmarkClientStreamc1(b *testing.B) { 123 | grpc.EnableTracing = true 124 | runStream(b, 1) 125 | } 126 | 127 | func BenchmarkClientStreamc8(b *testing.B) { 128 | grpc.EnableTracing = true 129 | runStream(b, 8) 130 | } 131 | 132 | func BenchmarkClientStreamc64(b *testing.B) { 133 | grpc.EnableTracing = true 134 | runStream(b, 64) 135 | } 136 | 137 | func BenchmarkClientStreamc512(b *testing.B) { 138 | grpc.EnableTracing = true 139 | runStream(b, 512) 140 | } 141 | func BenchmarkClientUnaryc1(b *testing.B) { 142 | grpc.EnableTracing = true 143 | runUnary(b, 1) 144 | } 145 | 146 | func BenchmarkClientUnaryc8(b *testing.B) { 147 | grpc.EnableTracing = true 148 | runUnary(b, 8) 149 | } 150 | 151 | func BenchmarkClientUnaryc64(b *testing.B) { 152 | grpc.EnableTracing = true 153 | runUnary(b, 64) 154 | } 155 | 156 | func BenchmarkClientUnaryc512(b *testing.B) { 157 | grpc.EnableTracing = true 158 | runUnary(b, 512) 159 | } 160 | 161 | func BenchmarkClientStreamNoTracec1(b *testing.B) { 162 | grpc.EnableTracing = false 163 | runStream(b, 1) 164 | } 165 | 166 | func BenchmarkClientStreamNoTracec8(b *testing.B) { 167 | grpc.EnableTracing = false 168 | runStream(b, 8) 169 | } 170 | 171 | func BenchmarkClientStreamNoTracec64(b *testing.B) { 172 | grpc.EnableTracing = false 173 | runStream(b, 64) 174 | } 175 | 176 | func BenchmarkClientStreamNoTracec512(b *testing.B) { 177 | grpc.EnableTracing = false 178 | runStream(b, 512) 179 | } 180 | func BenchmarkClientUnaryNoTracec1(b *testing.B) { 181 | grpc.EnableTracing = false 182 | runUnary(b, 1) 183 | } 184 | 185 | func BenchmarkClientUnaryNoTracec8(b *testing.B) { 186 | grpc.EnableTracing = false 187 | runUnary(b, 8) 188 | } 189 | 190 | func BenchmarkClientUnaryNoTracec64(b *testing.B) { 191 | grpc.EnableTracing = false 192 | runUnary(b, 64) 193 | } 194 | 195 | func BenchmarkClientUnaryNoTracec512(b *testing.B) { 196 | grpc.EnableTracing = false 197 | runUnary(b, 512) 198 | } 199 | 200 | func TestMain(m *testing.M) { 201 | os.Exit(stats.RunTestMain(m)) 202 | } 203 | -------------------------------------------------------------------------------- /benchmark/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "math" 6 | "net" 7 | "net/http" 8 | _ "net/http/pprof" 9 | "sync" 10 | "time" 11 | 12 | "golang.org/x/net/context" 13 | "google.golang.org/grpc" 14 | "google.golang.org/grpc/benchmark" 15 | testpb "google.golang.org/grpc/benchmark/grpc_testing" 16 | "google.golang.org/grpc/benchmark/stats" 17 | "google.golang.org/grpc/grpclog" 18 | ) 19 | 20 | var ( 21 | server = flag.String("server", "", "The server address") 22 | maxConcurrentRPCs = flag.Int("max_concurrent_rpcs", 1, "The max number of concurrent RPCs") 23 | duration = flag.Int("duration", math.MaxInt32, "The duration in seconds to run the benchmark client") 24 | trace = flag.Bool("trace", true, "Whether tracing is on") 25 | rpcType = flag.Int("rpc_type", 0, 26 | `Configure different client rpc type. Valid options are: 27 | 0 : unary call; 28 | 1 : streaming call.`) 29 | ) 30 | 31 | func unaryCaller(client testpb.BenchmarkServiceClient) { 32 | benchmark.DoUnaryCall(client, 1, 1) 33 | } 34 | 35 | func streamCaller(stream testpb.BenchmarkService_StreamingCallClient) { 36 | benchmark.DoStreamingRoundTrip(stream, 1, 1) 37 | } 38 | 39 | func buildConnection() (s *stats.Stats, conn *grpc.ClientConn, tc testpb.BenchmarkServiceClient) { 40 | s = stats.NewStats(256) 41 | conn = benchmark.NewClientConn(*server) 42 | tc = testpb.NewBenchmarkServiceClient(conn) 43 | return s, conn, tc 44 | } 45 | 46 | func closeLoopUnary() { 47 | s, conn, tc := buildConnection() 48 | 49 | for i := 0; i < 100; i++ { 50 | unaryCaller(tc) 51 | } 52 | ch := make(chan int, *maxConcurrentRPCs*4) 53 | var ( 54 | mu sync.Mutex 55 | wg sync.WaitGroup 56 | ) 57 | wg.Add(*maxConcurrentRPCs) 58 | 59 | for i := 0; i < *maxConcurrentRPCs; i++ { 60 | go func() { 61 | for range ch { 62 | start := time.Now() 63 | unaryCaller(tc) 64 | elapse := time.Since(start) 65 | mu.Lock() 66 | s.Add(elapse) 67 | mu.Unlock() 68 | } 69 | wg.Done() 70 | }() 71 | } 72 | // Stop the client when time is up. 73 | done := make(chan struct{}) 74 | go func() { 75 | <-time.After(time.Duration(*duration) * time.Second) 76 | close(done) 77 | }() 78 | ok := true 79 | for ok { 80 | select { 81 | case ch <- 0: 82 | case <-done: 83 | ok = false 84 | } 85 | } 86 | close(ch) 87 | wg.Wait() 88 | conn.Close() 89 | grpclog.Println(s.String()) 90 | 91 | } 92 | 93 | func closeLoopStream() { 94 | s, conn, tc := buildConnection() 95 | ch := make(chan int, *maxConcurrentRPCs*4) 96 | var ( 97 | mu sync.Mutex 98 | wg sync.WaitGroup 99 | ) 100 | wg.Add(*maxConcurrentRPCs) 101 | // Distribute RPCs over maxConcurrentCalls workers. 102 | for i := 0; i < *maxConcurrentRPCs; i++ { 103 | go func() { 104 | stream, err := tc.StreamingCall(context.Background()) 105 | if err != nil { 106 | grpclog.Fatalf("%v.StreamingCall(_) = _, %v", tc, err) 107 | } 108 | // Do some warm up. 109 | for i := 0; i < 100; i++ { 110 | streamCaller(stream) 111 | } 112 | for range ch { 113 | start := time.Now() 114 | streamCaller(stream) 115 | elapse := time.Since(start) 116 | mu.Lock() 117 | s.Add(elapse) 118 | mu.Unlock() 119 | } 120 | wg.Done() 121 | }() 122 | } 123 | // Stop the client when time is up. 124 | done := make(chan struct{}) 125 | go func() { 126 | <-time.After(time.Duration(*duration) * time.Second) 127 | close(done) 128 | }() 129 | ok := true 130 | for ok { 131 | select { 132 | case ch <- 0: 133 | case <-done: 134 | ok = false 135 | } 136 | } 137 | close(ch) 138 | wg.Wait() 139 | conn.Close() 140 | grpclog.Println(s.String()) 141 | } 142 | 143 | func main() { 144 | flag.Parse() 145 | grpc.EnableTracing = *trace 146 | go func() { 147 | lis, err := net.Listen("tcp", ":0") 148 | if err != nil { 149 | grpclog.Fatalf("Failed to listen: %v", err) 150 | } 151 | grpclog.Println("Client profiling address: ", lis.Addr().String()) 152 | if err := http.Serve(lis, nil); err != nil { 153 | grpclog.Fatalf("Failed to serve: %v", err) 154 | } 155 | }() 156 | switch *rpcType { 157 | case 0: 158 | closeLoopUnary() 159 | case 1: 160 | closeLoopStream() 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /benchmark/grpc_testing/payloads.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | syntax = "proto3"; 31 | 32 | package grpc.testing; 33 | 34 | message ByteBufferParams { 35 | int32 req_size = 1; 36 | int32 resp_size = 2; 37 | } 38 | 39 | message SimpleProtoParams { 40 | int32 req_size = 1; 41 | int32 resp_size = 2; 42 | } 43 | 44 | message ComplexProtoParams { 45 | // TODO (vpai): Fill this in once the details of complex, representative 46 | // protos are decided 47 | } 48 | 49 | message PayloadConfig { 50 | oneof payload { 51 | ByteBufferParams bytebuf_params = 1; 52 | SimpleProtoParams simple_params = 2; 53 | ComplexProtoParams complex_params = 3; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /benchmark/grpc_testing/services.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // An integration test service that covers all the method signature permutations 31 | // of unary/streaming requests/responses. 32 | syntax = "proto3"; 33 | 34 | import "messages.proto"; 35 | import "control.proto"; 36 | 37 | package grpc.testing; 38 | 39 | service BenchmarkService { 40 | // One request followed by one response. 41 | // The server returns the client payload as-is. 42 | rpc UnaryCall(SimpleRequest) returns (SimpleResponse); 43 | 44 | // One request followed by one response. 45 | // The server returns the client payload as-is. 46 | rpc StreamingCall(stream SimpleRequest) returns (stream SimpleResponse); 47 | } 48 | 49 | service WorkerService { 50 | // Start server with specified workload. 51 | // First request sent specifies the ServerConfig followed by ServerStatus 52 | // response. After that, a "Mark" can be sent anytime to request the latest 53 | // stats. Closing the stream will initiate shutdown of the test server 54 | // and once the shutdown has finished, the OK status is sent to terminate 55 | // this RPC. 56 | rpc RunServer(stream ServerArgs) returns (stream ServerStatus); 57 | 58 | // Start client with specified workload. 59 | // First request sent specifies the ClientConfig followed by ClientStatus 60 | // response. After that, a "Mark" can be sent anytime to request the latest 61 | // stats. Closing the stream will initiate shutdown of the test client 62 | // and once the shutdown has finished, the OK status is sent to terminate 63 | // this RPC. 64 | rpc RunClient(stream ClientArgs) returns (stream ClientStatus); 65 | 66 | // Just return the core count - unary call 67 | rpc CoreCount(CoreRequest) returns (CoreResponse); 68 | 69 | // Quit this worker 70 | rpc QuitWorker(Void) returns (Void); 71 | } 72 | -------------------------------------------------------------------------------- /benchmark/grpc_testing/stats.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2016, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | syntax = "proto3"; 31 | 32 | package grpc.testing; 33 | 34 | message ServerStats { 35 | // wall clock time change in seconds since last reset 36 | double time_elapsed = 1; 37 | 38 | // change in user time (in seconds) used by the server since last reset 39 | double time_user = 2; 40 | 41 | // change in server time (in seconds) used by the server process and all 42 | // threads since last reset 43 | double time_system = 3; 44 | } 45 | 46 | // Histogram params based on grpc/support/histogram.c 47 | message HistogramParams { 48 | double resolution = 1; // first bucket is [0, 1 + resolution) 49 | double max_possible = 2; // use enough buckets to allow this value 50 | } 51 | 52 | // Histogram data based on grpc/support/histogram.c 53 | message HistogramData { 54 | repeated uint32 bucket = 1; 55 | double min_seen = 2; 56 | double max_seen = 3; 57 | double sum = 4; 58 | double sum_of_squares = 5; 59 | double count = 6; 60 | } 61 | 62 | message ClientStats { 63 | // Latency histogram. Data points are in nanoseconds. 64 | HistogramData latencies = 1; 65 | 66 | // See ServerStats for details. 67 | double time_elapsed = 2; 68 | double time_user = 3; 69 | double time_system = 4; 70 | } 71 | -------------------------------------------------------------------------------- /benchmark/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "math" 6 | "net" 7 | "net/http" 8 | _ "net/http/pprof" 9 | "time" 10 | 11 | "google.golang.org/grpc/benchmark" 12 | "google.golang.org/grpc/grpclog" 13 | ) 14 | 15 | var ( 16 | duration = flag.Int("duration", math.MaxInt32, "The duration in seconds to run the benchmark server") 17 | ) 18 | 19 | func main() { 20 | flag.Parse() 21 | go func() { 22 | lis, err := net.Listen("tcp", ":0") 23 | if err != nil { 24 | grpclog.Fatalf("Failed to listen: %v", err) 25 | } 26 | grpclog.Println("Server profiling address: ", lis.Addr().String()) 27 | if err := http.Serve(lis, nil); err != nil { 28 | grpclog.Fatalf("Failed to serve: %v", err) 29 | } 30 | }() 31 | addr, stopper := benchmark.StartServer(benchmark.ServerInfo{Addr: ":0", Type: "protobuf"}) // listen on all interfaces 32 | grpclog.Println("Server Address: ", addr) 33 | <-time.After(time.Duration(*duration) * time.Second) 34 | stopper() 35 | } 36 | -------------------------------------------------------------------------------- /benchmark/server/testdata/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla 5 | Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 6 | YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT 7 | BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 8 | +L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu 9 | g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd 10 | Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV 11 | HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau 12 | sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m 13 | oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG 14 | Dfcog5wrJytaQ6UA0wE= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /benchmark/server/testdata/server1.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD 3 | M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf 4 | 3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY 5 | AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm 6 | V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY 7 | tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p 8 | dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q 9 | K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR 10 | 81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff 11 | DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd 12 | aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 13 | ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 14 | XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe 15 | F98XJ7tIFfJq 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /benchmark/server/testdata/server1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET 3 | MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ 4 | dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx 5 | MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV 6 | BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 7 | ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco 8 | LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg 9 | zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd 10 | 9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw 11 | CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy 12 | em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G 13 | CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 14 | hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh 15 | y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /benchmark/stats/stats.go: -------------------------------------------------------------------------------- 1 | package stats 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "math" 8 | "time" 9 | ) 10 | 11 | // Stats is a simple helper for gathering additional statistics like histogram 12 | // during benchmarks. This is not thread safe. 13 | type Stats struct { 14 | numBuckets int 15 | unit time.Duration 16 | min, max int64 17 | histogram *Histogram 18 | 19 | durations durationSlice 20 | dirty bool 21 | } 22 | 23 | type durationSlice []time.Duration 24 | 25 | // NewStats creates a new Stats instance. If numBuckets is not positive, 26 | // the default value (16) will be used. 27 | func NewStats(numBuckets int) *Stats { 28 | if numBuckets <= 0 { 29 | numBuckets = 16 30 | } 31 | return &Stats{ 32 | // Use one more bucket for the last unbounded bucket. 33 | numBuckets: numBuckets + 1, 34 | durations: make(durationSlice, 0, 100000), 35 | } 36 | } 37 | 38 | // Add adds an elapsed time per operation to the stats. 39 | func (stats *Stats) Add(d time.Duration) { 40 | stats.durations = append(stats.durations, d) 41 | stats.dirty = true 42 | } 43 | 44 | // Clear resets the stats, removing all values. 45 | func (stats *Stats) Clear() { 46 | stats.durations = stats.durations[:0] 47 | stats.histogram = nil 48 | stats.dirty = false 49 | } 50 | 51 | // maybeUpdate updates internal stat data if there was any newly added 52 | // stats since this was updated. 53 | func (stats *Stats) maybeUpdate() { 54 | if !stats.dirty { 55 | return 56 | } 57 | 58 | stats.min = math.MaxInt64 59 | stats.max = 0 60 | for _, d := range stats.durations { 61 | if stats.min > int64(d) { 62 | stats.min = int64(d) 63 | } 64 | if stats.max < int64(d) { 65 | stats.max = int64(d) 66 | } 67 | } 68 | 69 | // Use the largest unit that can represent the minimum time duration. 70 | stats.unit = time.Nanosecond 71 | for _, u := range []time.Duration{time.Microsecond, time.Millisecond, time.Second} { 72 | if stats.min <= int64(u) { 73 | break 74 | } 75 | stats.unit = u 76 | } 77 | 78 | // Adjust the min/max according to the new unit. 79 | stats.min /= int64(stats.unit) 80 | stats.max /= int64(stats.unit) 81 | numBuckets := stats.numBuckets 82 | if n := int(stats.max - stats.min + 1); n < numBuckets { 83 | numBuckets = n 84 | } 85 | stats.histogram = NewHistogram(HistogramOptions{ 86 | NumBuckets: numBuckets, 87 | // max-min(lower bound of last bucket) = (1 + growthFactor)^(numBuckets-2) * baseBucketSize. 88 | GrowthFactor: math.Pow(float64(stats.max-stats.min), 1/float64(numBuckets-2)) - 1, 89 | BaseBucketSize: 1.0, 90 | MinValue: stats.min}) 91 | 92 | for _, d := range stats.durations { 93 | stats.histogram.Add(int64(d / stats.unit)) 94 | } 95 | 96 | stats.dirty = false 97 | } 98 | 99 | // Print writes textual output of the Stats. 100 | func (stats *Stats) Print(w io.Writer) { 101 | stats.maybeUpdate() 102 | 103 | if stats.histogram == nil { 104 | fmt.Fprint(w, "Histogram (empty)\n") 105 | } else { 106 | fmt.Fprintf(w, "Histogram (unit: %s)\n", fmt.Sprintf("%v", stats.unit)[1:]) 107 | stats.histogram.Print(w) 108 | } 109 | } 110 | 111 | // String returns the textual output of the Stats as string. 112 | func (stats *Stats) String() string { 113 | var b bytes.Buffer 114 | stats.Print(&b) 115 | return b.String() 116 | } 117 | -------------------------------------------------------------------------------- /benchmark/stats/util.go: -------------------------------------------------------------------------------- 1 | package stats 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "fmt" 7 | "os" 8 | "runtime" 9 | "sort" 10 | "strings" 11 | "sync" 12 | "testing" 13 | ) 14 | 15 | var ( 16 | curB *testing.B 17 | curBenchName string 18 | curStats map[string]*Stats 19 | 20 | orgStdout *os.File 21 | nextOutPos int 22 | 23 | injectCond *sync.Cond 24 | injectDone chan struct{} 25 | ) 26 | 27 | // AddStats adds a new unnamed Stats instance to the current benchmark. You need 28 | // to run benchmarks by calling RunTestMain() to inject the stats to the 29 | // benchmark results. If numBuckets is not positive, the default value (16) will 30 | // be used. Please note that this calls b.ResetTimer() since it may be blocked 31 | // until the previous benchmark stats is printed out. So AddStats() should 32 | // typically be called at the very beginning of each benchmark function. 33 | func AddStats(b *testing.B, numBuckets int) *Stats { 34 | return AddStatsWithName(b, "", numBuckets) 35 | } 36 | 37 | // AddStatsWithName adds a new named Stats instance to the current benchmark. 38 | // With this, you can add multiple stats in a single benchmark. You need 39 | // to run benchmarks by calling RunTestMain() to inject the stats to the 40 | // benchmark results. If numBuckets is not positive, the default value (16) will 41 | // be used. Please note that this calls b.ResetTimer() since it may be blocked 42 | // until the previous benchmark stats is printed out. So AddStatsWithName() 43 | // should typically be called at the very beginning of each benchmark function. 44 | func AddStatsWithName(b *testing.B, name string, numBuckets int) *Stats { 45 | var benchName string 46 | for i := 1; ; i++ { 47 | pc, _, _, ok := runtime.Caller(i) 48 | if !ok { 49 | panic("benchmark function not found") 50 | } 51 | p := strings.Split(runtime.FuncForPC(pc).Name(), ".") 52 | benchName = p[len(p)-1] 53 | if strings.HasPrefix(benchName, "Benchmark") { 54 | break 55 | } 56 | } 57 | procs := runtime.GOMAXPROCS(-1) 58 | if procs != 1 { 59 | benchName = fmt.Sprintf("%s-%d", benchName, procs) 60 | } 61 | 62 | stats := NewStats(numBuckets) 63 | 64 | if injectCond != nil { 65 | // We need to wait until the previous benchmark stats is printed out. 66 | injectCond.L.Lock() 67 | for curB != nil && curBenchName != benchName { 68 | injectCond.Wait() 69 | } 70 | 71 | curB = b 72 | curBenchName = benchName 73 | curStats[name] = stats 74 | 75 | injectCond.L.Unlock() 76 | } 77 | 78 | b.ResetTimer() 79 | return stats 80 | } 81 | 82 | // RunTestMain runs the tests with enabling injection of benchmark stats. It 83 | // returns an exit code to pass to os.Exit. 84 | func RunTestMain(m *testing.M) int { 85 | startStatsInjector() 86 | defer stopStatsInjector() 87 | return m.Run() 88 | } 89 | 90 | // startStatsInjector starts stats injection to benchmark results. 91 | func startStatsInjector() { 92 | orgStdout = os.Stdout 93 | r, w, _ := os.Pipe() 94 | os.Stdout = w 95 | nextOutPos = 0 96 | 97 | resetCurBenchStats() 98 | 99 | injectCond = sync.NewCond(&sync.Mutex{}) 100 | injectDone = make(chan struct{}) 101 | go func() { 102 | defer close(injectDone) 103 | 104 | scanner := bufio.NewScanner(r) 105 | scanner.Split(splitLines) 106 | for scanner.Scan() { 107 | injectStatsIfFinished(scanner.Text()) 108 | } 109 | if err := scanner.Err(); err != nil { 110 | panic(err) 111 | } 112 | }() 113 | } 114 | 115 | // stopStatsInjector stops stats injection and restores os.Stdout. 116 | func stopStatsInjector() { 117 | os.Stdout.Close() 118 | <-injectDone 119 | injectCond = nil 120 | os.Stdout = orgStdout 121 | } 122 | 123 | // splitLines is a split function for a bufio.Scanner that returns each line 124 | // of text, teeing texts to the original stdout even before each line ends. 125 | func splitLines(data []byte, eof bool) (advance int, token []byte, err error) { 126 | if eof && len(data) == 0 { 127 | return 0, nil, nil 128 | } 129 | 130 | if i := bytes.IndexByte(data, '\n'); i >= 0 { 131 | orgStdout.Write(data[nextOutPos : i+1]) 132 | nextOutPos = 0 133 | return i + 1, data[0:i], nil 134 | } 135 | 136 | orgStdout.Write(data[nextOutPos:]) 137 | nextOutPos = len(data) 138 | 139 | if eof { 140 | // This is a final, non-terminated line. Return it. 141 | return len(data), data, nil 142 | } 143 | 144 | return 0, nil, nil 145 | } 146 | 147 | // injectStatsIfFinished prints out the stats if the current benchmark finishes. 148 | func injectStatsIfFinished(line string) { 149 | injectCond.L.Lock() 150 | defer injectCond.L.Unlock() 151 | 152 | // We assume that the benchmark results start with the benchmark name. 153 | if curB == nil || !strings.HasPrefix(line, curBenchName) { 154 | return 155 | } 156 | 157 | if !curB.Failed() { 158 | // Output all stats in alphabetical order. 159 | names := make([]string, 0, len(curStats)) 160 | for name := range curStats { 161 | names = append(names, name) 162 | } 163 | sort.Strings(names) 164 | for _, name := range names { 165 | stats := curStats[name] 166 | // The output of stats starts with a header like "Histogram (unit: ms)" 167 | // followed by statistical properties and the buckets. Add the stats name 168 | // if it is a named stats and indent them as Go testing outputs. 169 | lines := strings.Split(stats.String(), "\n") 170 | if n := len(lines); n > 0 { 171 | if name != "" { 172 | name = ": " + name 173 | } 174 | fmt.Fprintf(orgStdout, "--- %s%s\n", lines[0], name) 175 | for _, line := range lines[1 : n-1] { 176 | fmt.Fprintf(orgStdout, "\t%s\n", line) 177 | } 178 | } 179 | } 180 | } 181 | 182 | resetCurBenchStats() 183 | injectCond.Signal() 184 | } 185 | 186 | // resetCurBenchStats resets the current benchmark stats. 187 | func resetCurBenchStats() { 188 | curB = nil 189 | curBenchName = "" 190 | curStats = make(map[string]*Stats) 191 | } 192 | -------------------------------------------------------------------------------- /benchmark/worker/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | * 31 | */ 32 | 33 | package main 34 | 35 | import ( 36 | "log" 37 | "os" 38 | "path/filepath" 39 | ) 40 | 41 | // abs returns the absolute path the given relative file or directory path, 42 | // relative to the google.golang.org/grpc directory in the user's GOPATH. 43 | // If rel is already absolute, it is returned unmodified. 44 | func abs(rel string) string { 45 | if filepath.IsAbs(rel) { 46 | return rel 47 | } 48 | v, err := goPackagePath("google.golang.org/grpc") 49 | if err != nil { 50 | log.Fatalf("Error finding google.golang.org/grpc/testdata directory: %v", err) 51 | } 52 | return filepath.Join(v, rel) 53 | } 54 | 55 | func goPackagePath(pkg string) (path string, err error) { 56 | gp := os.Getenv("GOPATH") 57 | if gp == "" { 58 | return path, os.ErrNotExist 59 | } 60 | for _, p := range filepath.SplitList(gp) { 61 | dir := filepath.Join(p, "src", filepath.FromSlash(pkg)) 62 | fi, err := os.Stat(dir) 63 | if os.IsNotExist(err) { 64 | continue 65 | } 66 | if err != nil { 67 | return "", err 68 | } 69 | if !fi.IsDir() { 70 | continue 71 | } 72 | return dir, nil 73 | } 74 | return path, os.ErrNotExist 75 | } 76 | -------------------------------------------------------------------------------- /codegen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script serves as an example to demonstrate how to generate the gRPC-Go 4 | # interface and the related messages from .proto file. 5 | # 6 | # It assumes the installation of i) Google proto buffer compiler at 7 | # https://github.com/google/protobuf (after v2.6.1) and ii) the Go codegen 8 | # plugin at https://github.com/golang/protobuf (after 2015-02-20). If you have 9 | # not, please install them first. 10 | # 11 | # We recommend running this script at $GOPATH/src. 12 | # 13 | # If this is not what you need, feel free to make your own scripts. Again, this 14 | # script is for demonstration purpose. 15 | # 16 | proto=$1 17 | protoc --go_out=plugins=grpc:. $proto 18 | -------------------------------------------------------------------------------- /codes/code_string.go: -------------------------------------------------------------------------------- 1 | // generated by stringer -type=Code; DO NOT EDIT 2 | 3 | package codes 4 | 5 | import "fmt" 6 | 7 | const _Code_name = "OKCanceledUnknownInvalidArgumentDeadlineExceededNotFoundAlreadyExistsPermissionDeniedResourceExhaustedFailedPreconditionAbortedOutOfRangeUnimplementedInternalUnavailableDataLossUnauthenticated" 8 | 9 | var _Code_index = [...]uint8{0, 2, 10, 17, 32, 48, 56, 69, 85, 102, 120, 127, 137, 150, 158, 169, 177, 192} 10 | 11 | func (i Code) String() string { 12 | if i+1 >= Code(len(_Code_index)) { 13 | return fmt.Sprintf("Code(%d)", i) 14 | } 15 | return _Code_name[_Code_index[i]:_Code_index[i+1]] 16 | } 17 | -------------------------------------------------------------------------------- /coverage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | set -e 5 | 6 | workdir=.cover 7 | profile="$workdir/cover.out" 8 | mode=set 9 | end2endtest="google.golang.org/grpc/test" 10 | 11 | generate_cover_data() { 12 | rm -rf "$workdir" 13 | mkdir "$workdir" 14 | 15 | for pkg in "$@"; do 16 | if [ $pkg == "google.golang.org/grpc" -o $pkg == "google.golang.org/grpc/transport" -o $pkg == "google.golang.org/grpc/metadata" -o $pkg == "google.golang.org/grpc/credentials" ] 17 | then 18 | f="$workdir/$(echo $pkg | tr / -)" 19 | go test -covermode="$mode" -coverprofile="$f.cover" "$pkg" 20 | go test -covermode="$mode" -coverpkg "$pkg" -coverprofile="$f.e2e.cover" "$end2endtest" 21 | fi 22 | done 23 | 24 | echo "mode: $mode" >"$profile" 25 | grep -h -v "^mode:" "$workdir"/*.cover >>"$profile" 26 | } 27 | 28 | show_cover_report() { 29 | go tool cover -${1}="$profile" 30 | } 31 | 32 | push_to_coveralls() { 33 | goveralls -coverprofile="$profile" 34 | } 35 | 36 | generate_cover_data $(go list ./...) 37 | show_cover_report func 38 | case "$1" in 39 | "") 40 | ;; 41 | --html) 42 | show_cover_report html ;; 43 | --coveralls) 44 | push_to_coveralls ;; 45 | *) 46 | echo >&2 "error: invalid option: $1" ;; 47 | esac 48 | rm -rf "$workdir" 49 | -------------------------------------------------------------------------------- /credentials/credentials_util_go17.go: -------------------------------------------------------------------------------- 1 | // +build go1.7 2 | // +build !go1.8 3 | 4 | /* 5 | * 6 | * Copyright 2016, Google Inc. 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are 11 | * met: 12 | * 13 | * * Redistributions of source code must retain the above copyright 14 | * notice, this list of conditions and the following disclaimer. 15 | * * Redistributions in binary form must reproduce the above 16 | * copyright notice, this list of conditions and the following disclaimer 17 | * in the documentation and/or other materials provided with the 18 | * distribution. 19 | * * Neither the name of Google Inc. nor the names of its 20 | * contributors may be used to endorse or promote products derived from 21 | * this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | */ 36 | 37 | package credentials 38 | 39 | import ( 40 | "crypto/tls" 41 | ) 42 | 43 | // cloneTLSConfig returns a shallow clone of the exported 44 | // fields of cfg, ignoring the unexported sync.Once, which 45 | // contains a mutex and must not be copied. 46 | // 47 | // If cfg is nil, a new zero tls.Config is returned. 48 | func cloneTLSConfig(cfg *tls.Config) *tls.Config { 49 | if cfg == nil { 50 | return &tls.Config{} 51 | } 52 | return &tls.Config{ 53 | Rand: cfg.Rand, 54 | Time: cfg.Time, 55 | Certificates: cfg.Certificates, 56 | NameToCertificate: cfg.NameToCertificate, 57 | GetCertificate: cfg.GetCertificate, 58 | RootCAs: cfg.RootCAs, 59 | NextProtos: cfg.NextProtos, 60 | ServerName: cfg.ServerName, 61 | ClientAuth: cfg.ClientAuth, 62 | ClientCAs: cfg.ClientCAs, 63 | InsecureSkipVerify: cfg.InsecureSkipVerify, 64 | CipherSuites: cfg.CipherSuites, 65 | PreferServerCipherSuites: cfg.PreferServerCipherSuites, 66 | SessionTicketsDisabled: cfg.SessionTicketsDisabled, 67 | SessionTicketKey: cfg.SessionTicketKey, 68 | ClientSessionCache: cfg.ClientSessionCache, 69 | MinVersion: cfg.MinVersion, 70 | MaxVersion: cfg.MaxVersion, 71 | CurvePreferences: cfg.CurvePreferences, 72 | DynamicRecordSizingDisabled: cfg.DynamicRecordSizingDisabled, 73 | Renegotiation: cfg.Renegotiation, 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /credentials/credentials_util_go18.go: -------------------------------------------------------------------------------- 1 | // +build go1.8 2 | 3 | /* 4 | * 5 | * Copyright 2017, Google Inc. 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are 10 | * met: 11 | * 12 | * * Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * * Redistributions in binary form must reproduce the above 15 | * copyright notice, this list of conditions and the following disclaimer 16 | * in the documentation and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of Google Inc. nor the names of its 19 | * contributors may be used to endorse or promote products derived from 20 | * this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | package credentials 37 | 38 | import ( 39 | "crypto/tls" 40 | ) 41 | 42 | // cloneTLSConfig returns a shallow clone of the exported 43 | // fields of cfg, ignoring the unexported sync.Once, which 44 | // contains a mutex and must not be copied. 45 | // 46 | // If cfg is nil, a new zero tls.Config is returned. 47 | func cloneTLSConfig(cfg *tls.Config) *tls.Config { 48 | if cfg == nil { 49 | return &tls.Config{} 50 | } 51 | 52 | return cfg.Clone() 53 | } 54 | -------------------------------------------------------------------------------- /credentials/credentials_util_pre_go17.go: -------------------------------------------------------------------------------- 1 | // +build !go1.7 2 | 3 | /* 4 | * 5 | * Copyright 2016, Google Inc. 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are 10 | * met: 11 | * 12 | * * Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * * Redistributions in binary form must reproduce the above 15 | * copyright notice, this list of conditions and the following disclaimer 16 | * in the documentation and/or other materials provided with the 17 | * distribution. 18 | * * Neither the name of Google Inc. nor the names of its 19 | * contributors may be used to endorse or promote products derived from 20 | * this software without specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | package credentials 37 | 38 | import ( 39 | "crypto/tls" 40 | ) 41 | 42 | // cloneTLSConfig returns a shallow clone of the exported 43 | // fields of cfg, ignoring the unexported sync.Once, which 44 | // contains a mutex and must not be copied. 45 | // 46 | // If cfg is nil, a new zero tls.Config is returned. 47 | func cloneTLSConfig(cfg *tls.Config) *tls.Config { 48 | if cfg == nil { 49 | return &tls.Config{} 50 | } 51 | return &tls.Config{ 52 | Rand: cfg.Rand, 53 | Time: cfg.Time, 54 | Certificates: cfg.Certificates, 55 | NameToCertificate: cfg.NameToCertificate, 56 | GetCertificate: cfg.GetCertificate, 57 | RootCAs: cfg.RootCAs, 58 | NextProtos: cfg.NextProtos, 59 | ServerName: cfg.ServerName, 60 | ClientAuth: cfg.ClientAuth, 61 | ClientCAs: cfg.ClientCAs, 62 | InsecureSkipVerify: cfg.InsecureSkipVerify, 63 | CipherSuites: cfg.CipherSuites, 64 | PreferServerCipherSuites: cfg.PreferServerCipherSuites, 65 | SessionTicketsDisabled: cfg.SessionTicketsDisabled, 66 | SessionTicketKey: cfg.SessionTicketKey, 67 | ClientSessionCache: cfg.ClientSessionCache, 68 | MinVersion: cfg.MinVersion, 69 | MaxVersion: cfg.MaxVersion, 70 | CurvePreferences: cfg.CurvePreferences, 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package grpc implements an RPC system called gRPC. 3 | 4 | See www.grpc.io for more information about gRPC. 5 | */ 6 | package grpc // import "google.golang.org/grpc" 7 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | gRPC in 3 minutes (Go) 2 | ====================== 3 | 4 | BACKGROUND 5 | ------------- 6 | For this sample, we've already generated the server and client stubs from [helloworld.proto](helloworld/helloworld/helloworld.proto). 7 | 8 | PREREQUISITES 9 | ------------- 10 | 11 | - This requires Go 1.5 or later 12 | - Requires that [GOPATH is set](https://golang.org/doc/code.html#GOPATH) 13 | 14 | ``` 15 | $ go help gopath 16 | $ # ensure the PATH contains $GOPATH/bin 17 | $ export PATH=$PATH:$GOPATH/bin 18 | ``` 19 | 20 | INSTALL 21 | ------- 22 | 23 | ``` 24 | $ go get -u google.golang.org/grpc/examples/helloworld/greeter_client 25 | $ go get -u google.golang.org/grpc/examples/helloworld/greeter_server 26 | ``` 27 | 28 | TRY IT! 29 | ------- 30 | 31 | - Run the server 32 | 33 | ``` 34 | $ greeter_server & 35 | ``` 36 | 37 | - Run the client 38 | 39 | ``` 40 | $ greeter_client 41 | ``` 42 | 43 | OPTIONAL - Rebuilding the generated code 44 | ---------------------------------------- 45 | 46 | 1 First [install protoc](https://github.com/google/protobuf/blob/master/README.md) 47 | - For now, this needs to be installed from source 48 | - This is will change once proto3 is officially released 49 | 50 | 2 Install the protoc Go plugin. 51 | 52 | ``` 53 | $ go get -a github.com/golang/protobuf/protoc-gen-go 54 | $ 55 | $ # from this dir; invoke protoc 56 | $ protoc -I ./helloworld/helloworld/ ./helloworld/helloworld/helloworld.proto --go_out=plugins=grpc:helloworld 57 | ``` 58 | -------------------------------------------------------------------------------- /examples/helloworld/greeter_client/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2015, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package main 35 | 36 | import ( 37 | "log" 38 | "os" 39 | 40 | "golang.org/x/net/context" 41 | "google.golang.org/grpc" 42 | pb "google.golang.org/grpc/examples/helloworld/helloworld" 43 | ) 44 | 45 | const ( 46 | address = "localhost:50051" 47 | defaultName = "world" 48 | ) 49 | 50 | func main() { 51 | // Set up a connection to the server. 52 | conn, err := grpc.Dial(address, grpc.WithInsecure()) 53 | if err != nil { 54 | log.Fatalf("did not connect: %v", err) 55 | } 56 | defer conn.Close() 57 | c := pb.NewGreeterClient(conn) 58 | 59 | // Contact the server and print out its response. 60 | name := defaultName 61 | if len(os.Args) > 1 { 62 | name = os.Args[1] 63 | } 64 | r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) 65 | if err != nil { 66 | log.Fatalf("could not greet: %v", err) 67 | } 68 | log.Printf("Greeting: %s", r.Message) 69 | } 70 | -------------------------------------------------------------------------------- /examples/helloworld/greeter_server/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2015, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package main 35 | 36 | import ( 37 | "log" 38 | "net" 39 | 40 | "golang.org/x/net/context" 41 | "google.golang.org/grpc" 42 | pb "google.golang.org/grpc/examples/helloworld/helloworld" 43 | "google.golang.org/grpc/reflection" 44 | ) 45 | 46 | const ( 47 | port = ":50051" 48 | ) 49 | 50 | // server is used to implement helloworld.GreeterServer. 51 | type server struct{} 52 | 53 | // SayHello implements helloworld.GreeterServer 54 | func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { 55 | return &pb.HelloReply{Message: "Hello " + in.Name}, nil 56 | } 57 | 58 | func main() { 59 | lis, err := net.Listen("tcp", port) 60 | if err != nil { 61 | log.Fatalf("failed to listen: %v", err) 62 | } 63 | s := grpc.NewServer() 64 | pb.RegisterGreeterServer(s, &server{}) 65 | // Register reflection service on gRPC server. 66 | reflection.Register(s) 67 | if err := s.Serve(lis); err != nil { 68 | log.Fatalf("failed to serve: %v", err) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /examples/helloworld/helloworld/helloworld.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: helloworld.proto 3 | // DO NOT EDIT! 4 | 5 | /* 6 | Package helloworld is a generated protocol buffer package. 7 | 8 | It is generated from these files: 9 | helloworld.proto 10 | 11 | It has these top-level messages: 12 | HelloRequest 13 | HelloReply 14 | */ 15 | package helloworld 16 | 17 | import proto "github.com/golang/protobuf/proto" 18 | import fmt "fmt" 19 | import math "math" 20 | 21 | import ( 22 | context "golang.org/x/net/context" 23 | grpc "google.golang.org/grpc" 24 | ) 25 | 26 | // Reference imports to suppress errors if they are not otherwise used. 27 | var _ = proto.Marshal 28 | var _ = fmt.Errorf 29 | var _ = math.Inf 30 | 31 | // This is a compile-time assertion to ensure that this generated file 32 | // is compatible with the proto package it is being compiled against. 33 | // A compilation error at this line likely means your copy of the 34 | // proto package needs to be updated. 35 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 36 | 37 | // The request message containing the user's name. 38 | type HelloRequest struct { 39 | Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` 40 | } 41 | 42 | func (m *HelloRequest) Reset() { *m = HelloRequest{} } 43 | func (m *HelloRequest) String() string { return proto.CompactTextString(m) } 44 | func (*HelloRequest) ProtoMessage() {} 45 | func (*HelloRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } 46 | 47 | // The response message containing the greetings 48 | type HelloReply struct { 49 | Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` 50 | } 51 | 52 | func (m *HelloReply) Reset() { *m = HelloReply{} } 53 | func (m *HelloReply) String() string { return proto.CompactTextString(m) } 54 | func (*HelloReply) ProtoMessage() {} 55 | func (*HelloReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } 56 | 57 | func init() { 58 | proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest") 59 | proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply") 60 | } 61 | 62 | // Reference imports to suppress errors if they are not otherwise used. 63 | var _ context.Context 64 | var _ grpc.ClientConn 65 | 66 | // This is a compile-time assertion to ensure that this generated file 67 | // is compatible with the grpc package it is being compiled against. 68 | const _ = grpc.SupportPackageIsVersion4 69 | 70 | // Client API for Greeter service 71 | 72 | type GreeterClient interface { 73 | // Sends a greeting 74 | SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) 75 | } 76 | 77 | type greeterClient struct { 78 | cc *grpc.ClientConn 79 | } 80 | 81 | func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { 82 | return &greeterClient{cc} 83 | } 84 | 85 | func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { 86 | out := new(HelloReply) 87 | err := grpc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, c.cc, opts...) 88 | if err != nil { 89 | return nil, err 90 | } 91 | return out, nil 92 | } 93 | 94 | // Server API for Greeter service 95 | 96 | type GreeterServer interface { 97 | // Sends a greeting 98 | SayHello(context.Context, *HelloRequest) (*HelloReply, error) 99 | } 100 | 101 | func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { 102 | s.RegisterService(&_Greeter_serviceDesc, srv) 103 | } 104 | 105 | func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 106 | in := new(HelloRequest) 107 | if err := dec(in); err != nil { 108 | return nil, err 109 | } 110 | if interceptor == nil { 111 | return srv.(GreeterServer).SayHello(ctx, in) 112 | } 113 | info := &grpc.UnaryServerInfo{ 114 | Server: srv, 115 | FullMethod: "/helloworld.Greeter/SayHello", 116 | } 117 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 118 | return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest)) 119 | } 120 | return interceptor(ctx, in, info, handler) 121 | } 122 | 123 | var _Greeter_serviceDesc = grpc.ServiceDesc{ 124 | ServiceName: "helloworld.Greeter", 125 | HandlerType: (*GreeterServer)(nil), 126 | Methods: []grpc.MethodDesc{ 127 | { 128 | MethodName: "SayHello", 129 | Handler: _Greeter_SayHello_Handler, 130 | }, 131 | }, 132 | Streams: []grpc.StreamDesc{}, 133 | Metadata: "helloworld.proto", 134 | } 135 | 136 | func init() { proto.RegisterFile("helloworld.proto", fileDescriptor0) } 137 | 138 | var fileDescriptor0 = []byte{ 139 | // 174 bytes of a gzipped FileDescriptorProto 140 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9, 141 | 0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0x88, 142 | 0x28, 0x29, 0x71, 0xf1, 0x78, 0x80, 0x78, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42, 143 | 0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x92, 144 | 0x1a, 0x17, 0x17, 0x54, 0x4d, 0x41, 0x4e, 0xa5, 0x90, 0x04, 0x17, 0x7b, 0x6e, 0x6a, 0x71, 0x71, 145 | 0x62, 0x3a, 0x4c, 0x11, 0x8c, 0x6b, 0xe4, 0xc9, 0xc5, 0xee, 0x5e, 0x94, 0x9a, 0x5a, 0x92, 0x5a, 146 | 0x24, 0x64, 0xc7, 0xc5, 0x11, 0x9c, 0x58, 0x09, 0xd6, 0x25, 0x24, 0xa1, 0x87, 0xe4, 0x02, 0x64, 147 | 0xcb, 0xa4, 0xc4, 0xb0, 0xc8, 0x00, 0xad, 0x50, 0x62, 0x70, 0x32, 0xe0, 0x92, 0xce, 0xcc, 0xd7, 148 | 0x4b, 0x2f, 0x2a, 0x48, 0xd6, 0x4b, 0xad, 0x48, 0xcc, 0x2d, 0xc8, 0x49, 0x2d, 0x46, 0x52, 0xeb, 149 | 0xc4, 0x0f, 0x56, 0x1c, 0x0e, 0x62, 0x07, 0x80, 0xbc, 0x14, 0xc0, 0x98, 0xc4, 0x06, 0xf6, 0x9b, 150 | 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xb7, 0xcd, 0xf2, 0xef, 0x00, 0x00, 0x00, 151 | } 152 | -------------------------------------------------------------------------------- /examples/helloworld/helloworld/helloworld.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | syntax = "proto3"; 31 | 32 | option java_multiple_files = true; 33 | option java_package = "io.grpc.examples.helloworld"; 34 | option java_outer_classname = "HelloWorldProto"; 35 | 36 | package helloworld; 37 | 38 | // The greeting service definition. 39 | service Greeter { 40 | // Sends a greeting 41 | rpc SayHello (HelloRequest) returns (HelloReply) {} 42 | } 43 | 44 | // The request message containing the user's name. 45 | message HelloRequest { 46 | string name = 1; 47 | } 48 | 49 | // The response message containing the greetings 50 | message HelloReply { 51 | string message = 1; 52 | } 53 | -------------------------------------------------------------------------------- /examples/helloworld/mock/hw_test.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/golang/mock/gomock" 8 | "github.com/golang/protobuf/proto" 9 | "golang.org/x/net/context" 10 | helloworld "google.golang.org/grpc/examples/helloworld/helloworld" 11 | hwmock "google.golang.org/grpc/examples/helloworld/mock/mock_helloworld" 12 | ) 13 | 14 | // rpcMsg implements the gomock.Matcher interface 15 | type rpcMsg struct { 16 | msg proto.Message 17 | } 18 | 19 | func (r *rpcMsg) Matches(msg interface{}) bool { 20 | m, ok := msg.(proto.Message) 21 | if !ok { 22 | return false 23 | } 24 | return proto.Equal(m, r.msg) 25 | } 26 | 27 | func (r *rpcMsg) String() string { 28 | return fmt.Sprintf("is %s", r.msg) 29 | } 30 | 31 | func TestSayHello(t *testing.T) { 32 | ctrl := gomock.NewController(t) 33 | defer ctrl.Finish() 34 | mockGreeterClient := hwmock.NewMockGreeterClient(ctrl) 35 | req := &helloworld.HelloRequest{Name: "unit_test"} 36 | mockGreeterClient.EXPECT().SayHello( 37 | gomock.Any(), 38 | &rpcMsg{msg: req}, 39 | ).Return(&helloworld.HelloReply{Message: "Mocked Interface"}, nil) 40 | testSayHello(t, mockGreeterClient) 41 | } 42 | 43 | func testSayHello(t *testing.T, client helloworld.GreeterClient) { 44 | r, err := client.SayHello(context.Background(), &helloworld.HelloRequest{Name: "unit_test"}) 45 | if err != nil || r.Message != "Mocked Interface" { 46 | t.Errorf("mocking failed") 47 | } 48 | t.Log("Reply : ", r.Message) 49 | } 50 | -------------------------------------------------------------------------------- /examples/helloworld/mock/mock_helloworld/hw_mock.go: -------------------------------------------------------------------------------- 1 | // Automatically generated by MockGen. DO NOT EDIT! 2 | // Source: google.golang.org/grpc/examples/helloworld/helloworld (interfaces: GreeterClient) 3 | 4 | package mock_helloworld 5 | 6 | import ( 7 | gomock "github.com/golang/mock/gomock" 8 | context "golang.org/x/net/context" 9 | grpc "google.golang.org/grpc" 10 | helloworld "google.golang.org/grpc/examples/helloworld/helloworld" 11 | ) 12 | 13 | // Mock of GreeterClient interface 14 | type MockGreeterClient struct { 15 | ctrl *gomock.Controller 16 | recorder *_MockGreeterClientRecorder 17 | } 18 | 19 | // Recorder for MockGreeterClient (not exported) 20 | type _MockGreeterClientRecorder struct { 21 | mock *MockGreeterClient 22 | } 23 | 24 | func NewMockGreeterClient(ctrl *gomock.Controller) *MockGreeterClient { 25 | mock := &MockGreeterClient{ctrl: ctrl} 26 | mock.recorder = &_MockGreeterClientRecorder{mock} 27 | return mock 28 | } 29 | 30 | func (_m *MockGreeterClient) EXPECT() *_MockGreeterClientRecorder { 31 | return _m.recorder 32 | } 33 | 34 | func (_m *MockGreeterClient) SayHello(_param0 context.Context, _param1 *helloworld.HelloRequest, _param2 ...grpc.CallOption) (*helloworld.HelloReply, error) { 35 | _s := []interface{}{_param0, _param1} 36 | for _, _x := range _param2 { 37 | _s = append(_s, _x) 38 | } 39 | ret := _m.ctrl.Call(_m, "SayHello", _s...) 40 | ret0, _ := ret[0].(*helloworld.HelloReply) 41 | ret1, _ := ret[1].(error) 42 | return ret0, ret1 43 | } 44 | 45 | func (_mr *_MockGreeterClientRecorder) SayHello(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call { 46 | _s := append([]interface{}{arg0, arg1}, arg2...) 47 | return _mr.mock.ctrl.RecordCall(_mr.mock, "SayHello", _s...) 48 | } 49 | -------------------------------------------------------------------------------- /examples/route_guide/README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | The route guide server and client demonstrate how to use grpc go libraries to 3 | perform unary, client streaming, server streaming and full duplex RPCs. 4 | 5 | Please refer to [gRPC Basics: Go] (http://www.grpc.io/docs/tutorials/basic/go.html) for more information. 6 | 7 | See the definition of the route guide service in proto/route_guide.proto. 8 | 9 | # Run the sample code 10 | To compile and run the server, assuming you are in the root of the route_guide 11 | folder, i.e., .../examples/route_guide/, simply: 12 | 13 | ```sh 14 | $ go run server/server.go 15 | ``` 16 | 17 | Likewise, to run the client: 18 | 19 | ```sh 20 | $ go run client/client.go 21 | ``` 22 | 23 | # Optional command line flags 24 | The server and client both take optional command line flags. For example, the 25 | client and server run without TLS by default. To enable TLS: 26 | 27 | ```sh 28 | $ go run server/server.go -tls=true 29 | ``` 30 | 31 | and 32 | 33 | ```sh 34 | $ go run client/client.go -tls=true 35 | ``` 36 | -------------------------------------------------------------------------------- /examples/route_guide/routeguide/route_guide.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | syntax = "proto3"; 31 | 32 | option java_multiple_files = true; 33 | option java_package = "io.grpc.examples.routeguide"; 34 | option java_outer_classname = "RouteGuideProto"; 35 | 36 | package routeguide; 37 | 38 | // Interface exported by the server. 39 | service RouteGuide { 40 | // A simple RPC. 41 | // 42 | // Obtains the feature at a given position. 43 | // 44 | // A feature with an empty name is returned if there's no feature at the given 45 | // position. 46 | rpc GetFeature(Point) returns (Feature) {} 47 | 48 | // A server-to-client streaming RPC. 49 | // 50 | // Obtains the Features available within the given Rectangle. Results are 51 | // streamed rather than returned at once (e.g. in a response message with a 52 | // repeated field), as the rectangle may cover a large area and contain a 53 | // huge number of features. 54 | rpc ListFeatures(Rectangle) returns (stream Feature) {} 55 | 56 | // A client-to-server streaming RPC. 57 | // 58 | // Accepts a stream of Points on a route being traversed, returning a 59 | // RouteSummary when traversal is completed. 60 | rpc RecordRoute(stream Point) returns (RouteSummary) {} 61 | 62 | // A Bidirectional streaming RPC. 63 | // 64 | // Accepts a stream of RouteNotes sent while a route is being traversed, 65 | // while receiving other RouteNotes (e.g. from other users). 66 | rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} 67 | } 68 | 69 | // Points are represented as latitude-longitude pairs in the E7 representation 70 | // (degrees multiplied by 10**7 and rounded to the nearest integer). 71 | // Latitudes should be in the range +/- 90 degrees and longitude should be in 72 | // the range +/- 180 degrees (inclusive). 73 | message Point { 74 | int32 latitude = 1; 75 | int32 longitude = 2; 76 | } 77 | 78 | // A latitude-longitude rectangle, represented as two diagonally opposite 79 | // points "lo" and "hi". 80 | message Rectangle { 81 | // One corner of the rectangle. 82 | Point lo = 1; 83 | 84 | // The other corner of the rectangle. 85 | Point hi = 2; 86 | } 87 | 88 | // A feature names something at a given point. 89 | // 90 | // If a feature could not be named, the name is empty. 91 | message Feature { 92 | // The name of the feature. 93 | string name = 1; 94 | 95 | // The point where the feature is detected. 96 | Point location = 2; 97 | } 98 | 99 | // A RouteNote is a message sent while at a given point. 100 | message RouteNote { 101 | // The location from which the message is sent. 102 | Point location = 1; 103 | 104 | // The message to be sent. 105 | string message = 2; 106 | } 107 | 108 | // A RouteSummary is received in response to a RecordRoute rpc. 109 | // 110 | // It contains the number of individual points received, the number of 111 | // detected features, and the total distance covered as the cumulative sum of 112 | // the distance between each point. 113 | message RouteSummary { 114 | // The number of points received. 115 | int32 point_count = 1; 116 | 117 | // The number of known features passed while traversing the route. 118 | int32 feature_count = 2; 119 | 120 | // The distance covered in metres. 121 | int32 distance = 3; 122 | 123 | // The duration of the traversal in seconds. 124 | int32 elapsed_time = 4; 125 | } 126 | -------------------------------------------------------------------------------- /examples/route_guide/testdata/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla 5 | Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 6 | YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT 7 | BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 8 | +L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu 9 | g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd 10 | Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV 11 | HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau 12 | sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m 13 | oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG 14 | Dfcog5wrJytaQ6UA0wE= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /examples/route_guide/testdata/server1.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD 3 | M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf 4 | 3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY 5 | AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm 6 | V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY 7 | tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p 8 | dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q 9 | K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR 10 | 81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff 11 | DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd 12 | aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 13 | ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 14 | XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe 15 | F98XJ7tIFfJq 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /examples/route_guide/testdata/server1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET 3 | MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ 4 | dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx 5 | MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV 6 | BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 7 | ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco 8 | LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg 9 | zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd 10 | 9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw 11 | CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy 12 | em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G 13 | CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 14 | hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh 15 | y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /grpclb/grpc_lb_v1/grpclb.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.lb.v1; 4 | 5 | message Duration { 6 | // Signed seconds of the span of time. Must be from -315,576,000,000 7 | // to +315,576,000,000 inclusive. 8 | int64 seconds = 1; 9 | 10 | // Signed fractions of a second at nanosecond resolution of the span 11 | // of time. Durations less than one second are represented with a 0 12 | // `seconds` field and a positive or negative `nanos` field. For durations 13 | // of one second or more, a non-zero value for the `nanos` field must be 14 | // of the same sign as the `seconds` field. Must be from -999,999,999 15 | // to +999,999,999 inclusive. 16 | int32 nanos = 2; 17 | } 18 | 19 | service LoadBalancer { 20 | // Bidirectional rpc to get a list of servers. 21 | rpc BalanceLoad(stream LoadBalanceRequest) 22 | returns (stream LoadBalanceResponse); 23 | } 24 | 25 | message LoadBalanceRequest { 26 | oneof load_balance_request_type { 27 | // This message should be sent on the first request to the load balancer. 28 | InitialLoadBalanceRequest initial_request = 1; 29 | 30 | // The client stats should be periodically reported to the load balancer 31 | // based on the duration defined in the InitialLoadBalanceResponse. 32 | ClientStats client_stats = 2; 33 | } 34 | } 35 | 36 | message InitialLoadBalanceRequest { 37 | // Name of load balanced service (IE, service.grpc.gslb.google.com) 38 | string name = 1; 39 | } 40 | 41 | // Contains client level statistics that are useful to load balancing. Each 42 | // count should be reset to zero after reporting the stats. 43 | message ClientStats { 44 | // The total number of requests sent by the client since the last report. 45 | int64 total_requests = 1; 46 | 47 | // The number of client rpc errors since the last report. 48 | int64 client_rpc_errors = 2; 49 | 50 | // The number of dropped requests since the last report. 51 | int64 dropped_requests = 3; 52 | } 53 | 54 | message LoadBalanceResponse { 55 | oneof load_balance_response_type { 56 | // This message should be sent on the first response to the client. 57 | InitialLoadBalanceResponse initial_response = 1; 58 | 59 | // Contains the list of servers selected by the load balancer. The client 60 | // should send requests to these servers in the specified order. 61 | ServerList server_list = 2; 62 | } 63 | } 64 | 65 | message InitialLoadBalanceResponse { 66 | // This is an application layer redirect that indicates the client should use 67 | // the specified server for load balancing. When this field is non-empty in 68 | // the response, the client should open a separate connection to the 69 | // load_balancer_delegate and call the BalanceLoad method. 70 | string load_balancer_delegate = 1; 71 | 72 | // This interval defines how often the client should send the client stats 73 | // to the load balancer. Stats should only be reported when the duration is 74 | // positive. 75 | Duration client_stats_report_interval = 3; 76 | } 77 | 78 | message ServerList { 79 | // Contains a list of servers selected by the load balancer. The list will 80 | // be updated when server resolutions change or as needed to balance load 81 | // across more servers. The client should consume the server list in order 82 | // unless instructed otherwise via the client_config. 83 | repeated Server servers = 1; 84 | 85 | // Indicates the amount of time that the client should consider this server 86 | // list as valid. It may be considered stale after waiting this interval of 87 | // time after receiving the list. If the interval is not positive, the 88 | // client can assume the list is valid until the next list is received. 89 | Duration expiration_interval = 3; 90 | } 91 | 92 | message Server { 93 | // A resolved address for the server, serialized in network-byte-order. It may 94 | // either be an IPv4 or IPv6 address. 95 | bytes ip_address = 1; 96 | 97 | // A resolved port number for the server. 98 | int32 port = 2; 99 | 100 | // An opaque but printable token given to the frontend for each pick. All 101 | // frontend requests for that pick must include the token in its initial 102 | // metadata. The token is used by the backend to verify the request and to 103 | // allow the backend to report load to the gRPC LB system. 104 | string load_balance_token = 3; 105 | 106 | // Indicates whether this particular request should be dropped by the client 107 | // when this server is chosen from the list. 108 | bool drop_request = 4; 109 | } 110 | -------------------------------------------------------------------------------- /grpclog/glogger/glogger.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2015, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | /* 35 | Package glogger defines glog-based logging for grpc. 36 | */ 37 | package glogger 38 | 39 | import ( 40 | "fmt" 41 | 42 | "github.com/golang/glog" 43 | "google.golang.org/grpc/grpclog" 44 | ) 45 | 46 | func init() { 47 | grpclog.SetLogger(&glogger{}) 48 | } 49 | 50 | type glogger struct{} 51 | 52 | func (g *glogger) Fatal(args ...interface{}) { 53 | glog.FatalDepth(2, args...) 54 | } 55 | 56 | func (g *glogger) Fatalf(format string, args ...interface{}) { 57 | glog.FatalDepth(2, fmt.Sprintf(format, args...)) 58 | } 59 | 60 | func (g *glogger) Fatalln(args ...interface{}) { 61 | glog.FatalDepth(2, fmt.Sprintln(args...)) 62 | } 63 | 64 | func (g *glogger) Print(args ...interface{}) { 65 | glog.InfoDepth(2, args...) 66 | } 67 | 68 | func (g *glogger) Printf(format string, args ...interface{}) { 69 | glog.InfoDepth(2, fmt.Sprintf(format, args...)) 70 | } 71 | 72 | func (g *glogger) Println(args ...interface{}) { 73 | glog.InfoDepth(2, fmt.Sprintln(args...)) 74 | } 75 | -------------------------------------------------------------------------------- /grpclog/logger.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2015, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | /* 35 | Package grpclog defines logging for grpc. 36 | */ 37 | package grpclog // import "google.golang.org/grpc/grpclog" 38 | 39 | import ( 40 | "log" 41 | "os" 42 | ) 43 | 44 | // Use golang's standard logger by default. 45 | // Access is not mutex-protected: do not modify except in init() 46 | // functions. 47 | var logger Logger = log.New(os.Stderr, "", log.LstdFlags) 48 | 49 | // Logger mimics golang's standard Logger as an interface. 50 | type Logger interface { 51 | Fatal(args ...interface{}) 52 | Fatalf(format string, args ...interface{}) 53 | Fatalln(args ...interface{}) 54 | Print(args ...interface{}) 55 | Printf(format string, args ...interface{}) 56 | Println(args ...interface{}) 57 | } 58 | 59 | // SetLogger sets the logger that is used in grpc. Call only from 60 | // init() functions. 61 | func SetLogger(l Logger) { 62 | logger = l 63 | } 64 | 65 | // Fatal is equivalent to Print() followed by a call to os.Exit() with a non-zero exit code. 66 | func Fatal(args ...interface{}) { 67 | logger.Fatal(args...) 68 | } 69 | 70 | // Fatalf is equivalent to Printf() followed by a call to os.Exit() with a non-zero exit code. 71 | func Fatalf(format string, args ...interface{}) { 72 | logger.Fatalf(format, args...) 73 | } 74 | 75 | // Fatalln is equivalent to Println() followed by a call to os.Exit()) with a non-zero exit code. 76 | func Fatalln(args ...interface{}) { 77 | logger.Fatalln(args...) 78 | } 79 | 80 | // Print prints to the logger. Arguments are handled in the manner of fmt.Print. 81 | func Print(args ...interface{}) { 82 | logger.Print(args...) 83 | } 84 | 85 | // Printf prints to the logger. Arguments are handled in the manner of fmt.Printf. 86 | func Printf(format string, args ...interface{}) { 87 | logger.Printf(format, args...) 88 | } 89 | 90 | // Println prints to the logger. Arguments are handled in the manner of fmt.Println. 91 | func Println(args ...interface{}) { 92 | logger.Println(args...) 93 | } 94 | -------------------------------------------------------------------------------- /health/grpc_health_v1/health.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.health.v1; 4 | 5 | message HealthCheckRequest { 6 | string service = 1; 7 | } 8 | 9 | message HealthCheckResponse { 10 | enum ServingStatus { 11 | UNKNOWN = 0; 12 | SERVING = 1; 13 | NOT_SERVING = 2; 14 | } 15 | ServingStatus status = 1; 16 | } 17 | 18 | service Health{ 19 | rpc Check(HealthCheckRequest) returns (HealthCheckResponse); 20 | } 21 | -------------------------------------------------------------------------------- /health/health.go: -------------------------------------------------------------------------------- 1 | // Package health provides some utility functions to health-check a server. The implementation 2 | // is based on protobuf. Users need to write their own implementations if other IDLs are used. 3 | package health 4 | 5 | import ( 6 | "sync" 7 | 8 | "golang.org/x/net/context" 9 | "google.golang.org/grpc" 10 | "google.golang.org/grpc/codes" 11 | healthpb "google.golang.org/grpc/health/grpc_health_v1" 12 | ) 13 | 14 | // Server implements `service Health`. 15 | type Server struct { 16 | mu sync.Mutex 17 | // statusMap stores the serving status of the services this Server monitors. 18 | statusMap map[string]healthpb.HealthCheckResponse_ServingStatus 19 | } 20 | 21 | // NewServer returns a new Server. 22 | func NewServer() *Server { 23 | return &Server{ 24 | statusMap: make(map[string]healthpb.HealthCheckResponse_ServingStatus), 25 | } 26 | } 27 | 28 | // Check implements `service Health`. 29 | func (s *Server) Check(ctx context.Context, in *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) { 30 | s.mu.Lock() 31 | defer s.mu.Unlock() 32 | if in.Service == "" { 33 | // check the server overall health status. 34 | return &healthpb.HealthCheckResponse{ 35 | Status: healthpb.HealthCheckResponse_SERVING, 36 | }, nil 37 | } 38 | if status, ok := s.statusMap[in.Service]; ok { 39 | return &healthpb.HealthCheckResponse{ 40 | Status: status, 41 | }, nil 42 | } 43 | return nil, grpc.Errorf(codes.NotFound, "unknown service") 44 | } 45 | 46 | // SetServingStatus is called when need to reset the serving status of a service 47 | // or insert a new service entry into the statusMap. 48 | func (s *Server) SetServingStatus(service string, status healthpb.HealthCheckResponse_ServingStatus) { 49 | s.mu.Lock() 50 | s.statusMap[service] = status 51 | s.mu.Unlock() 52 | } 53 | -------------------------------------------------------------------------------- /interceptor.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2016, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package grpc 35 | 36 | import ( 37 | "golang.org/x/net/context" 38 | ) 39 | 40 | // UnaryInvoker is called by UnaryClientInterceptor to complete RPCs. 41 | type UnaryInvoker func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, opts ...CallOption) error 42 | 43 | // UnaryClientInterceptor intercepts the execution of a unary RPC on the client. inovker is the handler to complete the RPC 44 | // and it is the responsibility of the interceptor to call it. 45 | // This is the EXPERIMENTAL API. 46 | type UnaryClientInterceptor func(ctx context.Context, method string, req, reply interface{}, cc *ClientConn, invoker UnaryInvoker, opts ...CallOption) error 47 | 48 | // Streamer is called by StreamClientInterceptor to create a ClientStream. 49 | type Streamer func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) 50 | 51 | // StreamClientInterceptor intercepts the creation of ClientStream. It may return a custom ClientStream to intercept all I/O 52 | // operations. streamer is the handlder to create a ClientStream and it is the responsibility of the interceptor to call it. 53 | // This is the EXPERIMENTAL API. 54 | type StreamClientInterceptor func(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, streamer Streamer, opts ...CallOption) (ClientStream, error) 55 | 56 | // UnaryServerInfo consists of various information about a unary RPC on 57 | // server side. All per-rpc information may be mutated by the interceptor. 58 | type UnaryServerInfo struct { 59 | // Server is the service implementation the user provides. This is read-only. 60 | Server interface{} 61 | // FullMethod is the full RPC method string, i.e., /package.service/method. 62 | FullMethod string 63 | } 64 | 65 | // UnaryHandler defines the handler invoked by UnaryServerInterceptor to complete the normal 66 | // execution of a unary RPC. 67 | type UnaryHandler func(ctx context.Context, req interface{}) (interface{}, error) 68 | 69 | // UnaryServerInterceptor provides a hook to intercept the execution of a unary RPC on the server. info 70 | // contains all the information of this RPC the interceptor can operate on. And handler is the wrapper 71 | // of the service method implementation. It is the responsibility of the interceptor to invoke handler 72 | // to complete the RPC. 73 | type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error) 74 | 75 | // StreamServerInfo consists of various information about a streaming RPC on 76 | // server side. All per-rpc information may be mutated by the interceptor. 77 | type StreamServerInfo struct { 78 | // FullMethod is the full RPC method string, i.e., /package.service/method. 79 | FullMethod string 80 | // IsClientStream indicates whether the RPC is a client streaming RPC. 81 | IsClientStream bool 82 | // IsServerStream indicates whether the RPC is a server streaming RPC. 83 | IsServerStream bool 84 | } 85 | 86 | // StreamServerInterceptor provides a hook to intercept the execution of a streaming RPC on the server. 87 | // info contains all the information of this RPC the interceptor can operate on. And handler is the 88 | // service method implementation. It is the responsibility of the interceptor to invoke handler to 89 | // complete the RPC. 90 | type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error 91 | -------------------------------------------------------------------------------- /internal/internal.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | * 31 | */ 32 | 33 | // Package internal contains gRPC-internal code for testing, to avoid polluting 34 | // the godoc of the top-level grpc package. 35 | package internal 36 | 37 | // TestingCloseConns closes all existing transports but keeps 38 | // grpcServer.lis accepting new connections. 39 | // 40 | // The provided grpcServer must be of type *grpc.Server. It is untyped 41 | // for circular dependency reasons. 42 | var TestingCloseConns func(grpcServer interface{}) 43 | 44 | // TestingUseHandlerImpl enables the http.Handler-based server implementation. 45 | // It must be called before Serve and requires TLS credentials. 46 | // 47 | // The provided grpcServer must be of type *grpc.Server. It is untyped 48 | // for circular dependency reasons. 49 | var TestingUseHandlerImpl func(grpcServer interface{}) 50 | -------------------------------------------------------------------------------- /interop/client/testdata/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla 5 | Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 6 | YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT 7 | BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 8 | +L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu 9 | g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd 10 | Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV 11 | HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau 12 | sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m 13 | oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG 14 | Dfcog5wrJytaQ6UA0wE= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /interop/client/testdata/server1.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD 3 | M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf 4 | 3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY 5 | AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm 6 | V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY 7 | tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p 8 | dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q 9 | K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR 10 | 81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff 11 | DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd 12 | aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 13 | ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 14 | XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe 15 | F98XJ7tIFfJq 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /interop/client/testdata/server1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET 3 | MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ 4 | dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx 5 | MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV 6 | BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 7 | ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco 8 | LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg 9 | zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd 10 | 9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw 11 | CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy 12 | em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G 13 | CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 14 | hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh 15 | y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /interop/grpc_testing/test.proto: -------------------------------------------------------------------------------- 1 | // An integration test service that covers all the method signature permutations 2 | // of unary/streaming requests/responses. 3 | syntax = "proto2"; 4 | 5 | package grpc.testing; 6 | 7 | message Empty {} 8 | 9 | // The type of payload that should be returned. 10 | enum PayloadType { 11 | // Compressable text format. 12 | COMPRESSABLE = 0; 13 | 14 | // Uncompressable binary format. 15 | UNCOMPRESSABLE = 1; 16 | 17 | // Randomly chosen from all other formats defined in this enum. 18 | RANDOM = 2; 19 | } 20 | 21 | // A block of data, to simply increase gRPC message size. 22 | message Payload { 23 | // The type of data in body. 24 | optional PayloadType type = 1; 25 | // Primary contents of payload. 26 | optional bytes body = 2; 27 | } 28 | 29 | // A protobuf representation for grpc status. This is used by test 30 | // clients to specify a status that the server should attempt to return. 31 | message EchoStatus { 32 | optional int32 code = 1; 33 | optional string message = 2; 34 | } 35 | 36 | // Unary request. 37 | message SimpleRequest { 38 | // Desired payload type in the response from the server. 39 | // If response_type is RANDOM, server randomly chooses one from other formats. 40 | optional PayloadType response_type = 1; 41 | 42 | // Desired payload size in the response from the server. 43 | // If response_type is COMPRESSABLE, this denotes the size before compression. 44 | optional int32 response_size = 2; 45 | 46 | // Optional input payload sent along with the request. 47 | optional Payload payload = 3; 48 | 49 | // Whether SimpleResponse should include username. 50 | optional bool fill_username = 4; 51 | 52 | // Whether SimpleResponse should include OAuth scope. 53 | optional bool fill_oauth_scope = 5; 54 | 55 | // Whether server should return a given status 56 | optional EchoStatus response_status = 7; 57 | } 58 | 59 | // Unary response, as configured by the request. 60 | message SimpleResponse { 61 | // Payload to increase message size. 62 | optional Payload payload = 1; 63 | 64 | // The user the request came from, for verifying authentication was 65 | // successful when the client expected it. 66 | optional string username = 2; 67 | 68 | // OAuth scope. 69 | optional string oauth_scope = 3; 70 | } 71 | 72 | // Client-streaming request. 73 | message StreamingInputCallRequest { 74 | // Optional input payload sent along with the request. 75 | optional Payload payload = 1; 76 | 77 | // Not expecting any payload from the response. 78 | } 79 | 80 | // Client-streaming response. 81 | message StreamingInputCallResponse { 82 | // Aggregated size of payloads received from the client. 83 | optional int32 aggregated_payload_size = 1; 84 | } 85 | 86 | // Configuration for a particular response. 87 | message ResponseParameters { 88 | // Desired payload sizes in responses from the server. 89 | // If response_type is COMPRESSABLE, this denotes the size before compression. 90 | optional int32 size = 1; 91 | 92 | // Desired interval between consecutive responses in the response stream in 93 | // microseconds. 94 | optional int32 interval_us = 2; 95 | } 96 | 97 | // Server-streaming request. 98 | message StreamingOutputCallRequest { 99 | // Desired payload type in the response from the server. 100 | // If response_type is RANDOM, the payload from each response in the stream 101 | // might be of different types. This is to simulate a mixed type of payload 102 | // stream. 103 | optional PayloadType response_type = 1; 104 | 105 | // Configuration for each expected response message. 106 | repeated ResponseParameters response_parameters = 2; 107 | 108 | // Optional input payload sent along with the request. 109 | optional Payload payload = 3; 110 | 111 | // Whether server should return a given status 112 | optional EchoStatus response_status = 7; 113 | } 114 | 115 | // Server-streaming response, as configured by the request and parameters. 116 | message StreamingOutputCallResponse { 117 | // Payload to increase response size. 118 | optional Payload payload = 1; 119 | } 120 | 121 | // A simple service to test the various types of RPCs and experiment with 122 | // performance with various types of payload. 123 | service TestService { 124 | // One empty request followed by one empty response. 125 | rpc EmptyCall(Empty) returns (Empty); 126 | 127 | // One request followed by one response. 128 | // The server returns the client payload as-is. 129 | rpc UnaryCall(SimpleRequest) returns (SimpleResponse); 130 | 131 | // One request followed by a sequence of responses (streamed download). 132 | // The server returns the payload with client desired type and sizes. 133 | rpc StreamingOutputCall(StreamingOutputCallRequest) 134 | returns (stream StreamingOutputCallResponse); 135 | 136 | // A sequence of requests followed by one response (streamed upload). 137 | // The server returns the aggregated size of client payload as the result. 138 | rpc StreamingInputCall(stream StreamingInputCallRequest) 139 | returns (StreamingInputCallResponse); 140 | 141 | // A sequence of requests with each request served by the server immediately. 142 | // As one request could lead to multiple responses, this interface 143 | // demonstrates the idea of full duplexing. 144 | rpc FullDuplexCall(stream StreamingOutputCallRequest) 145 | returns (stream StreamingOutputCallResponse); 146 | 147 | // A sequence of requests followed by a sequence of responses. 148 | // The server buffers all the client requests and then serves them in order. A 149 | // stream of responses are returned to the client when the server starts with 150 | // first request. 151 | rpc HalfDuplexCall(stream StreamingOutputCallRequest) 152 | returns (stream StreamingOutputCallResponse); 153 | } 154 | 155 | // A simple service NOT implemented at servers so clients can test for 156 | // that case. 157 | service UnimplementedService { 158 | // A call that no server should implement 159 | rpc UnimplementedCall(grpc.testing.Empty) returns (grpc.testing.Empty); 160 | } 161 | -------------------------------------------------------------------------------- /interop/server/server.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package main 35 | 36 | import ( 37 | "flag" 38 | "net" 39 | "strconv" 40 | 41 | "google.golang.org/grpc" 42 | "google.golang.org/grpc/credentials" 43 | "google.golang.org/grpc/grpclog" 44 | "google.golang.org/grpc/interop" 45 | testpb "google.golang.org/grpc/interop/grpc_testing" 46 | ) 47 | 48 | var ( 49 | useTLS = flag.Bool("use_tls", false, "Connection uses TLS if true, else plain TCP") 50 | certFile = flag.String("tls_cert_file", "testdata/server1.pem", "The TLS cert file") 51 | keyFile = flag.String("tls_key_file", "testdata/server1.key", "The TLS key file") 52 | port = flag.Int("port", 10000, "The server port") 53 | ) 54 | 55 | func main() { 56 | flag.Parse() 57 | p := strconv.Itoa(*port) 58 | lis, err := net.Listen("tcp", ":"+p) 59 | if err != nil { 60 | grpclog.Fatalf("failed to listen: %v", err) 61 | } 62 | var opts []grpc.ServerOption 63 | if *useTLS { 64 | creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile) 65 | if err != nil { 66 | grpclog.Fatalf("Failed to generate credentials %v", err) 67 | } 68 | opts = []grpc.ServerOption{grpc.Creds(creds)} 69 | } 70 | server := grpc.NewServer(opts...) 71 | testpb.RegisterTestServiceServer(server, interop.NewTestServer()) 72 | server.Serve(lis) 73 | } 74 | -------------------------------------------------------------------------------- /interop/server/testdata/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla 5 | Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 6 | YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT 7 | BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 8 | +L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu 9 | g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd 10 | Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV 11 | HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau 12 | sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m 13 | oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG 14 | Dfcog5wrJytaQ6UA0wE= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /interop/server/testdata/server1.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD 3 | M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf 4 | 3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY 5 | AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm 6 | V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY 7 | tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p 8 | dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q 9 | K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR 10 | 81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff 11 | DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd 12 | aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 13 | ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 14 | XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe 15 | F98XJ7tIFfJq 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /interop/server/testdata/server1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET 3 | MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ 4 | dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx 5 | MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV 6 | BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 7 | ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco 8 | LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg 9 | zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd 10 | 9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw 11 | CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy 12 | em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G 13 | CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 14 | hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh 15 | y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /metadata/metadata.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | // Package metadata define the structure of the metadata supported by gRPC library. 35 | // Please refer to http://www.grpc.io/docs/guides/wire.html for more information about custom-metadata. 36 | package metadata // import "google.golang.org/grpc/metadata" 37 | 38 | import ( 39 | "encoding/base64" 40 | "fmt" 41 | "strings" 42 | 43 | "golang.org/x/net/context" 44 | ) 45 | 46 | const ( 47 | binHdrSuffix = "-bin" 48 | ) 49 | 50 | // encodeKeyValue encodes key and value qualified for transmission via gRPC. 51 | // Transmitting binary headers violates HTTP/2 spec. 52 | // TODO(zhaoq): Maybe check if k is ASCII also. 53 | func encodeKeyValue(k, v string) (string, string) { 54 | k = strings.ToLower(k) 55 | if strings.HasSuffix(k, binHdrSuffix) { 56 | val := base64.StdEncoding.EncodeToString([]byte(v)) 57 | v = string(val) 58 | } 59 | return k, v 60 | } 61 | 62 | // DecodeKeyValue returns the original key and value corresponding to the 63 | // encoded data in k, v. 64 | // If k is a binary header and v contains comma, v is split on comma before decoded, 65 | // and the decoded v will be joined with comma before returned. 66 | func DecodeKeyValue(k, v string) (string, string, error) { 67 | if !strings.HasSuffix(k, binHdrSuffix) { 68 | return k, v, nil 69 | } 70 | vvs := strings.Split(v, ",") 71 | for i, vv := range vvs { 72 | val, err := base64.StdEncoding.DecodeString(vv) 73 | if err != nil { 74 | return "", "", err 75 | } 76 | vvs[i] = string(val) 77 | } 78 | return k, strings.Join(vvs, ","), nil 79 | } 80 | 81 | // MD is a mapping from metadata keys to values. Users should use the following 82 | // two convenience functions New and Pairs to generate MD. 83 | type MD map[string][]string 84 | 85 | // New creates a MD from given key-value map. 86 | // Keys are automatically converted to lowercase. And for keys having "-bin" as suffix, their values will be applied Base64 encoding. 87 | func New(m map[string]string) MD { 88 | md := MD{} 89 | for k, v := range m { 90 | key, val := encodeKeyValue(k, v) 91 | md[key] = append(md[key], val) 92 | } 93 | return md 94 | } 95 | 96 | // Pairs returns an MD formed by the mapping of key, value ... 97 | // Pairs panics if len(kv) is odd. 98 | // Keys are automatically converted to lowercase. And for keys having "-bin" as suffix, their values will be appplied Base64 encoding. 99 | func Pairs(kv ...string) MD { 100 | if len(kv)%2 == 1 { 101 | panic(fmt.Sprintf("metadata: Pairs got the odd number of input pairs for metadata: %d", len(kv))) 102 | } 103 | md := MD{} 104 | var k string 105 | for i, s := range kv { 106 | if i%2 == 0 { 107 | k = s 108 | continue 109 | } 110 | key, val := encodeKeyValue(k, s) 111 | md[key] = append(md[key], val) 112 | } 113 | return md 114 | } 115 | 116 | // Len returns the number of items in md. 117 | func (md MD) Len() int { 118 | return len(md) 119 | } 120 | 121 | // Copy returns a copy of md. 122 | func (md MD) Copy() MD { 123 | return Join(md) 124 | } 125 | 126 | // Join joins any number of MDs into a single MD. 127 | // The order of values for each key is determined by the order in which 128 | // the MDs containing those values are presented to Join. 129 | func Join(mds ...MD) MD { 130 | out := MD{} 131 | for _, md := range mds { 132 | for k, v := range md { 133 | out[k] = append(out[k], v...) 134 | } 135 | } 136 | return out 137 | } 138 | 139 | type mdKey struct{} 140 | 141 | // NewContext creates a new context with md attached. 142 | func NewContext(ctx context.Context, md MD) context.Context { 143 | return context.WithValue(ctx, mdKey{}, md) 144 | } 145 | 146 | // FromContext returns the MD in ctx if it exists. 147 | // The returned md should be immutable, writing to it may cause races. 148 | // Modification should be made to the copies of the returned md. 149 | func FromContext(ctx context.Context) (md MD, ok bool) { 150 | md, ok = ctx.Value(mdKey{}).(MD) 151 | return 152 | } 153 | -------------------------------------------------------------------------------- /metadata/metadata_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package metadata 35 | 36 | import ( 37 | "reflect" 38 | "testing" 39 | ) 40 | 41 | const binaryValue = string(128) 42 | 43 | func TestEncodeKeyValue(t *testing.T) { 44 | for _, test := range []struct { 45 | // input 46 | kin string 47 | vin string 48 | // output 49 | kout string 50 | vout string 51 | }{ 52 | {"key", "abc", "key", "abc"}, 53 | {"KEY", "abc", "key", "abc"}, 54 | {"key-bin", "abc", "key-bin", "YWJj"}, 55 | {"key-bin", binaryValue, "key-bin", "woA="}, 56 | } { 57 | k, v := encodeKeyValue(test.kin, test.vin) 58 | if k != test.kout || !reflect.DeepEqual(v, test.vout) { 59 | t.Fatalf("encodeKeyValue(%q, %q) = %q, %q, want %q, %q", test.kin, test.vin, k, v, test.kout, test.vout) 60 | } 61 | } 62 | } 63 | 64 | func TestDecodeKeyValue(t *testing.T) { 65 | for _, test := range []struct { 66 | // input 67 | kin string 68 | vin string 69 | // output 70 | kout string 71 | vout string 72 | err error 73 | }{ 74 | {"a", "abc", "a", "abc", nil}, 75 | {"key-bin", "Zm9vAGJhcg==", "key-bin", "foo\x00bar", nil}, 76 | {"key-bin", "woA=", "key-bin", binaryValue, nil}, 77 | {"a", "abc,efg", "a", "abc,efg", nil}, 78 | {"key-bin", "Zm9vAGJhcg==,Zm9vAGJhcg==", "key-bin", "foo\x00bar,foo\x00bar", nil}, 79 | } { 80 | k, v, err := DecodeKeyValue(test.kin, test.vin) 81 | if k != test.kout || !reflect.DeepEqual(v, test.vout) || !reflect.DeepEqual(err, test.err) { 82 | t.Fatalf("DecodeKeyValue(%q, %q) = %q, %q, %v, want %q, %q, %v", test.kin, test.vin, k, v, err, test.kout, test.vout, test.err) 83 | } 84 | } 85 | } 86 | 87 | func TestPairsMD(t *testing.T) { 88 | for _, test := range []struct { 89 | // input 90 | kv []string 91 | // output 92 | md MD 93 | size int 94 | }{ 95 | {[]string{}, MD{}, 0}, 96 | {[]string{"k1", "v1", "k2-bin", binaryValue}, New(map[string]string{ 97 | "k1": "v1", 98 | "k2-bin": binaryValue, 99 | }), 2}, 100 | } { 101 | md := Pairs(test.kv...) 102 | if !reflect.DeepEqual(md, test.md) { 103 | t.Fatalf("Pairs(%v) = %v, want %v", test.kv, md, test.md) 104 | } 105 | if md.Len() != test.size { 106 | t.Fatalf("Pairs(%v) generates md of size %d, want %d", test.kv, md.Len(), test.size) 107 | } 108 | } 109 | } 110 | 111 | func TestCopy(t *testing.T) { 112 | const key, val = "key", "val" 113 | orig := Pairs(key, val) 114 | copy := orig.Copy() 115 | if !reflect.DeepEqual(orig, copy) { 116 | t.Errorf("copied value not equal to the original, got %v, want %v", copy, orig) 117 | } 118 | orig[key][0] = "foo" 119 | if v := copy[key][0]; v != val { 120 | t.Errorf("change in original should not affect copy, got %q, want %q", v, val) 121 | } 122 | } 123 | 124 | func TestJoin(t *testing.T) { 125 | for _, test := range []struct { 126 | mds []MD 127 | want MD 128 | }{ 129 | {[]MD{}, MD{}}, 130 | {[]MD{Pairs("foo", "bar")}, Pairs("foo", "bar")}, 131 | {[]MD{Pairs("foo", "bar"), Pairs("foo", "baz")}, Pairs("foo", "bar", "foo", "baz")}, 132 | {[]MD{Pairs("foo", "bar"), Pairs("foo", "baz"), Pairs("zip", "zap")}, Pairs("foo", "bar", "foo", "baz", "zip", "zap")}, 133 | } { 134 | md := Join(test.mds...) 135 | if !reflect.DeepEqual(md, test.want) { 136 | t.Errorf("context's metadata is %v, want %v", md, test.want) 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /naming/naming.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | // Package naming defines the naming API and related data structures for gRPC. 35 | // The interface is EXPERIMENTAL and may be suject to change. 36 | package naming 37 | 38 | // Operation defines the corresponding operations for a name resolution change. 39 | type Operation uint8 40 | 41 | const ( 42 | // Add indicates a new address is added. 43 | Add Operation = iota 44 | // Delete indicates an exisiting address is deleted. 45 | Delete 46 | ) 47 | 48 | // Update defines a name resolution update. Notice that it is not valid having both 49 | // empty string Addr and nil Metadata in an Update. 50 | type Update struct { 51 | // Op indicates the operation of the update. 52 | Op Operation 53 | // Addr is the updated address. It is empty string if there is no address update. 54 | Addr string 55 | // Metadata is the updated metadata. It is nil if there is no metadata update. 56 | // Metadata is not required for a custom naming implementation. 57 | Metadata interface{} 58 | } 59 | 60 | // Resolver creates a Watcher for a target to track its resolution changes. 61 | type Resolver interface { 62 | // Resolve creates a Watcher for target. 63 | Resolve(target string) (Watcher, error) 64 | } 65 | 66 | // Watcher watches for the updates on the specified target. 67 | type Watcher interface { 68 | // Next blocks until an update or error happens. It may return one or more 69 | // updates. The first call should get the full set of the results. It should 70 | // return an error if and only if Watcher cannot recover. 71 | Next() ([]*Update, error) 72 | // Close closes the Watcher. 73 | Close() 74 | } 75 | -------------------------------------------------------------------------------- /peer/peer.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | // Package peer defines various peer information associated with RPCs and 35 | // corresponding utils. 36 | package peer 37 | 38 | import ( 39 | "net" 40 | 41 | "golang.org/x/net/context" 42 | "google.golang.org/grpc/credentials" 43 | ) 44 | 45 | // Peer contains the information of the peer for an RPC. 46 | type Peer struct { 47 | // Addr is the peer address. 48 | Addr net.Addr 49 | // AuthInfo is the authentication information of the transport. 50 | // It is nil if there is no transport security being used. 51 | AuthInfo credentials.AuthInfo 52 | } 53 | 54 | type peerKey struct{} 55 | 56 | // NewContext creates a new context with peer information attached. 57 | func NewContext(ctx context.Context, p *Peer) context.Context { 58 | return context.WithValue(ctx, peerKey{}, p) 59 | } 60 | 61 | // FromContext returns the peer information in ctx if it exists. 62 | func FromContext(ctx context.Context) (p *Peer, ok bool) { 63 | p, ok = ctx.Value(peerKey{}).(*Peer) 64 | return 65 | } 66 | -------------------------------------------------------------------------------- /reflection/README.md: -------------------------------------------------------------------------------- 1 | # Reflection 2 | 3 | Package reflection implements server reflection service. 4 | 5 | The service implemented is defined in: https://github.com/grpc/grpc/blob/master/src/proto/grpc/reflection/v1alpha/reflection.proto. 6 | 7 | To register server reflection on a gRPC server: 8 | ```go 9 | import "google.golang.org/grpc/reflection" 10 | 11 | s := grpc.NewServer() 12 | pb.RegisterYourOwnServer(s, &server{}) 13 | 14 | // Register reflection service on gRPC server. 15 | reflection.Register(s) 16 | 17 | s.Serve(lis) 18 | ``` 19 | -------------------------------------------------------------------------------- /reflection/grpc_testing/proto2.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: proto2.proto 3 | // DO NOT EDIT! 4 | 5 | /* 6 | Package grpc_testing is a generated protocol buffer package. 7 | 8 | It is generated from these files: 9 | proto2.proto 10 | proto2_ext.proto 11 | proto2_ext2.proto 12 | test.proto 13 | 14 | It has these top-level messages: 15 | ToBeExtended 16 | Extension 17 | AnotherExtension 18 | SearchResponse 19 | SearchRequest 20 | */ 21 | package grpc_testing 22 | 23 | import proto "github.com/golang/protobuf/proto" 24 | import fmt "fmt" 25 | import math "math" 26 | 27 | // Reference imports to suppress errors if they are not otherwise used. 28 | var _ = proto.Marshal 29 | var _ = fmt.Errorf 30 | var _ = math.Inf 31 | 32 | // This is a compile-time assertion to ensure that this generated file 33 | // is compatible with the proto package it is being compiled against. 34 | // A compilation error at this line likely means your copy of the 35 | // proto package needs to be updated. 36 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 37 | 38 | type ToBeExtended struct { 39 | Foo *int32 `protobuf:"varint,1,req,name=foo" json:"foo,omitempty"` 40 | proto.XXX_InternalExtensions `json:"-"` 41 | XXX_unrecognized []byte `json:"-"` 42 | } 43 | 44 | func (m *ToBeExtended) Reset() { *m = ToBeExtended{} } 45 | func (m *ToBeExtended) String() string { return proto.CompactTextString(m) } 46 | func (*ToBeExtended) ProtoMessage() {} 47 | func (*ToBeExtended) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } 48 | 49 | var extRange_ToBeExtended = []proto.ExtensionRange{ 50 | {10, 30}, 51 | } 52 | 53 | func (*ToBeExtended) ExtensionRangeArray() []proto.ExtensionRange { 54 | return extRange_ToBeExtended 55 | } 56 | 57 | func (m *ToBeExtended) GetFoo() int32 { 58 | if m != nil && m.Foo != nil { 59 | return *m.Foo 60 | } 61 | return 0 62 | } 63 | 64 | func init() { 65 | proto.RegisterType((*ToBeExtended)(nil), "grpc.testing.ToBeExtended") 66 | } 67 | 68 | func init() { proto.RegisterFile("proto2.proto", fileDescriptor0) } 69 | 70 | var fileDescriptor0 = []byte{ 71 | // 86 bytes of a gzipped FileDescriptorProto 72 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x28, 0xca, 0x2f, 73 | 0xc9, 0x37, 0xd2, 0x03, 0x53, 0x42, 0x3c, 0xe9, 0x45, 0x05, 0xc9, 0x7a, 0x25, 0xa9, 0xc5, 0x25, 74 | 0x99, 0x79, 0xe9, 0x4a, 0x6a, 0x5c, 0x3c, 0x21, 0xf9, 0x4e, 0xa9, 0xae, 0x15, 0x25, 0xa9, 0x79, 75 | 0x29, 0xa9, 0x29, 0x42, 0x02, 0x5c, 0xcc, 0x69, 0xf9, 0xf9, 0x12, 0x8c, 0x0a, 0x4c, 0x1a, 0xac, 76 | 0x41, 0x20, 0xa6, 0x16, 0x0b, 0x07, 0x97, 0x80, 0x3c, 0x20, 0x00, 0x00, 0xff, 0xff, 0x74, 0x86, 77 | 0x9c, 0x08, 0x44, 0x00, 0x00, 0x00, 78 | } 79 | -------------------------------------------------------------------------------- /reflection/grpc_testing/proto2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package grpc.testing; 4 | 5 | message ToBeExtended { 6 | required int32 foo = 1; 7 | extensions 10 to 30; 8 | } 9 | -------------------------------------------------------------------------------- /reflection/grpc_testing/proto2_ext.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: proto2_ext.proto 3 | // DO NOT EDIT! 4 | 5 | package grpc_testing 6 | 7 | import proto "github.com/golang/protobuf/proto" 8 | import fmt "fmt" 9 | import math "math" 10 | 11 | // Reference imports to suppress errors if they are not otherwise used. 12 | var _ = proto.Marshal 13 | var _ = fmt.Errorf 14 | var _ = math.Inf 15 | 16 | type Extension struct { 17 | Whatzit *int32 `protobuf:"varint,1,opt,name=whatzit" json:"whatzit,omitempty"` 18 | XXX_unrecognized []byte `json:"-"` 19 | } 20 | 21 | func (m *Extension) Reset() { *m = Extension{} } 22 | func (m *Extension) String() string { return proto.CompactTextString(m) } 23 | func (*Extension) ProtoMessage() {} 24 | func (*Extension) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } 25 | 26 | func (m *Extension) GetWhatzit() int32 { 27 | if m != nil && m.Whatzit != nil { 28 | return *m.Whatzit 29 | } 30 | return 0 31 | } 32 | 33 | var E_Foo = &proto.ExtensionDesc{ 34 | ExtendedType: (*ToBeExtended)(nil), 35 | ExtensionType: (*int32)(nil), 36 | Field: 13, 37 | Name: "grpc.testing.foo", 38 | Tag: "varint,13,opt,name=foo", 39 | Filename: "proto2_ext.proto", 40 | } 41 | 42 | var E_Bar = &proto.ExtensionDesc{ 43 | ExtendedType: (*ToBeExtended)(nil), 44 | ExtensionType: (*Extension)(nil), 45 | Field: 17, 46 | Name: "grpc.testing.bar", 47 | Tag: "bytes,17,opt,name=bar", 48 | Filename: "proto2_ext.proto", 49 | } 50 | 51 | var E_Baz = &proto.ExtensionDesc{ 52 | ExtendedType: (*ToBeExtended)(nil), 53 | ExtensionType: (*SearchRequest)(nil), 54 | Field: 19, 55 | Name: "grpc.testing.baz", 56 | Tag: "bytes,19,opt,name=baz", 57 | Filename: "proto2_ext.proto", 58 | } 59 | 60 | func init() { 61 | proto.RegisterType((*Extension)(nil), "grpc.testing.Extension") 62 | proto.RegisterExtension(E_Foo) 63 | proto.RegisterExtension(E_Bar) 64 | proto.RegisterExtension(E_Baz) 65 | } 66 | 67 | func init() { proto.RegisterFile("proto2_ext.proto", fileDescriptor1) } 68 | 69 | var fileDescriptor1 = []byte{ 70 | // 179 bytes of a gzipped FileDescriptorProto 71 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0x28, 0x28, 0xca, 0x2f, 72 | 0xc9, 0x37, 0x8a, 0x4f, 0xad, 0x28, 0xd1, 0x03, 0x33, 0x85, 0x78, 0xd2, 0x8b, 0x0a, 0x92, 0xf5, 73 | 0x4a, 0x52, 0x8b, 0x4b, 0x32, 0xf3, 0xd2, 0xa5, 0x78, 0x20, 0xf2, 0x10, 0x39, 0x29, 0x2e, 0x90, 74 | 0x30, 0x84, 0xad, 0xa4, 0xca, 0xc5, 0xe9, 0x5a, 0x51, 0x92, 0x9a, 0x57, 0x9c, 0x99, 0x9f, 0x27, 75 | 0x24, 0xc1, 0xc5, 0x5e, 0x9e, 0x91, 0x58, 0x52, 0x95, 0x59, 0x22, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 76 | 0x1a, 0x04, 0xe3, 0x5a, 0xe9, 0x70, 0x31, 0xa7, 0xe5, 0xe7, 0x0b, 0x49, 0xe9, 0x21, 0x1b, 0xab, 77 | 0x17, 0x92, 0xef, 0x94, 0x0a, 0xd6, 0x9d, 0x92, 0x9a, 0x22, 0xc1, 0x0b, 0xd6, 0x01, 0x52, 0x66, 78 | 0xe5, 0xca, 0xc5, 0x9c, 0x94, 0x58, 0x84, 0x57, 0xb5, 0xa0, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0x38, 79 | 0xaa, 0x0a, 0xb8, 0x4b, 0x82, 0x40, 0xfa, 0xad, 0x3c, 0x41, 0xc6, 0x54, 0xe1, 0x35, 0x46, 0x18, 80 | 0x6c, 0x8c, 0x34, 0xaa, 0x8a, 0xe0, 0xd4, 0xc4, 0xa2, 0xe4, 0x8c, 0xa0, 0xd4, 0xc2, 0xd2, 0xd4, 81 | 0xe2, 0x12, 0x90, 0x51, 0x55, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x71, 0x6b, 0x94, 0x9f, 0x21, 82 | 0x01, 0x00, 0x00, 83 | } 84 | -------------------------------------------------------------------------------- /reflection/grpc_testing/proto2_ext.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package grpc.testing; 4 | 5 | import "proto2.proto"; 6 | import "test.proto"; 7 | 8 | extend ToBeExtended { 9 | optional int32 foo = 13; 10 | optional Extension bar = 17; 11 | optional SearchRequest baz = 19; 12 | } 13 | 14 | message Extension { 15 | optional int32 whatzit = 1; 16 | } 17 | -------------------------------------------------------------------------------- /reflection/grpc_testing/proto2_ext2.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: proto2_ext2.proto 3 | // DO NOT EDIT! 4 | 5 | package grpc_testing 6 | 7 | import proto "github.com/golang/protobuf/proto" 8 | import fmt "fmt" 9 | import math "math" 10 | 11 | // Reference imports to suppress errors if they are not otherwise used. 12 | var _ = proto.Marshal 13 | var _ = fmt.Errorf 14 | var _ = math.Inf 15 | 16 | type AnotherExtension struct { 17 | Whatchamacallit *int32 `protobuf:"varint,1,opt,name=whatchamacallit" json:"whatchamacallit,omitempty"` 18 | XXX_unrecognized []byte `json:"-"` 19 | } 20 | 21 | func (m *AnotherExtension) Reset() { *m = AnotherExtension{} } 22 | func (m *AnotherExtension) String() string { return proto.CompactTextString(m) } 23 | func (*AnotherExtension) ProtoMessage() {} 24 | func (*AnotherExtension) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } 25 | 26 | func (m *AnotherExtension) GetWhatchamacallit() int32 { 27 | if m != nil && m.Whatchamacallit != nil { 28 | return *m.Whatchamacallit 29 | } 30 | return 0 31 | } 32 | 33 | var E_Frob = &proto.ExtensionDesc{ 34 | ExtendedType: (*ToBeExtended)(nil), 35 | ExtensionType: (*string)(nil), 36 | Field: 23, 37 | Name: "grpc.testing.frob", 38 | Tag: "bytes,23,opt,name=frob", 39 | Filename: "proto2_ext2.proto", 40 | } 41 | 42 | var E_Nitz = &proto.ExtensionDesc{ 43 | ExtendedType: (*ToBeExtended)(nil), 44 | ExtensionType: (*AnotherExtension)(nil), 45 | Field: 29, 46 | Name: "grpc.testing.nitz", 47 | Tag: "bytes,29,opt,name=nitz", 48 | Filename: "proto2_ext2.proto", 49 | } 50 | 51 | func init() { 52 | proto.RegisterType((*AnotherExtension)(nil), "grpc.testing.AnotherExtension") 53 | proto.RegisterExtension(E_Frob) 54 | proto.RegisterExtension(E_Nitz) 55 | } 56 | 57 | func init() { proto.RegisterFile("proto2_ext2.proto", fileDescriptor2) } 58 | 59 | var fileDescriptor2 = []byte{ 60 | // 165 bytes of a gzipped FileDescriptorProto 61 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0x2c, 0x28, 0xca, 0x2f, 62 | 0xc9, 0x37, 0x8a, 0x4f, 0xad, 0x28, 0x31, 0xd2, 0x03, 0xb3, 0x85, 0x78, 0xd2, 0x8b, 0x0a, 0x92, 63 | 0xf5, 0x4a, 0x52, 0x8b, 0x4b, 0x32, 0xf3, 0xd2, 0xa5, 0x78, 0x20, 0x0a, 0x20, 0x72, 0x4a, 0x36, 64 | 0x5c, 0x02, 0x8e, 0x79, 0xf9, 0x25, 0x19, 0xa9, 0x45, 0xae, 0x15, 0x25, 0xa9, 0x79, 0xc5, 0x99, 65 | 0xf9, 0x79, 0x42, 0x1a, 0x5c, 0xfc, 0xe5, 0x19, 0x89, 0x25, 0xc9, 0x19, 0x89, 0xb9, 0x89, 0xc9, 66 | 0x89, 0x39, 0x39, 0x99, 0x25, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xac, 0x41, 0xe8, 0xc2, 0x56, 0x7a, 67 | 0x5c, 0x2c, 0x69, 0x45, 0xf9, 0x49, 0x42, 0x52, 0x7a, 0xc8, 0x56, 0xe8, 0x85, 0xe4, 0x3b, 0xa5, 68 | 0x82, 0x8d, 0x4b, 0x49, 0x4d, 0x91, 0x10, 0x57, 0x60, 0xd4, 0xe0, 0x0c, 0x02, 0xab, 0xb3, 0xf2, 69 | 0xe3, 0x62, 0xc9, 0xcb, 0x2c, 0xa9, 0xc2, 0xab, 0x5e, 0x56, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x0e, 70 | 0x55, 0x05, 0xba, 0x1b, 0x83, 0xc0, 0xe6, 0x00, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x7e, 0x0d, 71 | 0x26, 0xed, 0x00, 0x00, 0x00, 72 | } 73 | -------------------------------------------------------------------------------- /reflection/grpc_testing/proto2_ext2.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package grpc.testing; 4 | 5 | import "proto2.proto"; 6 | 7 | extend ToBeExtended { 8 | optional string frob = 23; 9 | optional AnotherExtension nitz = 29; 10 | } 11 | 12 | message AnotherExtension { 13 | optional int32 whatchamacallit = 1; 14 | } 15 | -------------------------------------------------------------------------------- /reflection/grpc_testing/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.testing; 4 | 5 | message SearchResponse { 6 | message Result { 7 | string url = 1; 8 | string title = 2; 9 | repeated string snippets = 3; 10 | } 11 | repeated Result results = 1; 12 | } 13 | 14 | message SearchRequest { 15 | string query = 1; 16 | } 17 | 18 | service SearchService { 19 | rpc Search(SearchRequest) returns (SearchResponse); 20 | rpc StreamingSearch(stream SearchRequest) returns (stream SearchResponse); 21 | } 22 | -------------------------------------------------------------------------------- /server_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2016, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package grpc 35 | 36 | import ( 37 | "net" 38 | "reflect" 39 | "strings" 40 | "testing" 41 | ) 42 | 43 | type emptyServiceServer interface{} 44 | 45 | type testServer struct{} 46 | 47 | func TestStopBeforeServe(t *testing.T) { 48 | lis, err := net.Listen("tcp", "localhost:0") 49 | if err != nil { 50 | t.Fatalf("failed to create listener: %v", err) 51 | } 52 | 53 | server := NewServer() 54 | server.Stop() 55 | err = server.Serve(lis) //xu:将lis传入stop过的serve,会默认将lis关闭。 56 | if err != ErrServerStopped { 57 | t.Fatalf("server.Serve() error = %v, want %v", err, ErrServerStopped) 58 | } 59 | 60 | // server.Serve is responsible for closing the listener, even if the 61 | // server was already stopped. 62 | err = lis.Close() 63 | if got, want := ErrorDesc(err), "use of closed network connection"; !strings.Contains(got, want) { 64 | t.Errorf("Close() error = %q, want %q", got, want) 65 | } 66 | } 67 | 68 | func TestGetServiceInfo(t *testing.T) { 69 | testSd := ServiceDesc{ 70 | ServiceName: "grpc.testing.EmptyService", 71 | HandlerType: (*emptyServiceServer)(nil), 72 | Methods: []MethodDesc{ 73 | { 74 | MethodName: "EmptyCall", 75 | Handler: nil, 76 | }, 77 | }, 78 | Streams: []StreamDesc{ 79 | { 80 | StreamName: "EmptyStream", 81 | Handler: nil, 82 | ServerStreams: false, 83 | ClientStreams: true, 84 | }, 85 | }, 86 | Metadata: []int{0, 2, 1, 3}, 87 | } 88 | 89 | server := NewServer() 90 | server.RegisterService(&testSd, &testServer{}) 91 | 92 | info := server.GetServiceInfo() 93 | want := map[string]ServiceInfo{ 94 | "grpc.testing.EmptyService": { 95 | Methods: []MethodInfo{ 96 | { 97 | Name: "EmptyCall", 98 | IsClientStream: false, 99 | IsServerStream: false, 100 | }, 101 | { 102 | Name: "EmptyStream", 103 | IsClientStream: true, 104 | IsServerStream: false, 105 | }}, 106 | Metadata: []int{0, 2, 1, 3}, 107 | }, 108 | } 109 | 110 | if !reflect.DeepEqual(info, want) { 111 | t.Errorf("GetServiceInfo() = %+v, want %+v", info, want) 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /stats/grpc_testing/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package grpc.testing; 4 | 5 | message SimpleRequest { 6 | int32 id = 2; 7 | } 8 | 9 | message SimpleResponse { 10 | int32 id = 3; 11 | } 12 | 13 | // A simple test service. 14 | service TestService { 15 | // One request followed by one response. 16 | // The server returns the client id as-is. 17 | rpc UnaryCall(SimpleRequest) returns (SimpleResponse); 18 | 19 | // A sequence of requests with each request served by the server immediately. 20 | // As one request could lead to multiple responses, this interface 21 | // demonstrates the idea of full duplexing. 22 | rpc FullDuplexCall(stream SimpleRequest) returns (stream SimpleResponse); 23 | } 24 | -------------------------------------------------------------------------------- /stats/handlers.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2016, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package stats 35 | 36 | import ( 37 | "net" 38 | 39 | "golang.org/x/net/context" 40 | ) 41 | 42 | // ConnTagInfo defines the relevant information needed by connection context tagger. 43 | type ConnTagInfo struct { 44 | // RemoteAddr is the remote address of the corresponding connection. 45 | RemoteAddr net.Addr 46 | // LocalAddr is the local address of the corresponding connection. 47 | LocalAddr net.Addr 48 | // TODO add QOS related fields. 49 | } 50 | 51 | // RPCTagInfo defines the relevant information needed by RPC context tagger. 52 | type RPCTagInfo struct { 53 | // FullMethodName is the RPC method in the format of /package.service/method. 54 | FullMethodName string 55 | } 56 | 57 | // Handler defines the interface for the related stats handling (e.g., RPCs, connections). 58 | type Handler interface { 59 | // TagRPC can attach some information to the given context. 60 | // The returned context is used in the rest lifetime of the RPC. 61 | TagRPC(context.Context, *RPCTagInfo) context.Context 62 | // HandleRPC processes the RPC stats. 63 | HandleRPC(context.Context, RPCStats) 64 | 65 | // TagConn can attach some information to the given context. 66 | // The returned context will be used for stats handling. 67 | // For conn stats handling, the context used in HandleConn for this 68 | // connection will be derived from the context returned. 69 | // For RPC stats handling, 70 | // - On server side, the context used in HandleRPC for all RPCs on this 71 | // connection will be derived from the context returned. 72 | // - On client side, the context is not derived from the context returned. 73 | TagConn(context.Context, *ConnTagInfo) context.Context 74 | // HandleConn processes the Conn stats. 75 | HandleConn(context.Context, ConnStats) 76 | } 77 | -------------------------------------------------------------------------------- /stress/client/testdata/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla 5 | Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 6 | YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT 7 | BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 8 | +L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu 9 | g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd 10 | Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV 11 | HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau 12 | sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m 13 | oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG 14 | Dfcog5wrJytaQ6UA0wE= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /stress/client/testdata/server1.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD 3 | M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf 4 | 3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY 5 | AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm 6 | V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY 7 | tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p 8 | dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q 9 | K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR 10 | 81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff 11 | DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd 12 | aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 13 | ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 14 | XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe 15 | F98XJ7tIFfJq 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /stress/client/testdata/server1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET 3 | MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ 4 | dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx 5 | MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV 6 | BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 7 | ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco 8 | LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg 9 | zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd 10 | 9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw 11 | CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy 12 | em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G 13 | CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 14 | hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh 15 | y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /stress/grpc_testing/metrics.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015-2016, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | // Contains the definitions for a metrics service and the type of metrics 31 | // exposed by the service. 32 | // 33 | // Currently, 'Gauge' (i.e a metric that represents the measured value of 34 | // something at an instant of time) is the only metric type supported by the 35 | // service. 36 | syntax = "proto3"; 37 | 38 | package grpc.testing; 39 | 40 | // Reponse message containing the gauge name and value 41 | message GaugeResponse { 42 | string name = 1; 43 | oneof value { 44 | int64 long_value = 2; 45 | double double_value = 3; 46 | string string_value = 4; 47 | } 48 | } 49 | 50 | // Request message containing the gauge name 51 | message GaugeRequest { 52 | string name = 1; 53 | } 54 | 55 | message EmptyMessage {} 56 | 57 | service MetricsService { 58 | // Returns the values of all the gauges that are currently being maintained by 59 | // the service 60 | rpc GetAllGauges(EmptyMessage) returns (stream GaugeResponse); 61 | 62 | // Returns the value of one gauge 63 | rpc GetGauge(GaugeRequest) returns (GaugeResponse); 64 | } 65 | -------------------------------------------------------------------------------- /stress/metrics_client/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2016, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package main 35 | 36 | import ( 37 | "flag" 38 | "fmt" 39 | "io" 40 | 41 | "golang.org/x/net/context" 42 | "google.golang.org/grpc" 43 | "google.golang.org/grpc/grpclog" 44 | metricspb "google.golang.org/grpc/stress/grpc_testing" 45 | ) 46 | 47 | var ( 48 | metricsServerAddress = flag.String("metrics_server_address", "", "The metrics server addresses in the fomrat :") 49 | totalOnly = flag.Bool("total_only", false, "If true, this prints only the total value of all gauges") 50 | ) 51 | 52 | func printMetrics(client metricspb.MetricsServiceClient, totalOnly bool) { 53 | stream, err := client.GetAllGauges(context.Background(), &metricspb.EmptyMessage{}) 54 | if err != nil { 55 | grpclog.Fatalf("failed to call GetAllGuages: %v", err) 56 | } 57 | 58 | var ( 59 | overallQPS int64 60 | rpcStatus error 61 | ) 62 | for { 63 | gaugeResponse, err := stream.Recv() 64 | if err != nil { 65 | rpcStatus = err 66 | break 67 | } 68 | if _, ok := gaugeResponse.GetValue().(*metricspb.GaugeResponse_LongValue); !ok { 69 | panic(fmt.Sprintf("gauge %s is not a long value", gaugeResponse.Name)) 70 | } 71 | v := gaugeResponse.GetLongValue() 72 | if !totalOnly { 73 | grpclog.Printf("%s: %d", gaugeResponse.Name, v) 74 | } 75 | overallQPS += v 76 | } 77 | if rpcStatus != io.EOF { 78 | grpclog.Fatalf("failed to finish server streaming: %v", rpcStatus) 79 | } 80 | grpclog.Printf("overall qps: %d", overallQPS) 81 | } 82 | 83 | func main() { 84 | flag.Parse() 85 | if *metricsServerAddress == "" { 86 | grpclog.Fatalf("Metrics server address is empty.") 87 | } 88 | 89 | conn, err := grpc.Dial(*metricsServerAddress, grpc.WithInsecure()) 90 | if err != nil { 91 | grpclog.Fatalf("cannot connect to metrics server: %v", err) 92 | } 93 | defer conn.Close() 94 | 95 | c := metricspb.NewMetricsServiceClient(conn) 96 | printMetrics(c, *totalOnly) 97 | } 98 | -------------------------------------------------------------------------------- /tap/tap.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2016, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | // Package tap defines the function handles which are executed on the transport 35 | // layer of gRPC-Go and related information. Everything here is EXPERIMENTAL. 36 | package tap 37 | 38 | import ( 39 | "golang.org/x/net/context" 40 | ) 41 | 42 | // Info defines the relevant information needed by the handles. 43 | type Info struct { 44 | // FullMethodName is the string of grpc method (in the format of 45 | // /package.service/method). 46 | FullMethodName string 47 | // TODO: More to be added. 48 | } 49 | 50 | // ServerInHandle defines the function which runs when a new stream is created 51 | // on the server side. Note that it is executed in the per-connection I/O goroutine(s) instead 52 | // of per-RPC goroutine. Therefore, users should NOT have any blocking/time-consuming 53 | // work in this handle. Otherwise all the RPCs would slow down. 54 | type ServerInHandle func(ctx context.Context, info *Info) (context.Context, error) 55 | -------------------------------------------------------------------------------- /test/codec_perf/perf.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. 2 | // source: perf.proto 3 | // DO NOT EDIT! 4 | 5 | /* 6 | Package codec_perf is a generated protocol buffer package. 7 | 8 | It is generated from these files: 9 | perf.proto 10 | 11 | It has these top-level messages: 12 | Buffer 13 | */ 14 | package codec_perf 15 | 16 | import proto "github.com/golang/protobuf/proto" 17 | import fmt "fmt" 18 | import math "math" 19 | 20 | // Reference imports to suppress errors if they are not otherwise used. 21 | var _ = proto.Marshal 22 | var _ = fmt.Errorf 23 | var _ = math.Inf 24 | 25 | // This is a compile-time assertion to ensure that this generated file 26 | // is compatible with the proto package it is being compiled against. 27 | // A compilation error at this line likely means your copy of the 28 | // proto package needs to be updated. 29 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 30 | 31 | // Buffer is a message that contains a body of bytes that is used to exercise 32 | // encoding and decoding overheads. 33 | type Buffer struct { 34 | Body []byte `protobuf:"bytes,1,opt,name=body" json:"body,omitempty"` 35 | XXX_unrecognized []byte `json:"-"` 36 | } 37 | 38 | func (m *Buffer) Reset() { *m = Buffer{} } 39 | func (m *Buffer) String() string { return proto.CompactTextString(m) } 40 | func (*Buffer) ProtoMessage() {} 41 | func (*Buffer) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } 42 | 43 | func (m *Buffer) GetBody() []byte { 44 | if m != nil { 45 | return m.Body 46 | } 47 | return nil 48 | } 49 | 50 | func init() { 51 | proto.RegisterType((*Buffer)(nil), "codec.perf.Buffer") 52 | } 53 | 54 | func init() { proto.RegisterFile("perf.proto", fileDescriptor0) } 55 | 56 | var fileDescriptor0 = []byte{ 57 | // 73 bytes of a gzipped FileDescriptorProto 58 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0x48, 0x2d, 0x4a, 59 | 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x4a, 0xce, 0x4f, 0x49, 0x4d, 0xd6, 0x03, 0x89, 60 | 0x28, 0xc9, 0x70, 0xb1, 0x39, 0x95, 0xa6, 0xa5, 0xa5, 0x16, 0x09, 0x09, 0x71, 0xb1, 0x24, 0xe5, 61 | 0xa7, 0x54, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x04, 0x81, 0xd9, 0x80, 0x00, 0x00, 0x00, 0xff, 62 | 0xff, 0x3a, 0x58, 0x92, 0x53, 0x36, 0x00, 0x00, 0x00, 63 | } 64 | -------------------------------------------------------------------------------- /test/codec_perf/perf.proto: -------------------------------------------------------------------------------- 1 | // Messages used for performance tests that may not reference grpc directly for 2 | // reasons of import cycles. 3 | syntax = "proto2"; 4 | 5 | package codec.perf; 6 | 7 | // Buffer is a message that contains a body of bytes that is used to exercise 8 | // encoding and decoding overheads. 9 | message Buffer { 10 | optional bytes body = 1; 11 | } 12 | -------------------------------------------------------------------------------- /test/grpc_testing/test.proto: -------------------------------------------------------------------------------- 1 | // An integration test service that covers all the method signature permutations 2 | // of unary/streaming requests/responses. 3 | syntax = "proto2"; 4 | 5 | package grpc.testing; 6 | 7 | message Empty {} 8 | 9 | // The type of payload that should be returned. 10 | enum PayloadType { 11 | // Compressable text format. 12 | COMPRESSABLE = 0; 13 | 14 | // Uncompressable binary format. 15 | UNCOMPRESSABLE = 1; 16 | 17 | // Randomly chosen from all other formats defined in this enum. 18 | RANDOM = 2; 19 | } 20 | 21 | // A block of data, to simply increase gRPC message size. 22 | message Payload { 23 | // The type of data in body. 24 | optional PayloadType type = 1; 25 | // Primary contents of payload. 26 | optional bytes body = 2; 27 | } 28 | 29 | // Unary request. 30 | message SimpleRequest { 31 | // Desired payload type in the response from the server. 32 | // If response_type is RANDOM, server randomly chooses one from other formats. 33 | optional PayloadType response_type = 1; 34 | 35 | // Desired payload size in the response from the server. 36 | // If response_type is COMPRESSABLE, this denotes the size before compression. 37 | optional int32 response_size = 2; 38 | 39 | // Optional input payload sent along with the request. 40 | optional Payload payload = 3; 41 | 42 | // Whether SimpleResponse should include username. 43 | optional bool fill_username = 4; 44 | 45 | // Whether SimpleResponse should include OAuth scope. 46 | optional bool fill_oauth_scope = 5; 47 | } 48 | 49 | // Unary response, as configured by the request. 50 | message SimpleResponse { 51 | // Payload to increase message size. 52 | optional Payload payload = 1; 53 | 54 | // The user the request came from, for verifying authentication was 55 | // successful when the client expected it. 56 | optional string username = 2; 57 | 58 | // OAuth scope. 59 | optional string oauth_scope = 3; 60 | } 61 | 62 | // Client-streaming request. 63 | message StreamingInputCallRequest { 64 | // Optional input payload sent along with the request. 65 | optional Payload payload = 1; 66 | 67 | // Not expecting any payload from the response. 68 | } 69 | 70 | // Client-streaming response. 71 | message StreamingInputCallResponse { 72 | // Aggregated size of payloads received from the client. 73 | optional int32 aggregated_payload_size = 1; 74 | } 75 | 76 | // Configuration for a particular response. 77 | message ResponseParameters { 78 | // Desired payload sizes in responses from the server. 79 | // If response_type is COMPRESSABLE, this denotes the size before compression. 80 | optional int32 size = 1; 81 | 82 | // Desired interval between consecutive responses in the response stream in 83 | // microseconds. 84 | optional int32 interval_us = 2; 85 | } 86 | 87 | // Server-streaming request. 88 | message StreamingOutputCallRequest { 89 | // Desired payload type in the response from the server. 90 | // If response_type is RANDOM, the payload from each response in the stream 91 | // might be of different types. This is to simulate a mixed type of payload 92 | // stream. 93 | optional PayloadType response_type = 1; 94 | 95 | // Configuration for each expected response message. 96 | repeated ResponseParameters response_parameters = 2; 97 | 98 | // Optional input payload sent along with the request. 99 | optional Payload payload = 3; 100 | } 101 | 102 | // Server-streaming response, as configured by the request and parameters. 103 | message StreamingOutputCallResponse { 104 | // Payload to increase response size. 105 | optional Payload payload = 1; 106 | } 107 | 108 | // A simple service to test the various types of RPCs and experiment with 109 | // performance with various types of payload. 110 | service TestService { 111 | // One empty request followed by one empty response. 112 | rpc EmptyCall(Empty) returns (Empty); 113 | 114 | // One request followed by one response. 115 | // The server returns the client payload as-is. 116 | rpc UnaryCall(SimpleRequest) returns (SimpleResponse); 117 | 118 | // One request followed by a sequence of responses (streamed download). 119 | // The server returns the payload with client desired type and sizes. 120 | rpc StreamingOutputCall(StreamingOutputCallRequest) 121 | returns (stream StreamingOutputCallResponse); 122 | 123 | // A sequence of requests followed by one response (streamed upload). 124 | // The server returns the aggregated size of client payload as the result. 125 | rpc StreamingInputCall(stream StreamingInputCallRequest) 126 | returns (StreamingInputCallResponse); 127 | 128 | // A sequence of requests with each request served by the server immediately. 129 | // As one request could lead to multiple responses, this interface 130 | // demonstrates the idea of full duplexing. 131 | rpc FullDuplexCall(stream StreamingOutputCallRequest) 132 | returns (stream StreamingOutputCallResponse); 133 | 134 | // A sequence of requests followed by a sequence of responses. 135 | // The server buffers all the client requests and then serves them in order. A 136 | // stream of responses are returned to the client when the server starts with 137 | // first request. 138 | rpc HalfDuplexCall(stream StreamingOutputCallRequest) 139 | returns (stream StreamingOutputCallResponse); 140 | } 141 | -------------------------------------------------------------------------------- /test/race_test.go: -------------------------------------------------------------------------------- 1 | // +build race 2 | 3 | /* 4 | * Copyright 2016, Google Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are 9 | * met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following disclaimer 15 | * in the documentation and/or other materials provided with the 16 | * distribution. 17 | * * Neither the name of Google Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | package grpc_test 36 | 37 | func init() { 38 | raceMode = true 39 | } 40 | -------------------------------------------------------------------------------- /test/testdata/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla 5 | Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 6 | YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT 7 | BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 8 | +L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu 9 | g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd 10 | Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV 11 | HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau 12 | sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m 13 | oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG 14 | Dfcog5wrJytaQ6UA0wE= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /test/testdata/server1.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD 3 | M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf 4 | 3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY 5 | AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm 6 | V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY 7 | tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p 8 | dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q 9 | K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR 10 | 81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff 11 | DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd 12 | aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 13 | ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 14 | XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe 15 | F98XJ7tIFfJq 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /test/testdata/server1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET 3 | MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ 4 | dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx 5 | MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV 6 | BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 7 | ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco 8 | LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg 9 | zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd 10 | 9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw 11 | CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy 12 | em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G 13 | CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 14 | hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh 15 | y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /testdata/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla 5 | Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 6 | YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT 7 | BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 8 | +L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu 9 | g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd 10 | Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV 11 | HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau 12 | sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m 13 | oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG 14 | Dfcog5wrJytaQ6UA0wE= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /testdata/server1.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD 3 | M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf 4 | 3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY 5 | AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm 6 | V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY 7 | tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p 8 | dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q 9 | K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR 10 | 81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff 11 | DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd 12 | aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 13 | ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 14 | XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe 15 | F98XJ7tIFfJq 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /testdata/server1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET 3 | MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ 4 | dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx 5 | MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV 6 | BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 7 | ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco 8 | LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg 9 | zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd 10 | 9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw 11 | CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy 12 | em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G 13 | CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 14 | hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh 15 | y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /trace.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2015, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package grpc 35 | 36 | import ( 37 | "bytes" 38 | "fmt" 39 | "io" 40 | "net" 41 | "strings" 42 | "time" 43 | 44 | "golang.org/x/net/trace" 45 | ) 46 | 47 | // EnableTracing controls whether to trace RPCs using the golang.org/x/net/trace package. 48 | // This should only be set before any RPCs are sent or received by this program. 49 | var EnableTracing = true 50 | 51 | // methodFamily returns the trace family for the given method. 52 | // It turns "/pkg.Service/GetFoo" into "pkg.Service". 53 | func methodFamily(m string) string { 54 | m = strings.TrimPrefix(m, "/") // remove leading slash 55 | if i := strings.Index(m, "/"); i >= 0 { 56 | m = m[:i] // remove everything from second slash 57 | } 58 | if i := strings.LastIndex(m, "."); i >= 0 { 59 | m = m[i+1:] // cut down to last dotted component 60 | } 61 | return m 62 | } 63 | 64 | // traceInfo contains tracing information for an RPC. 65 | type traceInfo struct { 66 | tr trace.Trace 67 | firstLine firstLine 68 | } 69 | 70 | // firstLine is the first line of an RPC trace. 71 | type firstLine struct { 72 | client bool // whether this is a client (outgoing) RPC 73 | remoteAddr net.Addr 74 | deadline time.Duration // may be zero 75 | } 76 | 77 | func (f *firstLine) String() string { 78 | var line bytes.Buffer 79 | io.WriteString(&line, "RPC: ") 80 | if f.client { 81 | io.WriteString(&line, "to") 82 | } else { 83 | io.WriteString(&line, "from") 84 | } 85 | fmt.Fprintf(&line, " %v deadline:", f.remoteAddr) 86 | if f.deadline != 0 { 87 | fmt.Fprint(&line, f.deadline) 88 | } else { 89 | io.WriteString(&line, "none") 90 | } 91 | return line.String() 92 | } 93 | 94 | // payload represents an RPC request or response payload. 95 | type payload struct { 96 | sent bool // whether this is an outgoing payload 97 | msg interface{} // e.g. a proto.Message 98 | // TODO(dsymonds): add stringifying info to codec, and limit how much we hold here? 99 | } 100 | 101 | func (p payload) String() string { 102 | if p.sent { 103 | return fmt.Sprintf("sent: %v", p.msg) 104 | } 105 | return fmt.Sprintf("recv: %v", p.msg) 106 | } 107 | 108 | type fmtStringer struct { 109 | format string 110 | a []interface{} 111 | } 112 | 113 | func (f *fmtStringer) String() string { 114 | return fmt.Sprintf(f.format, f.a...) 115 | } 116 | 117 | type stringer string 118 | 119 | func (s stringer) String() string { return string(s) } 120 | -------------------------------------------------------------------------------- /transport/control.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package transport 35 | 36 | import ( 37 | "fmt" 38 | "sync" 39 | 40 | "golang.org/x/net/http2" 41 | ) 42 | 43 | const ( 44 | // The default value of flow control window size in HTTP2 spec. 45 | defaultWindowSize = 65535 46 | // The initial window size for flow control. 47 | initialWindowSize = defaultWindowSize // for an RPC 48 | initialConnWindowSize = defaultWindowSize * 16 // for a connection 49 | ) 50 | 51 | // The following defines various control items which could flow through 52 | // the control buffer of transport. They represent different aspects of 53 | // control tasks, e.g., flow control, settings, streaming resetting, etc. 54 | type windowUpdate struct { 55 | streamID uint32 56 | increment uint32 57 | } 58 | 59 | func (*windowUpdate) item() {} 60 | 61 | type settings struct { 62 | ack bool 63 | ss []http2.Setting 64 | } 65 | 66 | func (*settings) item() {} 67 | 68 | type resetStream struct { 69 | streamID uint32 70 | code http2.ErrCode 71 | } 72 | 73 | func (*resetStream) item() {} 74 | 75 | type goAway struct { 76 | } 77 | 78 | func (*goAway) item() {} 79 | 80 | type flushIO struct { 81 | } 82 | 83 | func (*flushIO) item() {} 84 | 85 | type ping struct { 86 | ack bool 87 | data [8]byte 88 | } 89 | 90 | func (*ping) item() {} 91 | 92 | // quotaPool is a pool which accumulates the quota and sends it to acquire() 93 | // when it is available. 94 | // xu: 用于发送流控。 将当前可用的quota(字节数)写入c,有数据发送需要时,从c中获取。 95 | // acquire 将quota全部获取出来,根据实际使用量,将未使用的重新add回pool。 96 | type quotaPool struct { 97 | c chan int 98 | 99 | mu sync.Mutex 100 | quota int 101 | } 102 | 103 | // newQuotaPool creates a quotaPool which has quota q available to consume. 104 | func newQuotaPool(q int) *quotaPool { 105 | qb := "aPool{ 106 | c: make(chan int, 1), 107 | } 108 | if q > 0 { 109 | qb.c <- q 110 | } else { 111 | qb.quota = q 112 | } 113 | return qb 114 | } 115 | 116 | // add cancels the pending quota sent on acquired, incremented by v and sends 117 | // it back on acquire. 118 | func (qb *quotaPool) add(v int) { 119 | qb.mu.Lock() 120 | defer qb.mu.Unlock() 121 | select { 122 | case n := <-qb.c: 123 | qb.quota += n 124 | default: 125 | } 126 | qb.quota += v 127 | if qb.quota <= 0 { 128 | return 129 | } 130 | // After the pool has been created, this is the only place that sends on 131 | // the channel. Since mu is held at this point and any quota that was sent 132 | // on the channel has been retrieved, we know that this code will always 133 | // place any positive quota value on the channel. 134 | select { 135 | case qb.c <- qb.quota: 136 | qb.quota = 0 137 | default: 138 | } 139 | } 140 | 141 | // acquire returns the channel on which available quota amounts are sent. 142 | func (qb *quotaPool) acquire() <-chan int { 143 | return qb.c 144 | } 145 | 146 | // inFlow deals with inbound flow control 147 | // xu:用于接收流控。 148 | type inFlow struct { 149 | // The inbound flow control limit for pending data. 150 | limit uint32 151 | 152 | mu sync.Mutex 153 | // pendingData is the overall data which have been received but not been 154 | // consumed by applications. 155 | pendingData uint32 156 | // The amount of data the application has consumed but grpc has not sent 157 | // window update for them. Used to reduce window update frequency. 158 | pendingUpdate uint32 159 | } 160 | 161 | // onData is invoked when some data frame is received. It updates pendingData. 162 | func (f *inFlow) onData(n uint32) error { 163 | f.mu.Lock() 164 | defer f.mu.Unlock() 165 | f.pendingData += n 166 | if f.pendingData+f.pendingUpdate > f.limit { 167 | return fmt.Errorf("received %d-bytes data exceeding the limit %d bytes", f.pendingData+f.pendingUpdate, f.limit) 168 | } 169 | return nil 170 | } 171 | 172 | // onRead is invoked when the application reads the data. It returns the window size 173 | // to be sent to the peer. 174 | func (f *inFlow) onRead(n uint32) uint32 { 175 | f.mu.Lock() 176 | defer f.mu.Unlock() 177 | if f.pendingData == 0 { 178 | return 0 179 | } 180 | f.pendingData -= n 181 | f.pendingUpdate += n 182 | if f.pendingUpdate >= f.limit/4 { 183 | wu := f.pendingUpdate 184 | f.pendingUpdate = 0 185 | return wu 186 | } 187 | return 0 188 | } 189 | 190 | func (f *inFlow) resetPendingData() uint32 { 191 | f.mu.Lock() 192 | defer f.mu.Unlock() 193 | n := f.pendingData 194 | f.pendingData = 0 195 | return n 196 | } 197 | -------------------------------------------------------------------------------- /transport/go16.go: -------------------------------------------------------------------------------- 1 | // +build go1.6,!go1.7 2 | 3 | /* 4 | * Copyright 2016, Google Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are 9 | * met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following disclaimer 15 | * in the documentation and/or other materials provided with the 16 | * distribution. 17 | * * Neither the name of Google Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | package transport 36 | 37 | import ( 38 | "net" 39 | 40 | "golang.org/x/net/context" 41 | ) 42 | 43 | // dialContext connects to the address on the named network. 44 | func dialContext(ctx context.Context, network, address string) (net.Conn, error) { 45 | return (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address) 46 | } 47 | -------------------------------------------------------------------------------- /transport/go17.go: -------------------------------------------------------------------------------- 1 | // +build go1.7 2 | 3 | /* 4 | * Copyright 2016, Google Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are 9 | * met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following disclaimer 15 | * in the documentation and/or other materials provided with the 16 | * distribution. 17 | * * Neither the name of Google Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | package transport 36 | 37 | import ( 38 | "net" 39 | 40 | "golang.org/x/net/context" 41 | ) 42 | 43 | // dialContext connects to the address on the named network. 44 | func dialContext(ctx context.Context, network, address string) (net.Conn, error) { 45 | return (&net.Dialer{}).DialContext(ctx, network, address) 46 | } 47 | -------------------------------------------------------------------------------- /transport/http_util_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2014, Google Inc. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above 13 | * copyright notice, this list of conditions and the following disclaimer 14 | * in the documentation and/or other materials provided with the 15 | * distribution. 16 | * * Neither the name of Google Inc. nor the names of its 17 | * contributors may be used to endorse or promote products derived from 18 | * this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | 34 | package transport 35 | 36 | import ( 37 | "fmt" 38 | "testing" 39 | "time" 40 | ) 41 | 42 | func TestTimeoutEncode(t *testing.T) { 43 | for i, test := range []struct { 44 | in string 45 | out string 46 | }{ 47 | {"12345678ns", "12345678n"}, 48 | {"123456789ns", "123457u"}, 49 | {"12345678us", "12345678u"}, 50 | {"123456789us", "123457m"}, 51 | {"12345678ms", "12345678m"}, 52 | {"123456789ms", "123457S"}, 53 | {"12345678s", "12345678S"}, 54 | {"123456789s", "2057614M"}, 55 | {"12345678m", "12345678M"}, 56 | {"123456789m", "2057614H"}, 57 | } { 58 | d, err := time.ParseDuration(test.in) 59 | if err != nil { 60 | t.Fatalf("failed to parse duration string %s: %v", test.in, err) 61 | } 62 | 63 | out := encodeTimeout(d) 64 | if out != test.out { 65 | t.Fatalf("timeoutEncode(%s) = %s, want %s", test.in, out, test.out) 66 | } 67 | fmt.Printf("%d: in %s, d %d, out %s\n", i, test.in, d, test.out) 68 | } 69 | } 70 | 71 | func TestTimeoutDecode(t *testing.T) { 72 | for _, test := range []struct { 73 | // input 74 | s string 75 | // output 76 | d time.Duration 77 | err error 78 | }{ 79 | {"1234S", time.Second * 1234, nil}, 80 | {"1234x", 0, fmt.Errorf("transport: timeout unit is not recognized: %q", "1234x")}, 81 | {"1", 0, fmt.Errorf("transport: timeout string is too short: %q", "1")}, 82 | {"", 0, fmt.Errorf("transport: timeout string is too short: %q", "")}, 83 | } { 84 | d, err := decodeTimeout(test.s) 85 | if d != test.d || fmt.Sprint(err) != fmt.Sprint(test.err) { 86 | t.Fatalf("timeoutDecode(%q) = %d, %v, want %d, %v", test.s, int64(d), err, int64(test.d), test.err) 87 | } 88 | } 89 | } 90 | 91 | func TestValidContentType(t *testing.T) { 92 | tests := []struct { 93 | h string 94 | want bool 95 | }{ 96 | {"application/grpc", true}, 97 | {"application/grpc+", true}, 98 | {"application/grpc+blah", true}, 99 | {"application/grpc;", true}, 100 | {"application/grpc;blah", true}, 101 | {"application/grpcd", false}, 102 | {"application/grpd", false}, 103 | {"application/grp", false}, 104 | } 105 | for _, tt := range tests { 106 | got := validContentType(tt.h) 107 | if got != tt.want { 108 | t.Errorf("validContentType(%q) = %v; want %v", tt.h, got, tt.want) 109 | } 110 | } 111 | } 112 | 113 | func TestEncodeGrpcMessage(t *testing.T) { 114 | for _, tt := range []struct { 115 | input string 116 | expected string 117 | }{ 118 | {"", ""}, 119 | {"Hello", "Hello"}, 120 | {"my favorite character is \u0000", "my favorite character is %00"}, 121 | {"my favorite character is %", "my favorite character is %25"}, 122 | } { 123 | actual := encodeGrpcMessage(tt.input) 124 | if tt.expected != actual { 125 | t.Errorf("encodeGrpcMessage(%v) = %v, want %v", tt.input, actual, tt.expected) 126 | } 127 | } 128 | } 129 | 130 | func TestDecodeGrpcMessage(t *testing.T) { 131 | for _, tt := range []struct { 132 | input string 133 | expected string 134 | }{ 135 | {"", ""}, 136 | {"Hello", "Hello"}, 137 | {"H%61o", "Hao"}, 138 | {"H%6", "H%6"}, 139 | {"%G0", "%G0"}, 140 | {"%E7%B3%BB%E7%BB%9F", "系统"}, 141 | } { 142 | actual := decodeGrpcMessage(tt.input) 143 | if tt.expected != actual { 144 | t.Errorf("dncodeGrpcMessage(%v) = %v, want %v", tt.input, actual, tt.expected) 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /transport/pre_go16.go: -------------------------------------------------------------------------------- 1 | // +build !go1.6 2 | 3 | /* 4 | * Copyright 2016, Google Inc. 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are 9 | * met: 10 | * 11 | * * Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above 14 | * copyright notice, this list of conditions and the following disclaimer 15 | * in the documentation and/or other materials provided with the 16 | * distribution. 17 | * * Neither the name of Google Inc. nor the names of its 18 | * contributors may be used to endorse or promote products derived from 19 | * this software without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | * 33 | */ 34 | 35 | package transport 36 | 37 | import ( 38 | "net" 39 | "time" 40 | 41 | "golang.org/x/net/context" 42 | ) 43 | 44 | // dialContext connects to the address on the named network. 45 | func dialContext(ctx context.Context, network, address string) (net.Conn, error) { 46 | var dialer net.Dialer 47 | if deadline, ok := ctx.Deadline(); ok { 48 | dialer.Timeout = deadline.Sub(time.Now()) 49 | } 50 | return dialer.Dial(network, address) 51 | } 52 | -------------------------------------------------------------------------------- /transport/testdata/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla 5 | Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 6 | YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT 7 | BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 8 | +L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu 9 | g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd 10 | Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV 11 | HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau 12 | sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m 13 | oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG 14 | Dfcog5wrJytaQ6UA0wE= 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /transport/testdata/server1.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD 3 | M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf 4 | 3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY 5 | AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm 6 | V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY 7 | tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p 8 | dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q 9 | K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR 10 | 81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff 11 | DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd 12 | aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 13 | ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 14 | XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe 15 | F98XJ7tIFfJq 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /transport/testdata/server1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET 3 | MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ 4 | dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx 5 | MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV 6 | BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 7 | ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco 8 | LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg 9 | zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd 10 | 9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw 11 | CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy 12 | em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G 13 | CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 14 | hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh 15 | y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 16 | -----END CERTIFICATE----- 17 | --------------------------------------------------------------------------------