github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/net/rpc/server.go (about) 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. 4 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. 12 13 Only methods that satisfy these criteria will be made available for remote access; 14 other methods will be ignored: 15 16 - the method is exported. 17 - the method has two arguments, both exported (or builtin) types. 18 - the method's second argument is a pointer. 19 - the method has return type error. 20 21 In effect, the method must look schematically like 22 23 func (t *T) MethodName(argType T1, replyType *T2) error 24 25 where T, T1 and T2 can be marshaled by encoding/gob. 26 These requirements apply even if a different codec is used. 27 (In the future, these requirements may soften for custom codecs.) 28 29 The method's first argument represents the arguments provided by the caller; the 30 second argument represents the result parameters to be returned to the caller. 31 The method's return value, if non-nil, is passed back as a string that the client 32 sees as if created by errors.New. If an error is returned, the reply parameter 33 will not be sent back to the client. 34 35 The server may handle requests on a single connection by calling ServeConn. More 36 typically it will create a network listener and call Accept or, for an HTTP 37 listener, HandleHTTP and http.Serve. 38 39 A client wishing to use the service establishes a connection and then invokes 40 NewClient on the connection. The convenience function Dial (DialHTTP) performs 41 both steps for a raw network connection (an HTTP connection). The resulting 42 Client object has two methods, Call and Go, that specify the service and method to 43 call, a pointer containing the arguments, and a pointer to receive the result 44 parameters. 45 46 The Call method waits for the remote call to complete while the Go method 47 launches the call asynchronously and signals completion using the Call 48 structure's Done channel. 49 50 Unless an explicit codec is set up, package encoding/gob is used to 51 transport the data. 52 53 Here is a simple example. A server wishes to export an object of type Arith: 54 55 package server 56 57 type Args struct { 58 A, B int 59 } 60 61 type Quotient struct { 62 Quo, Rem int 63 } 64 65 type Arith int 66 67 func (t *Arith) Multiply(args *Args, reply *int) error { 68 *reply = args.A * args.B 69 return nil 70 } 71 72 func (t *Arith) Divide(args *Args, quo *Quotient) error { 73 if args.B == 0 { 74 return errors.New("divide by zero") 75 } 76 quo.Quo = args.A / args.B 77 quo.Rem = args.A % args.B 78 return nil 79 } 80 81 The server calls (for HTTP service): 82 83 arith := new(Arith) 84 rpc.Register(arith) 85 rpc.HandleHTTP() 86 l, e := net.Listen("tcp", ":1234") 87 if e != nil { 88 log.Fatal("listen error:", e) 89 } 90 go http.Serve(l, nil) 91 92 At this point, clients can see a service "Arith" with methods "Arith.Multiply" and 93 "Arith.Divide". To invoke one, a client first dials the server: 94 95 client, err := rpc.DialHTTP("tcp", serverAddress + ":1234") 96 if err != nil { 97 log.Fatal("dialing:", err) 98 } 99 100 Then it can make a remote call: 101 102 // Synchronous call 103 args := &server.Args{7,8} 104 var reply int 105 err = client.Call("Arith.Multiply", args, &reply) 106 if err != nil { 107 log.Fatal("arith error:", err) 108 } 109 fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply) 110 111 or 112 113 // Asynchronous call 114 quotient := new(Quotient) 115 divCall := client.Go("Arith.Divide", args, quotient, nil) 116 replyCall := <-divCall.Done // will be equal to divCall 117 // check errors, print, etc. 118 119 A server implementation will often provide a simple, type-safe wrapper for the 120 client. 121 */ 122 package rpc 123 124 import ( 125 "bufio" 126 "encoding/gob" 127 "errors" 128 "io" 129 "log" 130 "net" 131 "net/http" 132 "reflect" 133 "strings" 134 "sync" 135 "unicode" 136 "unicode/utf8" 137 ) 138 139 const ( 140 // Defaults used by HandleHTTP 141 DefaultRPCPath = "/_goRPC_" 142 DefaultDebugPath = "/debug/rpc" 143 ) 144 145 // Precompute the reflect type for error. Can't use error directly 146 // because Typeof takes an empty interface value. This is annoying. 147 var typeOfError = reflect.TypeOf((*error)(nil)).Elem() 148 149 type methodType struct { 150 sync.Mutex // protects counters 151 method reflect.Method 152 ArgType reflect.Type 153 ReplyType reflect.Type 154 numCalls uint 155 } 156 157 type service struct { 158 name string // name of service 159 rcvr reflect.Value // receiver of methods for the service 160 typ reflect.Type // type of the receiver 161 method map[string]*methodType // registered methods 162 } 163 164 // Request is a header written before every RPC call. It is used internally 165 // but documented here as an aid to debugging, such as when analyzing 166 // network traffic. 167 type Request struct { 168 ServiceMethod string // format: "Service.Method" 169 Seq uint64 // sequence number chosen by client 170 next *Request // for free list in Server 171 } 172 173 // Response is a header written before every RPC return. It is used internally 174 // but documented here as an aid to debugging, such as when analyzing 175 // network traffic. 176 type Response struct { 177 ServiceMethod string // echoes that of the Request 178 Seq uint64 // echoes that of the request 179 Error string // error, if any. 180 next *Response // for free list in Server 181 } 182 183 // Server represents an RPC Server. 184 type Server struct { 185 mu sync.RWMutex // protects the serviceMap 186 serviceMap map[string]*service 187 reqLock sync.Mutex // protects freeReq 188 freeReq *Request 189 respLock sync.Mutex // protects freeResp 190 freeResp *Response 191 } 192 193 // NewServer returns a new Server. 194 func NewServer() *Server { 195 return &Server{serviceMap: make(map[string]*service)} 196 } 197 198 // DefaultServer is the default instance of *Server. 199 var DefaultServer = NewServer() 200 201 // Is this an exported - upper case - name? 202 func isExported(name string) bool { 203 rune, _ := utf8.DecodeRuneInString(name) 204 return unicode.IsUpper(rune) 205 } 206 207 // Is this type exported or a builtin? 208 func isExportedOrBuiltinType(t reflect.Type) bool { 209 for t.Kind() == reflect.Ptr { 210 t = t.Elem() 211 } 212 // PkgPath will be non-empty even for an exported type, 213 // so we need to check the type name as well. 214 return isExported(t.Name()) || t.PkgPath() == "" 215 } 216 217 // Register publishes in the server the set of methods of the 218 // receiver value that satisfy the following conditions: 219 // - exported method 220 // - two arguments, both pointers to exported structs 221 // - one return value, of type error 222 // It returns an error if the receiver is not an exported type or has 223 // no methods or unsuitable methods. It also logs the error using package log. 224 // The client accesses each method using a string of the form "Type.Method", 225 // where Type is the receiver's concrete type. 226 func (server *Server) Register(rcvr interface{}) error { 227 return server.register(rcvr, "", false) 228 } 229 230 // RegisterName is like Register but uses the provided name for the type 231 // instead of the receiver's concrete type. 232 func (server *Server) RegisterName(name string, rcvr interface{}) error { 233 return server.register(rcvr, name, true) 234 } 235 236 func (server *Server) register(rcvr interface{}, name string, useName bool) error { 237 server.mu.Lock() 238 defer server.mu.Unlock() 239 if server.serviceMap == nil { 240 server.serviceMap = make(map[string]*service) 241 } 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 248 } 249 if sname == "" { 250 s := "rpc.Register: no service name for type " + s.typ.String() 251 log.Print(s) 252 return errors.New(s) 253 } 254 if !isExported(sname) && !useName { 255 s := "rpc.Register: type " + sname + " is not exported" 256 log.Print(s) 257 return errors.New(s) 258 } 259 if _, present := server.serviceMap[sname]; present { 260 return errors.New("rpc: service already defined: " + sname) 261 } 262 s.name = sname 263 264 // Install the methods 265 s.method = suitableMethods(s.typ, true) 266 267 if len(s.method) == 0 { 268 str := "" 269 // To help the user, see if a pointer receiver would work. 270 method := suitableMethods(reflect.PtrTo(s.typ), false) 271 if len(method) != 0 { 272 str = "rpc.Register: type " + sname + " has no exported methods of suitable type (hint: pass a pointer to value of that type)" 273 } else { 274 str = "rpc.Register: type " + sname + " has no exported methods of suitable type" 275 } 276 log.Print(str) 277 return errors.New(str) 278 } 279 server.serviceMap[s.name] = s 280 return nil 281 } 282 283 // suitableMethods returns suitable Rpc methods of typ, it will report 284 // error using log if reportErr is true. 285 func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType { 286 methods := make(map[string]*methodType) 287 for m := 0; m < typ.NumMethod(); m++ { 288 method := typ.Method(m) 289 mtype := method.Type 290 mname := method.Name 291 // Method must be exported. 292 if method.PkgPath != "" { 293 continue 294 } 295 // Method needs three ins: receiver, *args, *reply. 296 if mtype.NumIn() != 3 { 297 if reportErr { 298 log.Println("method", mname, "has wrong number of ins:", mtype.NumIn()) 299 } 300 continue 301 } 302 // First arg need not be a pointer. 303 argType := mtype.In(1) 304 if !isExportedOrBuiltinType(argType) { 305 if reportErr { 306 log.Println(mname, "argument type not exported:", argType) 307 } 308 continue 309 } 310 // Second arg must be a pointer. 311 replyType := mtype.In(2) 312 if replyType.Kind() != reflect.Ptr { 313 if reportErr { 314 log.Println("method", mname, "reply type not a pointer:", replyType) 315 } 316 continue 317 } 318 // Reply type must be exported. 319 if !isExportedOrBuiltinType(replyType) { 320 if reportErr { 321 log.Println("method", mname, "reply type not exported:", replyType) 322 } 323 continue 324 } 325 // Method needs one out. 326 if mtype.NumOut() != 1 { 327 if reportErr { 328 log.Println("method", mname, "has wrong number of outs:", mtype.NumOut()) 329 } 330 continue 331 } 332 // The return type of the method must be error. 333 if returnType := mtype.Out(0); returnType != typeOfError { 334 if reportErr { 335 log.Println("method", mname, "returns", returnType.String(), "not error") 336 } 337 continue 338 } 339 methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType} 340 } 341 return methods 342 } 343 344 // A value sent as a placeholder for the server's response value when the server 345 // receives an invalid request. It is never decoded by the client since the Response 346 // contains an error when it is used. 347 var invalidRequest = struct{}{} 348 349 func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply interface{}, codec ServerCodec, errmsg string) { 350 resp := server.getResponse() 351 // Encode the response header 352 resp.ServiceMethod = req.ServiceMethod 353 if errmsg != "" { 354 resp.Error = errmsg 355 reply = invalidRequest 356 } 357 resp.Seq = req.Seq 358 sending.Lock() 359 err := codec.WriteResponse(resp, reply) 360 if err != nil { 361 log.Println("rpc: writing response:", err) 362 } 363 sending.Unlock() 364 server.freeResponse(resp) 365 } 366 367 func (m *methodType) NumCalls() (n uint) { 368 m.Lock() 369 n = m.numCalls 370 m.Unlock() 371 return n 372 } 373 374 func (s *service) call(server *Server, sending *sync.Mutex, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) { 375 mtype.Lock() 376 mtype.numCalls++ 377 mtype.Unlock() 378 function := mtype.method.Func 379 // Invoke the method, providing a new value for the reply. 380 returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv}) 381 // The return value for the method is an error. 382 errInter := returnValues[0].Interface() 383 errmsg := "" 384 if errInter != nil { 385 errmsg = errInter.(error).Error() 386 } 387 server.sendResponse(sending, req, replyv.Interface(), codec, errmsg) 388 server.freeRequest(req) 389 } 390 391 type gobServerCodec struct { 392 rwc io.ReadWriteCloser 393 dec *gob.Decoder 394 enc *gob.Encoder 395 encBuf *bufio.Writer 396 } 397 398 func (c *gobServerCodec) ReadRequestHeader(r *Request) error { 399 return c.dec.Decode(r) 400 } 401 402 func (c *gobServerCodec) ReadRequestBody(body interface{}) error { 403 return c.dec.Decode(body) 404 } 405 406 func (c *gobServerCodec) WriteResponse(r *Response, body interface{}) (err error) { 407 if err = c.enc.Encode(r); err != nil { 408 return 409 } 410 if err = c.enc.Encode(body); err != nil { 411 return 412 } 413 return c.encBuf.Flush() 414 } 415 416 func (c *gobServerCodec) Close() error { 417 return c.rwc.Close() 418 } 419 420 // ServeConn runs the server on a single connection. 421 // ServeConn blocks, serving the connection until the client hangs up. 422 // The caller typically invokes ServeConn in a go statement. 423 // ServeConn uses the gob wire format (see package gob) on the 424 // connection. To use an alternate codec, use ServeCodec. 425 func (server *Server) ServeConn(conn io.ReadWriteCloser) { 426 buf := bufio.NewWriter(conn) 427 srv := &gobServerCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(buf), buf} 428 server.ServeCodec(srv) 429 } 430 431 // ServeCodec is like ServeConn but uses the specified codec to 432 // decode requests and encode responses. 433 func (server *Server) ServeCodec(codec ServerCodec) { 434 sending := new(sync.Mutex) 435 for { 436 service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec) 437 if err != nil { 438 if err != io.EOF { 439 log.Println("rpc:", err) 440 } 441 if !keepReading { 442 break 443 } 444 // send a response if we actually managed to read a header. 445 if req != nil { 446 server.sendResponse(sending, req, invalidRequest, codec, err.Error()) 447 server.freeRequest(req) 448 } 449 continue 450 } 451 go service.call(server, sending, mtype, req, argv, replyv, codec) 452 } 453 codec.Close() 454 } 455 456 // ServeRequest is like ServeCodec but synchronously serves a single request. 457 // It does not close the codec upon completion. 458 func (server *Server) ServeRequest(codec ServerCodec) error { 459 sending := new(sync.Mutex) 460 service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec) 461 if err != nil { 462 if !keepReading { 463 return err 464 } 465 // send a response if we actually managed to read a header. 466 if req != nil { 467 server.sendResponse(sending, req, invalidRequest, codec, err.Error()) 468 server.freeRequest(req) 469 } 470 return err 471 } 472 service.call(server, sending, mtype, req, argv, replyv, codec) 473 return nil 474 } 475 476 func (server *Server) getRequest() *Request { 477 server.reqLock.Lock() 478 req := server.freeReq 479 if req == nil { 480 req = new(Request) 481 } else { 482 server.freeReq = req.next 483 *req = Request{} 484 } 485 server.reqLock.Unlock() 486 return req 487 } 488 489 func (server *Server) freeRequest(req *Request) { 490 server.reqLock.Lock() 491 req.next = server.freeReq 492 server.freeReq = req 493 server.reqLock.Unlock() 494 } 495 496 func (server *Server) getResponse() *Response { 497 server.respLock.Lock() 498 resp := server.freeResp 499 if resp == nil { 500 resp = new(Response) 501 } else { 502 server.freeResp = resp.next 503 *resp = Response{} 504 } 505 server.respLock.Unlock() 506 return resp 507 } 508 509 func (server *Server) freeResponse(resp *Response) { 510 server.respLock.Lock() 511 resp.next = server.freeResp 512 server.freeResp = resp 513 server.respLock.Unlock() 514 } 515 516 func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err error) { 517 service, mtype, req, keepReading, err = server.readRequestHeader(codec) 518 if err != nil { 519 if !keepReading { 520 return 521 } 522 // discard body 523 codec.ReadRequestBody(nil) 524 return 525 } 526 527 // Decode the argument value. 528 argIsValue := false // if true, need to indirect before calling. 529 if mtype.ArgType.Kind() == reflect.Ptr { 530 argv = reflect.New(mtype.ArgType.Elem()) 531 } else { 532 argv = reflect.New(mtype.ArgType) 533 argIsValue = true 534 } 535 // argv guaranteed to be a pointer now. 536 if err = codec.ReadRequestBody(argv.Interface()); err != nil { 537 return 538 } 539 if argIsValue { 540 argv = argv.Elem() 541 } 542 543 replyv = reflect.New(mtype.ReplyType.Elem()) 544 return 545 } 546 547 func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mtype *methodType, req *Request, keepReading bool, err error) { 548 // Grab the request header. 549 req = server.getRequest() 550 err = codec.ReadRequestHeader(req) 551 if err != nil { 552 req = nil 553 if err == io.EOF || err == io.ErrUnexpectedEOF { 554 return 555 } 556 err = errors.New("rpc: server cannot decode request: " + err.Error()) 557 return 558 } 559 560 // We read the header successfully. If we see an error now, 561 // we can still recover and move on to the next request. 562 keepReading = true 563 564 dot := strings.LastIndex(req.ServiceMethod, ".") 565 if dot < 0 { 566 err = errors.New("rpc: service/method request ill-formed: " + req.ServiceMethod) 567 return 568 } 569 serviceName := req.ServiceMethod[:dot] 570 methodName := req.ServiceMethod[dot+1:] 571 572 // Look up the request. 573 server.mu.RLock() 574 service = server.serviceMap[serviceName] 575 server.mu.RUnlock() 576 if service == nil { 577 err = errors.New("rpc: can't find service " + req.ServiceMethod) 578 return 579 } 580 mtype = service.method[methodName] 581 if mtype == nil { 582 err = errors.New("rpc: can't find method " + req.ServiceMethod) 583 } 584 return 585 } 586 587 // Accept accepts connections on the listener and serves requests 588 // for each incoming connection. Accept blocks; the caller typically 589 // invokes it in a go statement. 590 func (server *Server) Accept(lis net.Listener) { 591 for { 592 conn, err := lis.Accept() 593 if err != nil { 594 log.Fatal("rpc.Serve: accept:", err.Error()) // TODO(r): exit? 595 } 596 go server.ServeConn(conn) 597 } 598 } 599 600 // Register publishes the receiver's methods in the DefaultServer. 601 func Register(rcvr interface{}) error { return DefaultServer.Register(rcvr) } 602 603 // RegisterName is like Register but uses the provided name for the type 604 // instead of the receiver's concrete type. 605 func RegisterName(name string, rcvr interface{}) error { 606 return DefaultServer.RegisterName(name, rcvr) 607 } 608 609 // A ServerCodec implements reading of RPC requests and writing of 610 // RPC responses for the server side of an RPC session. 611 // The server calls ReadRequestHeader and ReadRequestBody in pairs 612 // to read requests from the connection, and it calls WriteResponse to 613 // write a response back. The server calls Close when finished with the 614 // connection. ReadRequestBody may be called with a nil 615 // argument to force the body of the request to be read and discarded. 616 type ServerCodec interface { 617 ReadRequestHeader(*Request) error 618 ReadRequestBody(interface{}) error 619 WriteResponse(*Response, interface{}) error 620 621 Close() error 622 } 623 624 // ServeConn runs the DefaultServer on a single connection. 625 // ServeConn blocks, serving the connection until the client hangs up. 626 // The caller typically invokes ServeConn in a go statement. 627 // ServeConn uses the gob wire format (see package gob) on the 628 // connection. To use an alternate codec, use ServeCodec. 629 func ServeConn(conn io.ReadWriteCloser) { 630 DefaultServer.ServeConn(conn) 631 } 632 633 // ServeCodec is like ServeConn but uses the specified codec to 634 // decode requests and encode responses. 635 func ServeCodec(codec ServerCodec) { 636 DefaultServer.ServeCodec(codec) 637 } 638 639 // ServeRequest is like ServeCodec but synchronously serves a single request. 640 // It does not close the codec upon completion. 641 func ServeRequest(codec ServerCodec) error { 642 return DefaultServer.ServeRequest(codec) 643 } 644 645 // Accept accepts connections on the listener and serves requests 646 // to DefaultServer for each incoming connection. 647 // Accept blocks; the caller typically invokes it in a go statement. 648 func Accept(lis net.Listener) { DefaultServer.Accept(lis) } 649 650 // Can connect to RPC service using HTTP CONNECT to rpcPath. 651 var connected = "200 Connected to Go RPC" 652 653 // ServeHTTP implements an http.Handler that answers RPC requests. 654 func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { 655 if req.Method != "CONNECT" { 656 w.Header().Set("Content-Type", "text/plain; charset=utf-8") 657 w.WriteHeader(http.StatusMethodNotAllowed) 658 io.WriteString(w, "405 must CONNECT\n") 659 return 660 } 661 conn, _, err := w.(http.Hijacker).Hijack() 662 if err != nil { 663 log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error()) 664 return 665 } 666 io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n") 667 server.ServeConn(conn) 668 } 669 670 // HandleHTTP registers an HTTP handler for RPC messages on rpcPath, 671 // and a debugging handler on debugPath. 672 // It is still necessary to invoke http.Serve(), typically in a go statement. 673 func (server *Server) HandleHTTP(rpcPath, debugPath string) { 674 http.Handle(rpcPath, server) 675 http.Handle(debugPath, debugHTTP{server}) 676 } 677 678 // HandleHTTP registers an HTTP handler for RPC messages to DefaultServer 679 // on DefaultRPCPath and a debugging handler on DefaultDebugPath. 680 // It is still necessary to invoke http.Serve(), typically in a go statement. 681 func HandleHTTP() { 682 DefaultServer.HandleHTTP(DefaultRPCPath, DefaultDebugPath) 683 }