// if an rpc reply comes in from a remote, match to request
if an rpc reply comes in from a remote, match to request
// if an rpc reply comes in from a remote match to request
func (twoway *Bilateral) rpcClientResponseHandler(item interface{}) error {
	switch item.(type) {
	case rpcClientTimeoutData: 
		timeout := item.(rpcClientTimeoutData)
		if request, ok := twoway.rpcReturns[timeout.id]; ok {
			log.Infof("timeout id: %d  request: %v", timeout.id, request)
			twoway.finishRequest(request)
		}
		return nil
	case rpcClientResponseData: 
		response := item.(rpcClientResponseData)
		buffer := bytes.NewBuffer(response.response)
		dec := gob.NewDecoder(buffer)
		var id uint32
		err := dec.Decode(&id)
		if nil != err {
			log.Errorf("id decode error: %v", err)
		}
		var method string
		err = dec.Decode(&method)
		if nil != err {
			log.Errorf("method decode error: %v", err)
		}
		var errmsg string
		err = dec.Decode(&errmsg)
		if nil != err {
			log.Errorf("errmsg decode error: %v", err)
		}
		request, ok := twoway.rpcReturns[id]
		if !ok || request.method != method {
			log.Infof("RPC response: expired")
			return nil
		}
		result := reflect.New(request.structType)
		resultElement := result.Elem()
		from := resultElement.FieldByName("From")
		replyError := resultElement.FieldByName("Err")
		reply := resultElement.FieldByName("Reply")
		log.Debugf("RPC response: result: %v", reply.Kind())
		from.SetString(response.from)
		if "" == errmsg {
			err = dec.Decode(reply.Addr().Interface())
			if nil != err {
				log.Errorf("…reply decode error: %v", err)
			}
		} else {
			replyError.Set(reflect.ValueOf(errors.New(errmsg)))
		}
		log.Debugf("RPC response: %q:%d %s(...) → %#v", response.from, id, method, reply.Interface())
		request.reply <- result
		if request.count <= 1 {
			log.Info("RPC response: done")
			twoway.finishRequest(request)
		} else {
			request.count -= 1
			log.Infof("RPC response: normal, remaining: %d", request.count)
		}
	default: 
	}
	return nil
}
func ( twoway * Bilateral ) rpcClientResponseHandler ( item interface { } ) error { switch item . ( type ) { case rpcClientTimeoutData : timeout := item . ( rpcClientTimeoutData ) if request , ok := twoway . rpcReturns [ timeout . id ] ; ok { log . Infof ( " " , timeout . id , request ) twoway . finishRequest ( request ) } return nil case rpcClientResponseData : response := item . ( rpcClientResponseData ) buffer := bytes . NewBuffer ( response . response ) dec := gob . NewDecoder ( buffer ) var id uint32 err := dec . Decode ( & id ) if nil != err { log . Errorf ( " " , err ) } var method string err = dec . Decode ( & method ) if nil != err { log . Errorf ( " " , err ) } var errmsg string err = dec . Decode ( & errmsg ) if nil != err { log . Errorf ( " " , err ) } request , ok := twoway . rpcReturns [ id ] if ! ok || request . method != method { log . Infof ( " " ) return nil } result := reflect . New ( request . structType ) resultElement := result . Elem ( ) from := resultElement . FieldByName ( " " ) replyError := resultElement . FieldByName ( " " ) reply := resultElement . FieldByName ( " " ) log . Debugf ( " " , reply . Kind ( ) ) from . SetString ( response . from ) if " " == errmsg { err = dec . Decode ( reply . Addr ( ) . Interface ( ) ) if nil != err { log . Errorf ( " e r) } } else { replyError . Set ( reflect . ValueOf ( errors . New ( errmsg ) ) ) } log . Debugf ( " r sponse.f r om,  i ,  m thod,  r ply.I n terface() ) request . reply <- result if request . count <= 1 { log . Info ( " " ) twoway . finishRequest ( request ) } else { request . count -= 1 log . Infof ( " " , request . count ) } default : } return nil }
if an rpc reply comes in from a remote, match to request
if an rpc reply comes in from a remote match to request
// handle a timeout message // handle normal message // get matching request or throw away invalid/expired requests // decode the result // send the from/result parts of the response // just throw away invalid items