OSDN Git Service

new repo
[bytom/vapor.git] / vendor / google.golang.org / grpc / service_config.go
1 /*
2  *
3  * Copyright 2017 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 package grpc
20
21 import (
22         "encoding/json"
23         "time"
24
25         "google.golang.org/grpc/grpclog"
26 )
27
28 const maxInt = int(^uint(0) >> 1)
29
30 // MethodConfig defines the configuration recommended by the service providers for a
31 // particular method.
32 // DEPRECATED: Users should not use this struct. Service config should be received
33 // through name resolver, as specified here
34 // https://github.com/grpc/grpc/blob/master/doc/service_config.md
35 type MethodConfig struct {
36         // WaitForReady indicates whether RPCs sent to this method should wait until
37         // the connection is ready by default (!failfast). The value specified via the
38         // gRPC client API will override the value set here.
39         WaitForReady *bool
40         // Timeout is the default timeout for RPCs sent to this method. The actual
41         // deadline used will be the minimum of the value specified here and the value
42         // set by the application via the gRPC client API.  If either one is not set,
43         // then the other will be used.  If neither is set, then the RPC has no deadline.
44         Timeout *time.Duration
45         // MaxReqSize is the maximum allowed payload size for an individual request in a
46         // stream (client->server) in bytes. The size which is measured is the serialized
47         // payload after per-message compression (but before stream compression) in bytes.
48         // The actual value used is the minimum of the value specified here and the value set
49         // by the application via the gRPC client API. If either one is not set, then the other
50         // will be used.  If neither is set, then the built-in default is used.
51         MaxReqSize *int
52         // MaxRespSize is the maximum allowed payload size for an individual response in a
53         // stream (server->client) in bytes.
54         MaxRespSize *int
55 }
56
57 // ServiceConfig is provided by the service provider and contains parameters for how
58 // clients that connect to the service should behave.
59 // DEPRECATED: Users should not use this struct. Service config should be received
60 // through name resolver, as specified here
61 // https://github.com/grpc/grpc/blob/master/doc/service_config.md
62 type ServiceConfig struct {
63         // LB is the load balancer the service providers recommends. The balancer specified
64         // via grpc.WithBalancer will override this.
65         LB *string
66         // Methods contains a map for the methods in this service.
67         // If there is an exact match for a method (i.e. /service/method) in the map, use the corresponding MethodConfig.
68         // If there's no exact match, look for the default config for the service (/service/) and use the corresponding MethodConfig if it exists.
69         // Otherwise, the method has no MethodConfig to use.
70         Methods map[string]MethodConfig
71 }
72
73 func parseTimeout(t *string) (*time.Duration, error) {
74         if t == nil {
75                 return nil, nil
76         }
77         d, err := time.ParseDuration(*t)
78         return &d, err
79 }
80
81 type jsonName struct {
82         Service *string
83         Method  *string
84 }
85
86 func (j jsonName) generatePath() (string, bool) {
87         if j.Service == nil {
88                 return "", false
89         }
90         res := "/" + *j.Service + "/"
91         if j.Method != nil {
92                 res += *j.Method
93         }
94         return res, true
95 }
96
97 // TODO(lyuxuan): delete this struct after cleaning up old service config implementation.
98 type jsonMC struct {
99         Name                    *[]jsonName
100         WaitForReady            *bool
101         Timeout                 *string
102         MaxRequestMessageBytes  *int64
103         MaxResponseMessageBytes *int64
104 }
105
106 // TODO(lyuxuan): delete this struct after cleaning up old service config implementation.
107 type jsonSC struct {
108         LoadBalancingPolicy *string
109         MethodConfig        *[]jsonMC
110 }
111
112 func parseServiceConfig(js string) (ServiceConfig, error) {
113         var rsc jsonSC
114         err := json.Unmarshal([]byte(js), &rsc)
115         if err != nil {
116                 grpclog.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err)
117                 return ServiceConfig{}, err
118         }
119         sc := ServiceConfig{
120                 LB:      rsc.LoadBalancingPolicy,
121                 Methods: make(map[string]MethodConfig),
122         }
123         if rsc.MethodConfig == nil {
124                 return sc, nil
125         }
126
127         for _, m := range *rsc.MethodConfig {
128                 if m.Name == nil {
129                         continue
130                 }
131                 d, err := parseTimeout(m.Timeout)
132                 if err != nil {
133                         grpclog.Warningf("grpc: parseServiceConfig error unmarshaling %s due to %v", js, err)
134                         return ServiceConfig{}, err
135                 }
136
137                 mc := MethodConfig{
138                         WaitForReady: m.WaitForReady,
139                         Timeout:      d,
140                 }
141                 if m.MaxRequestMessageBytes != nil {
142                         if *m.MaxRequestMessageBytes > int64(maxInt) {
143                                 mc.MaxReqSize = newInt(maxInt)
144                         } else {
145                                 mc.MaxReqSize = newInt(int(*m.MaxRequestMessageBytes))
146                         }
147                 }
148                 if m.MaxResponseMessageBytes != nil {
149                         if *m.MaxResponseMessageBytes > int64(maxInt) {
150                                 mc.MaxRespSize = newInt(maxInt)
151                         } else {
152                                 mc.MaxRespSize = newInt(int(*m.MaxResponseMessageBytes))
153                         }
154                 }
155                 for _, n := range *m.Name {
156                         if path, valid := n.generatePath(); valid {
157                                 sc.Methods[path] = mc
158                         }
159                 }
160         }
161
162         return sc, nil
163 }
164
165 func min(a, b *int) *int {
166         if *a < *b {
167                 return a
168         }
169         return b
170 }
171
172 func getMaxSize(mcMax, doptMax *int, defaultVal int) *int {
173         if mcMax == nil && doptMax == nil {
174                 return &defaultVal
175         }
176         if mcMax != nil && doptMax != nil {
177                 return min(mcMax, doptMax)
178         }
179         if mcMax != nil {
180                 return mcMax
181         }
182         return doptMax
183 }
184
185 func newBool(b bool) *bool {
186         return &b
187 }
188
189 func newInt(b int) *int {
190         return &b
191 }
192
193 func newDuration(b time.Duration) *time.Duration {
194         return &b
195 }
196
197 func newString(b string) *string {
198         return &b
199 }