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  }