github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/Godeps/_workspace/src/google.golang.org/grpc/server.go (about) 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 grpc 35 36 import ( 37 "errors" 38 "fmt" 39 "io" 40 "net" 41 "reflect" 42 "strings" 43 "sync" 44 45 "github.com/coreos/rkt/Godeps/_workspace/src/golang.org/x/net/context" 46 "github.com/coreos/rkt/Godeps/_workspace/src/golang.org/x/net/trace" 47 "github.com/coreos/rkt/Godeps/_workspace/src/google.golang.org/grpc/codes" 48 "github.com/coreos/rkt/Godeps/_workspace/src/google.golang.org/grpc/credentials" 49 "github.com/coreos/rkt/Godeps/_workspace/src/google.golang.org/grpc/grpclog" 50 "github.com/coreos/rkt/Godeps/_workspace/src/google.golang.org/grpc/metadata" 51 "github.com/coreos/rkt/Godeps/_workspace/src/google.golang.org/grpc/transport" 52 ) 53 54 type methodHandler func(srv interface{}, ctx context.Context, codec Codec, buf []byte) (interface{}, error) 55 56 // MethodDesc represents an RPC service's method specification. 57 type MethodDesc struct { 58 MethodName string 59 Handler methodHandler 60 } 61 62 // ServiceDesc represents an RPC service's specification. 63 type ServiceDesc struct { 64 ServiceName string 65 // The pointer to the service interface. Used to check whether the user 66 // provided implementation satisfies the interface requirements. 67 HandlerType interface{} 68 Methods []MethodDesc 69 Streams []StreamDesc 70 } 71 72 // service consists of the information of the server serving this service and 73 // the methods in this service. 74 type service struct { 75 server interface{} // the server for service methods 76 md map[string]*MethodDesc 77 sd map[string]*StreamDesc 78 } 79 80 // Server is a gRPC server to serve RPC requests. 81 type Server struct { 82 opts options 83 mu sync.Mutex 84 lis map[net.Listener]bool 85 conns map[transport.ServerTransport]bool 86 m map[string]*service // service name -> service info 87 } 88 89 type options struct { 90 creds credentials.Credentials 91 codec Codec 92 maxConcurrentStreams uint32 93 } 94 95 // A ServerOption sets options. 96 type ServerOption func(*options) 97 98 // CustomCodec returns a ServerOption that sets a codec for message marshaling and unmarshaling. 99 func CustomCodec(codec Codec) ServerOption { 100 return func(o *options) { 101 o.codec = codec 102 } 103 } 104 105 // MaxConcurrentStreams returns a ServerOption that will apply a limit on the number 106 // of concurrent streams to each ServerTransport. 107 func MaxConcurrentStreams(n uint32) ServerOption { 108 return func(o *options) { 109 o.maxConcurrentStreams = n 110 } 111 } 112 113 // Creds returns a ServerOption that sets credentials for server connections. 114 func Creds(c credentials.Credentials) ServerOption { 115 return func(o *options) { 116 o.creds = c 117 } 118 } 119 120 // NewServer creates a gRPC server which has no service registered and has not 121 // started to accept requests yet. 122 func NewServer(opt ...ServerOption) *Server { 123 var opts options 124 for _, o := range opt { 125 o(&opts) 126 } 127 if opts.codec == nil { 128 // Set the default codec. 129 opts.codec = protoCodec{} 130 } 131 return &Server{ 132 lis: make(map[net.Listener]bool), 133 opts: opts, 134 conns: make(map[transport.ServerTransport]bool), 135 m: make(map[string]*service), 136 } 137 } 138 139 // RegisterService register a service and its implementation to the gRPC 140 // server. Called from the IDL generated code. This must be called before 141 // invoking Serve. 142 func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) { 143 ht := reflect.TypeOf(sd.HandlerType).Elem() 144 st := reflect.TypeOf(ss) 145 if !st.Implements(ht) { 146 grpclog.Fatalf("grpc: Server.RegisterService found the handler of type %v that does not satisfy %v", st, ht) 147 } 148 s.register(sd, ss) 149 } 150 151 func (s *Server) register(sd *ServiceDesc, ss interface{}) { 152 s.mu.Lock() 153 defer s.mu.Unlock() 154 if _, ok := s.m[sd.ServiceName]; ok { 155 grpclog.Fatalf("grpc: Server.RegisterService found duplicate service registration for %q", sd.ServiceName) 156 } 157 srv := &service{ 158 server: ss, 159 md: make(map[string]*MethodDesc), 160 sd: make(map[string]*StreamDesc), 161 } 162 for i := range sd.Methods { 163 d := &sd.Methods[i] 164 srv.md[d.MethodName] = d 165 } 166 for i := range sd.Streams { 167 d := &sd.Streams[i] 168 srv.sd[d.StreamName] = d 169 } 170 s.m[sd.ServiceName] = srv 171 } 172 173 var ( 174 // ErrServerStopped indicates that the operation is now illegal because of 175 // the server being stopped. 176 ErrServerStopped = errors.New("grpc: the server has been stopped") 177 ) 178 179 // Serve accepts incoming connections on the listener lis, creating a new 180 // ServerTransport and service goroutine for each. The service goroutines 181 // read gRPC request and then call the registered handlers to reply to them. 182 // Service returns when lis.Accept fails. 183 func (s *Server) Serve(lis net.Listener) error { 184 s.mu.Lock() 185 if s.lis == nil { 186 s.mu.Unlock() 187 return ErrServerStopped 188 } 189 s.lis[lis] = true 190 s.mu.Unlock() 191 defer func() { 192 lis.Close() 193 s.mu.Lock() 194 delete(s.lis, lis) 195 s.mu.Unlock() 196 }() 197 for { 198 c, err := lis.Accept() 199 if err != nil { 200 return err 201 } 202 var authInfo credentials.AuthInfo 203 if creds, ok := s.opts.creds.(credentials.TransportAuthenticator); ok { 204 c, authInfo, err = creds.ServerHandshake(c) 205 if err != nil { 206 grpclog.Println("grpc: Server.Serve failed to complete security handshake.") 207 continue 208 } 209 } 210 s.mu.Lock() 211 if s.conns == nil { 212 s.mu.Unlock() 213 c.Close() 214 return nil 215 } 216 st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams, authInfo) 217 if err != nil { 218 s.mu.Unlock() 219 c.Close() 220 grpclog.Println("grpc: Server.Serve failed to create ServerTransport: ", err) 221 continue 222 } 223 s.conns[st] = true 224 s.mu.Unlock() 225 226 go func() { 227 st.HandleStreams(func(stream *transport.Stream) { 228 s.handleStream(st, stream) 229 }) 230 s.mu.Lock() 231 delete(s.conns, st) 232 s.mu.Unlock() 233 }() 234 } 235 } 236 237 func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, pf payloadFormat, opts *transport.Options) error { 238 p, err := encode(s.opts.codec, msg, pf) 239 if err != nil { 240 // This typically indicates a fatal issue (e.g., memory 241 // corruption or hardware faults) the application program 242 // cannot handle. 243 // 244 // TODO(zhaoq): There exist other options also such as only closing the 245 // faulty stream locally and remotely (Other streams can keep going). Find 246 // the optimal option. 247 grpclog.Fatalf("grpc: Server failed to encode response %v", err) 248 } 249 return t.Write(stream, p, opts) 250 } 251 252 func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, md *MethodDesc) (err error) { 253 var traceInfo traceInfo 254 if EnableTracing { 255 traceInfo.tr = trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()) 256 defer traceInfo.tr.Finish() 257 traceInfo.firstLine.client = false 258 traceInfo.tr.LazyLog(&traceInfo.firstLine, false) 259 defer func() { 260 if err != nil && err != io.EOF { 261 traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) 262 traceInfo.tr.SetError() 263 } 264 }() 265 } 266 p := &parser{s: stream} 267 for { 268 pf, req, err := p.recvMsg() 269 if err == io.EOF { 270 // The entire stream is done (for unary RPC only). 271 return err 272 } 273 if err != nil { 274 switch err := err.(type) { 275 case transport.ConnectionError: 276 // Nothing to do here. 277 case transport.StreamError: 278 if err := t.WriteStatus(stream, err.Code, err.Desc); err != nil { 279 grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err) 280 } 281 default: 282 panic(fmt.Sprintf("grpc: Unexpected error (%T) from recvMsg: %v", err, err)) 283 } 284 return err 285 } 286 if traceInfo.tr != nil { 287 traceInfo.tr.LazyLog(&payload{sent: false, msg: req}, true) 288 } 289 switch pf { 290 case compressionNone: 291 statusCode := codes.OK 292 statusDesc := "" 293 reply, appErr := md.Handler(srv.server, stream.Context(), s.opts.codec, req) 294 if appErr != nil { 295 if err, ok := appErr.(rpcError); ok { 296 statusCode = err.code 297 statusDesc = err.desc 298 } else { 299 statusCode = convertCode(appErr) 300 statusDesc = appErr.Error() 301 } 302 if err := t.WriteStatus(stream, statusCode, statusDesc); err != nil { 303 grpclog.Printf("grpc: Server.processUnaryRPC failed to write status: %v", err) 304 return err 305 } 306 return nil 307 } 308 opts := &transport.Options{ 309 Last: true, 310 Delay: false, 311 } 312 if err := s.sendResponse(t, stream, reply, compressionNone, opts); err != nil { 313 switch err := err.(type) { 314 case transport.ConnectionError: 315 // Nothing to do here. 316 case transport.StreamError: 317 statusCode = err.Code 318 statusDesc = err.Desc 319 default: 320 statusCode = codes.Unknown 321 statusDesc = err.Error() 322 } 323 return err 324 } 325 if traceInfo.tr != nil { 326 traceInfo.tr.LazyLog(&payload{sent: true, msg: reply}, true) 327 } 328 return t.WriteStatus(stream, statusCode, statusDesc) 329 default: 330 panic(fmt.Sprintf("payload format to be supported: %d", pf)) 331 } 332 } 333 } 334 335 func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc) (err error) { 336 ss := &serverStream{ 337 t: t, 338 s: stream, 339 p: &parser{s: stream}, 340 codec: s.opts.codec, 341 tracing: EnableTracing, 342 } 343 if ss.tracing { 344 ss.traceInfo.tr = trace.New("grpc.Recv."+methodFamily(stream.Method()), stream.Method()) 345 ss.traceInfo.firstLine.client = false 346 ss.traceInfo.tr.LazyLog(&ss.traceInfo.firstLine, false) 347 defer func() { 348 ss.mu.Lock() 349 if err != nil && err != io.EOF { 350 ss.traceInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) 351 ss.traceInfo.tr.SetError() 352 } 353 ss.traceInfo.tr.Finish() 354 ss.traceInfo.tr = nil 355 ss.mu.Unlock() 356 }() 357 } 358 if appErr := sd.Handler(srv.server, ss); appErr != nil { 359 if err, ok := appErr.(rpcError); ok { 360 ss.statusCode = err.code 361 ss.statusDesc = err.desc 362 } else { 363 ss.statusCode = convertCode(appErr) 364 ss.statusDesc = appErr.Error() 365 } 366 } 367 return t.WriteStatus(ss.s, ss.statusCode, ss.statusDesc) 368 369 } 370 371 func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream) { 372 sm := stream.Method() 373 if sm != "" && sm[0] == '/' { 374 sm = sm[1:] 375 } 376 pos := strings.LastIndex(sm, "/") 377 if pos == -1 { 378 if err := t.WriteStatus(stream, codes.InvalidArgument, fmt.Sprintf("malformed method name: %q", stream.Method())); err != nil { 379 grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err) 380 } 381 return 382 } 383 service := sm[:pos] 384 method := sm[pos+1:] 385 srv, ok := s.m[service] 386 if !ok { 387 if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown service %v", service)); err != nil { 388 grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err) 389 } 390 return 391 } 392 // Unary RPC or Streaming RPC? 393 if md, ok := srv.md[method]; ok { 394 s.processUnaryRPC(t, stream, srv, md) 395 return 396 } 397 if sd, ok := srv.sd[method]; ok { 398 s.processStreamingRPC(t, stream, srv, sd) 399 return 400 } 401 if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown method %v", method)); err != nil { 402 grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err) 403 } 404 } 405 406 // Stop stops the gRPC server. Once Stop returns, the server stops accepting 407 // connection requests and closes all the connected connections. 408 func (s *Server) Stop() { 409 s.mu.Lock() 410 listeners := s.lis 411 s.lis = nil 412 cs := s.conns 413 s.conns = nil 414 s.mu.Unlock() 415 for lis := range listeners { 416 lis.Close() 417 } 418 for c := range cs { 419 c.Close() 420 } 421 } 422 423 // TestingCloseConns closes all exiting transports but keeps s.lis accepting new 424 // connections. This is for test only now. 425 func (s *Server) TestingCloseConns() { 426 s.mu.Lock() 427 for c := range s.conns { 428 c.Close() 429 } 430 s.conns = make(map[transport.ServerTransport]bool) 431 s.mu.Unlock() 432 } 433 434 // SendHeader sends header metadata. It may be called at most once from a unary 435 // RPC handler. The ctx is the RPC handler's Context or one derived from it. 436 func SendHeader(ctx context.Context, md metadata.MD) error { 437 if md.Len() == 0 { 438 return nil 439 } 440 stream, ok := transport.StreamFromContext(ctx) 441 if !ok { 442 return fmt.Errorf("grpc: failed to fetch the stream from the context %v", ctx) 443 } 444 t := stream.ServerTransport() 445 if t == nil { 446 grpclog.Fatalf("grpc: SendHeader: %v has no ServerTransport to send header metadata.", stream) 447 } 448 return t.WriteHeader(stream, md) 449 } 450 451 // SetTrailer sets the trailer metadata that will be sent when an RPC returns. 452 // It may be called at most once from a unary RPC handler. The ctx is the RPC 453 // handler's Context or one derived from it. 454 func SetTrailer(ctx context.Context, md metadata.MD) error { 455 if md.Len() == 0 { 456 return nil 457 } 458 stream, ok := transport.StreamFromContext(ctx) 459 if !ok { 460 return fmt.Errorf("grpc: failed to fetch the stream from the context %v", ctx) 461 } 462 return stream.SetTrailer(md) 463 }