// ServiceRPC.Forward is the entry point for RPC calls. It wraps actual RPC calls // and provides a slot for the RequestInfo. The parameters to the actual RPC // calls are transmitted in a []byte, and are then marshalled/unmarshalled on // either end. func (srpc *ServiceRPC) Forward(in ServiceRPCIn, out *ServiceRPCOut) (err error) { m, ok := srpc.methods[in.Method] if !ok { err = errors.New(fmt.Sprintf("No such method %q", in.Method)) return } inValuePtr := reflect.New(m.Type().In(2)) err = bson.Unmarshal(in.In, inValuePtr.Interface()) if err != nil { return } // Allocate the out parameter of the RPC call. outType := m.Type().In(3) var outValue reflect.Value switch outType.Kind() { case reflect.Ptr: outValue = reflect.New(m.Type().In(3).Elem()) case reflect.Map: outValue = reflect.MakeMap(outType) default: panic("illegal out param type") } startTime := time.Now().UnixNano() params := []reflect.Value{ reflect.ValueOf(srpc.delegate), reflect.ValueOf(in.RequestInfo), inValuePtr.Elem(), outValue, } returns := m.Call(params) duration := time.Now().UnixNano() - startTime mc := MethodCall{ MethodName: in.Method, RequestInfo: in.RequestInfo, Duration: duration, } if srpc.log != nil { srpc.log.Item(mc) } out.Out, err = bson.Marshal(outValue.Interface()) if err != nil { return } erri := returns[0].Interface() out.Err, _ = erri.(error) return }
func (e *Encoder) Encode(v interface{}) (err error) { buf, err := bson.Marshal(v) if err != nil { return } _, err = e.w.Write(buf) return }
func (e *Encoder) Encode(v interface{}) (err error) { //fmt.Printf("encoding: %+v\n", v) buf, err := bson.Marshal(v) if err != nil { return } _, err = e.w.Write(buf) //fmt.Printf("encoded to: %v\n", buf) return }
func (c *ServiceClient) Send(requestInfo *skynet.RequestInfo, funcName string, in interface{}, outPointer interface{}) (err error) { // TODO: timeout logic s, err := c.getConnection(0) if err != nil { c.Log.Item(err) return } if requestInfo == nil { requestInfo = &skynet.RequestInfo{ RequestID: skynet.UUID(), } } sin := service.ServiceRPCIn{ RequestInfo: requestInfo, Method: funcName, } sin.In, err = bson.Marshal(in) if err != nil { return } sout := service.ServiceRPCOut{} // TODO: Check for connectivity issue so that we can try to get another resource out of the pool err = s.rpcClient.Call(s.service.Config.Name+".Forward", sin, &sout) if err != nil { c.Log.Item(err) } err = bson.Unmarshal(sout.Out, outPointer) if err != nil { return } c.connectionPool.Put(s) return }