libgo: update to Go1.10rc1
[official-gcc.git] / libgo / go / net / rpc / server.go
blob96e6973c3a2e710591be25e01b124a73028e2fa9
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 /*
6 Package rpc provides access to the exported methods of an object across a
7 network or other I/O connection. A server registers an object, making it visible
8 as a service with the name of the type of the object. After registration, exported
9 methods of the object will be accessible remotely. A server may register multiple
10 objects (services) of different types but it is an error to register multiple
11 objects of the same type.
13 Only methods that satisfy these criteria will be made available for remote access;
14 other methods will be ignored:
16 - the method's type is exported.
17 - the method is exported.
18 - the method has two arguments, both exported (or builtin) types.
19 - the method's second argument is a pointer.
20 - the method has return type error.
22 In effect, the method must look schematically like
24 func (t *T) MethodName(argType T1, replyType *T2) error
26 where T1 and T2 can be marshaled by encoding/gob.
27 These requirements apply even if a different codec is used.
28 (In the future, these requirements may soften for custom codecs.)
30 The method's first argument represents the arguments provided by the caller; the
31 second argument represents the result parameters to be returned to the caller.
32 The method's return value, if non-nil, is passed back as a string that the client
33 sees as if created by errors.New. If an error is returned, the reply parameter
34 will not be sent back to the client.
36 The server may handle requests on a single connection by calling ServeConn. More
37 typically it will create a network listener and call Accept or, for an HTTP
38 listener, HandleHTTP and http.Serve.
40 A client wishing to use the service establishes a connection and then invokes
41 NewClient on the connection. The convenience function Dial (DialHTTP) performs
42 both steps for a raw network connection (an HTTP connection). The resulting
43 Client object has two methods, Call and Go, that specify the service and method to
44 call, a pointer containing the arguments, and a pointer to receive the result
45 parameters.
47 The Call method waits for the remote call to complete while the Go method
48 launches the call asynchronously and signals completion using the Call
49 structure's Done channel.
51 Unless an explicit codec is set up, package encoding/gob is used to
52 transport the data.
54 Here is a simple example. A server wishes to export an object of type Arith:
56 package server
58 import "errors"
60 type Args struct {
61 A, B int
64 type Quotient struct {
65 Quo, Rem int
68 type Arith int
70 func (t *Arith) Multiply(args *Args, reply *int) error {
71 *reply = args.A * args.B
72 return nil
75 func (t *Arith) Divide(args *Args, quo *Quotient) error {
76 if args.B == 0 {
77 return errors.New("divide by zero")
79 quo.Quo = args.A / args.B
80 quo.Rem = args.A % args.B
81 return nil
84 The server calls (for HTTP service):
86 arith := new(Arith)
87 rpc.Register(arith)
88 rpc.HandleHTTP()
89 l, e := net.Listen("tcp", ":1234")
90 if e != nil {
91 log.Fatal("listen error:", e)
93 go http.Serve(l, nil)
95 At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
96 "Arith.Divide". To invoke one, a client first dials the server:
98 client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
99 if err != nil {
100 log.Fatal("dialing:", err)
103 Then it can make a remote call:
105 // Synchronous call
106 args := &server.Args{7,8}
107 var reply int
108 err = client.Call("Arith.Multiply", args, &reply)
109 if err != nil {
110 log.Fatal("arith error:", err)
112 fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
116 // Asynchronous call
117 quotient := new(Quotient)
118 divCall := client.Go("Arith.Divide", args, quotient, nil)
119 replyCall := <-divCall.Done // will be equal to divCall
120 // check errors, print, etc.
122 A server implementation will often provide a simple, type-safe wrapper for the
123 client.
125 The net/rpc package is frozen and is not accepting new features.
127 package rpc
129 import (
130 "bufio"
131 "encoding/gob"
132 "errors"
133 "io"
134 "log"
135 "net"
136 "net/http"
137 "reflect"
138 "strings"
139 "sync"
140 "unicode"
141 "unicode/utf8"
144 const (
145 // Defaults used by HandleHTTP
146 DefaultRPCPath = "/_goRPC_"
147 DefaultDebugPath = "/debug/rpc"
150 // Precompute the reflect type for error. Can't use error directly
151 // because Typeof takes an empty interface value. This is annoying.
152 var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
154 type methodType struct {
155 sync.Mutex // protects counters
156 method reflect.Method
157 ArgType reflect.Type
158 ReplyType reflect.Type
159 numCalls uint
162 type service struct {
163 name string // name of service
164 rcvr reflect.Value // receiver of methods for the service
165 typ reflect.Type // type of the receiver
166 method map[string]*methodType // registered methods
169 // Request is a header written before every RPC call. It is used internally
170 // but documented here as an aid to debugging, such as when analyzing
171 // network traffic.
172 type Request struct {
173 ServiceMethod string // format: "Service.Method"
174 Seq uint64 // sequence number chosen by client
175 next *Request // for free list in Server
178 // Response is a header written before every RPC return. It is used internally
179 // but documented here as an aid to debugging, such as when analyzing
180 // network traffic.
181 type Response struct {
182 ServiceMethod string // echoes that of the Request
183 Seq uint64 // echoes that of the request
184 Error string // error, if any.
185 next *Response // for free list in Server
188 // Server represents an RPC Server.
189 type Server struct {
190 serviceMap sync.Map // map[string]*service
191 reqLock sync.Mutex // protects freeReq
192 freeReq *Request
193 respLock sync.Mutex // protects freeResp
194 freeResp *Response
197 // NewServer returns a new Server.
198 func NewServer() *Server {
199 return &Server{}
202 // DefaultServer is the default instance of *Server.
203 var DefaultServer = NewServer()
205 // Is this an exported - upper case - name?
206 func isExported(name string) bool {
207 rune, _ := utf8.DecodeRuneInString(name)
208 return unicode.IsUpper(rune)
211 // Is this type exported or a builtin?
212 func isExportedOrBuiltinType(t reflect.Type) bool {
213 for t.Kind() == reflect.Ptr {
214 t = t.Elem()
216 // PkgPath will be non-empty even for an exported type,
217 // so we need to check the type name as well.
218 return isExported(t.Name()) || t.PkgPath() == ""
221 // Register publishes in the server the set of methods of the
222 // receiver value that satisfy the following conditions:
223 // - exported method of exported type
224 // - two arguments, both of exported type
225 // - the second argument is a pointer
226 // - one return value, of type error
227 // It returns an error if the receiver is not an exported type or has
228 // no suitable methods. It also logs the error using package log.
229 // The client accesses each method using a string of the form "Type.Method",
230 // where Type is the receiver's concrete type.
231 func (server *Server) Register(rcvr interface{}) error {
232 return server.register(rcvr, "", false)
235 // RegisterName is like Register but uses the provided name for the type
236 // instead of the receiver's concrete type.
237 func (server *Server) RegisterName(name string, rcvr interface{}) error {
238 return server.register(rcvr, name, true)
241 func (server *Server) register(rcvr interface{}, name string, useName bool) error {
242 s := new(service)
243 s.typ = reflect.TypeOf(rcvr)
244 s.rcvr = reflect.ValueOf(rcvr)
245 sname := reflect.Indirect(s.rcvr).Type().Name()
246 if useName {
247 sname = name
249 if sname == "" {
250 s := "rpc.Register: no service name for type " + s.typ.String()
251 log.Print(s)
252 return errors.New(s)
254 if !isExported(sname) && !useName {
255 s := "rpc.Register: type " + sname + " is not exported"
256 log.Print(s)
257 return errors.New(s)
259 s.name = sname
261 // Install the methods
262 s.method = suitableMethods(s.typ, true)
264 if len(s.method) == 0 {
265 str := ""
267 // To help the user, see if a pointer receiver would work.
268 method := suitableMethods(reflect.PtrTo(s.typ), false)
269 if len(method) != 0 {
270 str = "rpc.Register: type " + sname + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
271 } else {
272 str = "rpc.Register: type " + sname + " has no exported methods of suitable type"
274 log.Print(str)
275 return errors.New(str)
278 if _, dup := server.serviceMap.LoadOrStore(sname, s); dup {
279 return errors.New("rpc: service already defined: " + sname)
281 return nil
284 // suitableMethods returns suitable Rpc methods of typ, it will report
285 // error using log if reportErr is true.
286 func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType {
287 methods := make(map[string]*methodType)
288 for m := 0; m < typ.NumMethod(); m++ {
289 method := typ.Method(m)
290 mtype := method.Type
291 mname := method.Name
292 // Method must be exported.
293 if method.PkgPath != "" {
294 continue
296 // Method needs three ins: receiver, *args, *reply.
297 if mtype.NumIn() != 3 {
298 if reportErr {
299 log.Printf("rpc.Register: method %q has %d input parameters; needs exactly three\n", mname, mtype.NumIn())
301 continue
303 // First arg need not be a pointer.
304 argType := mtype.In(1)
305 if !isExportedOrBuiltinType(argType) {
306 if reportErr {
307 log.Printf("rpc.Register: argument type of method %q is not exported: %q\n", mname, argType)
309 continue
311 // Second arg must be a pointer.
312 replyType := mtype.In(2)
313 if replyType.Kind() != reflect.Ptr {
314 if reportErr {
315 log.Printf("rpc.Register: reply type of method %q is not a pointer: %q\n", mname, replyType)
317 continue
319 // Reply type must be exported.
320 if !isExportedOrBuiltinType(replyType) {
321 if reportErr {
322 log.Printf("rpc.Register: reply type of method %q is not exported: %q\n", mname, replyType)
324 continue
326 // Method needs one out.
327 if mtype.NumOut() != 1 {
328 if reportErr {
329 log.Printf("rpc.Register: method %q has %d output parameters; needs exactly one\n", mname, mtype.NumOut())
331 continue
333 // The return type of the method must be error.
334 if returnType := mtype.Out(0); returnType != typeOfError {
335 if reportErr {
336 log.Printf("rpc.Register: return type of method %q is %q, must be error\n", mname, returnType)
338 continue
340 methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType}
342 return methods
345 // A value sent as a placeholder for the server's response value when the server
346 // receives an invalid request. It is never decoded by the client since the Response
347 // contains an error when it is used.
348 var invalidRequest = struct{}{}
350 func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply interface{}, codec ServerCodec, errmsg string) {
351 resp := server.getResponse()
352 // Encode the response header
353 resp.ServiceMethod = req.ServiceMethod
354 if errmsg != "" {
355 resp.Error = errmsg
356 reply = invalidRequest
358 resp.Seq = req.Seq
359 sending.Lock()
360 err := codec.WriteResponse(resp, reply)
361 if debugLog && err != nil {
362 log.Println("rpc: writing response:", err)
364 sending.Unlock()
365 server.freeResponse(resp)
368 func (m *methodType) NumCalls() (n uint) {
369 m.Lock()
370 n = m.numCalls
371 m.Unlock()
372 return n
375 func (s *service) call(server *Server, sending *sync.Mutex, wg *sync.WaitGroup, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
376 if wg != nil {
377 defer wg.Done()
379 mtype.Lock()
380 mtype.numCalls++
381 mtype.Unlock()
382 function := mtype.method.Func
383 // Invoke the method, providing a new value for the reply.
384 returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv})
385 // The return value for the method is an error.
386 errInter := returnValues[0].Interface()
387 errmsg := ""
388 if errInter != nil {
389 errmsg = errInter.(error).Error()
391 server.sendResponse(sending, req, replyv.Interface(), codec, errmsg)
392 server.freeRequest(req)
395 type gobServerCodec struct {
396 rwc io.ReadWriteCloser
397 dec *gob.Decoder
398 enc *gob.Encoder
399 encBuf *bufio.Writer
400 closed bool
403 func (c *gobServerCodec) ReadRequestHeader(r *Request) error {
404 return c.dec.Decode(r)
407 func (c *gobServerCodec) ReadRequestBody(body interface{}) error {
408 return c.dec.Decode(body)
411 func (c *gobServerCodec) WriteResponse(r *Response, body interface{}) (err error) {
412 if err = c.enc.Encode(r); err != nil {
413 if c.encBuf.Flush() == nil {
414 // Gob couldn't encode the header. Should not happen, so if it does,
415 // shut down the connection to signal that the connection is broken.
416 log.Println("rpc: gob error encoding response:", err)
417 c.Close()
419 return
421 if err = c.enc.Encode(body); err != nil {
422 if c.encBuf.Flush() == nil {
423 // Was a gob problem encoding the body but the header has been written.
424 // Shut down the connection to signal that the connection is broken.
425 log.Println("rpc: gob error encoding body:", err)
426 c.Close()
428 return
430 return c.encBuf.Flush()
433 func (c *gobServerCodec) Close() error {
434 if c.closed {
435 // Only call c.rwc.Close once; otherwise the semantics are undefined.
436 return nil
438 c.closed = true
439 return c.rwc.Close()
442 // ServeConn runs the server on a single connection.
443 // ServeConn blocks, serving the connection until the client hangs up.
444 // The caller typically invokes ServeConn in a go statement.
445 // ServeConn uses the gob wire format (see package gob) on the
446 // connection. To use an alternate codec, use ServeCodec.
447 func (server *Server) ServeConn(conn io.ReadWriteCloser) {
448 buf := bufio.NewWriter(conn)
449 srv := &gobServerCodec{
450 rwc: conn,
451 dec: gob.NewDecoder(conn),
452 enc: gob.NewEncoder(buf),
453 encBuf: buf,
455 server.ServeCodec(srv)
458 // ServeCodec is like ServeConn but uses the specified codec to
459 // decode requests and encode responses.
460 func (server *Server) ServeCodec(codec ServerCodec) {
461 sending := new(sync.Mutex)
462 wg := new(sync.WaitGroup)
463 for {
464 service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
465 if err != nil {
466 if debugLog && err != io.EOF {
467 log.Println("rpc:", err)
469 if !keepReading {
470 break
472 // send a response if we actually managed to read a header.
473 if req != nil {
474 server.sendResponse(sending, req, invalidRequest, codec, err.Error())
475 server.freeRequest(req)
477 continue
479 wg.Add(1)
480 go service.call(server, sending, wg, mtype, req, argv, replyv, codec)
482 // We've seen that there are no more requests.
483 // Wait for responses to be sent before closing codec.
484 wg.Wait()
485 codec.Close()
488 // ServeRequest is like ServeCodec but synchronously serves a single request.
489 // It does not close the codec upon completion.
490 func (server *Server) ServeRequest(codec ServerCodec) error {
491 sending := new(sync.Mutex)
492 service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
493 if err != nil {
494 if !keepReading {
495 return err
497 // send a response if we actually managed to read a header.
498 if req != nil {
499 server.sendResponse(sending, req, invalidRequest, codec, err.Error())
500 server.freeRequest(req)
502 return err
504 service.call(server, sending, nil, mtype, req, argv, replyv, codec)
505 return nil
508 func (server *Server) getRequest() *Request {
509 server.reqLock.Lock()
510 req := server.freeReq
511 if req == nil {
512 req = new(Request)
513 } else {
514 server.freeReq = req.next
515 *req = Request{}
517 server.reqLock.Unlock()
518 return req
521 func (server *Server) freeRequest(req *Request) {
522 server.reqLock.Lock()
523 req.next = server.freeReq
524 server.freeReq = req
525 server.reqLock.Unlock()
528 func (server *Server) getResponse() *Response {
529 server.respLock.Lock()
530 resp := server.freeResp
531 if resp == nil {
532 resp = new(Response)
533 } else {
534 server.freeResp = resp.next
535 *resp = Response{}
537 server.respLock.Unlock()
538 return resp
541 func (server *Server) freeResponse(resp *Response) {
542 server.respLock.Lock()
543 resp.next = server.freeResp
544 server.freeResp = resp
545 server.respLock.Unlock()
548 func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err error) {
549 service, mtype, req, keepReading, err = server.readRequestHeader(codec)
550 if err != nil {
551 if !keepReading {
552 return
554 // discard body
555 codec.ReadRequestBody(nil)
556 return
559 // Decode the argument value.
560 argIsValue := false // if true, need to indirect before calling.
561 if mtype.ArgType.Kind() == reflect.Ptr {
562 argv = reflect.New(mtype.ArgType.Elem())
563 } else {
564 argv = reflect.New(mtype.ArgType)
565 argIsValue = true
567 // argv guaranteed to be a pointer now.
568 if err = codec.ReadRequestBody(argv.Interface()); err != nil {
569 return
571 if argIsValue {
572 argv = argv.Elem()
575 replyv = reflect.New(mtype.ReplyType.Elem())
577 switch mtype.ReplyType.Elem().Kind() {
578 case reflect.Map:
579 replyv.Elem().Set(reflect.MakeMap(mtype.ReplyType.Elem()))
580 case reflect.Slice:
581 replyv.Elem().Set(reflect.MakeSlice(mtype.ReplyType.Elem(), 0, 0))
583 return
586 func (server *Server) readRequestHeader(codec ServerCodec) (svc *service, mtype *methodType, req *Request, keepReading bool, err error) {
587 // Grab the request header.
588 req = server.getRequest()
589 err = codec.ReadRequestHeader(req)
590 if err != nil {
591 req = nil
592 if err == io.EOF || err == io.ErrUnexpectedEOF {
593 return
595 err = errors.New("rpc: server cannot decode request: " + err.Error())
596 return
599 // We read the header successfully. If we see an error now,
600 // we can still recover and move on to the next request.
601 keepReading = true
603 dot := strings.LastIndex(req.ServiceMethod, ".")
604 if dot < 0 {
605 err = errors.New("rpc: service/method request ill-formed: " + req.ServiceMethod)
606 return
608 serviceName := req.ServiceMethod[:dot]
609 methodName := req.ServiceMethod[dot+1:]
611 // Look up the request.
612 svci, ok := server.serviceMap.Load(serviceName)
613 if !ok {
614 err = errors.New("rpc: can't find service " + req.ServiceMethod)
615 return
617 svc = svci.(*service)
618 mtype = svc.method[methodName]
619 if mtype == nil {
620 err = errors.New("rpc: can't find method " + req.ServiceMethod)
622 return
625 // Accept accepts connections on the listener and serves requests
626 // for each incoming connection. Accept blocks until the listener
627 // returns a non-nil error. The caller typically invokes Accept in a
628 // go statement.
629 func (server *Server) Accept(lis net.Listener) {
630 for {
631 conn, err := lis.Accept()
632 if err != nil {
633 log.Print("rpc.Serve: accept:", err.Error())
634 return
636 go server.ServeConn(conn)
640 // Register publishes the receiver's methods in the DefaultServer.
641 func Register(rcvr interface{}) error { return DefaultServer.Register(rcvr) }
643 // RegisterName is like Register but uses the provided name for the type
644 // instead of the receiver's concrete type.
645 func RegisterName(name string, rcvr interface{}) error {
646 return DefaultServer.RegisterName(name, rcvr)
649 // A ServerCodec implements reading of RPC requests and writing of
650 // RPC responses for the server side of an RPC session.
651 // The server calls ReadRequestHeader and ReadRequestBody in pairs
652 // to read requests from the connection, and it calls WriteResponse to
653 // write a response back. The server calls Close when finished with the
654 // connection. ReadRequestBody may be called with a nil
655 // argument to force the body of the request to be read and discarded.
656 type ServerCodec interface {
657 ReadRequestHeader(*Request) error
658 ReadRequestBody(interface{}) error
659 // WriteResponse must be safe for concurrent use by multiple goroutines.
660 WriteResponse(*Response, interface{}) error
662 Close() error
665 // ServeConn runs the DefaultServer on a single connection.
666 // ServeConn blocks, serving the connection until the client hangs up.
667 // The caller typically invokes ServeConn in a go statement.
668 // ServeConn uses the gob wire format (see package gob) on the
669 // connection. To use an alternate codec, use ServeCodec.
670 func ServeConn(conn io.ReadWriteCloser) {
671 DefaultServer.ServeConn(conn)
674 // ServeCodec is like ServeConn but uses the specified codec to
675 // decode requests and encode responses.
676 func ServeCodec(codec ServerCodec) {
677 DefaultServer.ServeCodec(codec)
680 // ServeRequest is like ServeCodec but synchronously serves a single request.
681 // It does not close the codec upon completion.
682 func ServeRequest(codec ServerCodec) error {
683 return DefaultServer.ServeRequest(codec)
686 // Accept accepts connections on the listener and serves requests
687 // to DefaultServer for each incoming connection.
688 // Accept blocks; the caller typically invokes it in a go statement.
689 func Accept(lis net.Listener) { DefaultServer.Accept(lis) }
691 // Can connect to RPC service using HTTP CONNECT to rpcPath.
692 var connected = "200 Connected to Go RPC"
694 // ServeHTTP implements an http.Handler that answers RPC requests.
695 func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
696 if req.Method != "CONNECT" {
697 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
698 w.WriteHeader(http.StatusMethodNotAllowed)
699 io.WriteString(w, "405 must CONNECT\n")
700 return
702 conn, _, err := w.(http.Hijacker).Hijack()
703 if err != nil {
704 log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error())
705 return
707 io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n")
708 server.ServeConn(conn)
711 // HandleHTTP registers an HTTP handler for RPC messages on rpcPath,
712 // and a debugging handler on debugPath.
713 // It is still necessary to invoke http.Serve(), typically in a go statement.
714 func (server *Server) HandleHTTP(rpcPath, debugPath string) {
715 http.Handle(rpcPath, server)
716 http.Handle(debugPath, debugHTTP{server})
719 // HandleHTTP registers an HTTP handler for RPC messages to DefaultServer
720 // on DefaultRPCPath and a debugging handler on DefaultDebugPath.
721 // It is still necessary to invoke http.Serve(), typically in a go statement.
722 func HandleHTTP() {
723 DefaultServer.HandleHTTP(DefaultRPCPath, DefaultDebugPath)