Example #1
0
func (e *Endpoint) serve_response(msg *Message) error {
	e.client.mutex.Lock()
	call, found := e.client.pending[msg.ID]
	delete(e.client.pending, msg.ID)
	e.client.mutex.Unlock()

	if !found {
		return fmt.Errorf("Server responded with unknown seq %v", msg.ID)
	}

	if msg.Error == nil {
		if call.Reply != nil {
			err := e.codec.UnmarshalResult(msg, call.Reply)
			if err != nil {
				call.Error = fmt.Errorf("Unmarshaling result: %v", err)
			}
		}
	} else {
		call.Error = rpc.ServerError(msg.Error.Msg)
	}

	// notify the caller, but never block
	select {
	case call.Done <- call:
	default:
	}

	return nil
}
Example #2
0
func extractError(resp ErrorResponse) error {
	if resp.Error != "" {
		if resp.Fatal {
			return platform.FatalError{errors.New(resp.Error)}
		}
		return rpc.ServerError(resp.Error)
	}
	return nil
}
Example #3
0
// CallWithCodec is used to perform the same actions as rpc.Client.Call but
// in a much cheaper way. It assumes the underlying connection is not being
// shared with multiple concurrent RPCs. The request/response must be syncronous.
func CallWithCodec(cc rpc.ClientCodec, method string, args interface{}, resp interface{}) error {
	request := rpc.Request{
		Seq:           atomic.AddUint64(&nextCallSeq, 1),
		ServiceMethod: method,
	}
	if err := cc.WriteRequest(&request, args); err != nil {
		return err
	}
	var response rpc.Response
	if err := cc.ReadResponseHeader(&response); err != nil {
		return err
	}
	if err := cc.ReadResponseBody(resp); err != nil {
		return err
	}
	if response.Error != "" {
		return rpc.ServerError(response.Error)
	}
	return nil
}