Exemplo n.º 1
0
// 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
}
Exemplo n.º 2
0
func (e *Encoder) Encode(v interface{}) (err error) {
	buf, err := bson.Marshal(v)
	if err != nil {
		return
	}
	_, err = e.w.Write(buf)

	return
}
Exemplo n.º 3
0
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
}
Exemplo n.º 4
0
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
}