func (c *Conn) Call(ctx context.Context, method string, params, result interface{}) (_ ID, err error) {
	// generate a new request identifier
	id := ID{number: atomic.AddInt64(&c.seq, 1)}
	call, err := NewCall(id, method, params)
	if err != nil {
		return id, fmt.Errorf("marshaling call parameters: %v", err)
	}
	ctx, done := event.Start(ctx, method,
		tag.Method.Of(method),
		tag.RPCDirection.Of(tag.Outbound),
		tag.RPCID.Of(fmt.Sprintf("%q", id)),
	)
	defer func() {
		recordStatus(ctx, err)
		done()
	}()
	event.Metric(ctx, tag.Started.Of(1))
	// We have to add ourselves to the pending map before we send, otherwise we
	// are racing the response. Also add a buffer to rchan, so that if we get a
	// wire response between the time this call is cancelled and id is deleted
	// from c.pending, the send to rchan will not block.
	rchan := make(chan *Response, 1)
	c.pendingMu.Lock()
	c.pending[id] = rchan
	c.pendingMu.Unlock()
	defer func() {
		c.pendingMu.Lock()
		delete(c.pending, id)
		c.pendingMu.Unlock()
	}()
	// now we are ready to send
	n, err := c.write(ctx, call)
	event.Metric(ctx, tag.SentBytes.Of(n))
	if err != nil {
		// sending failed, we will never get a response, so don't leave it pending
		return id, err
	}
	// now wait for the response
	select {
	case response := <-rchan:
		// is it an error response?
		if response.err != nil {
			return id, response.err
		}
		if result == nil || len(response.result) == 0 {
			return id, nil
		}
		if err := json.Unmarshal(response.result, result); err != nil {
			return id, fmt.Errorf("unmarshaling result: %v", err)
		}
		return id, nil
	case <-ctx.Done():
		return id, ctx.Err()
	}
}
// Call sends a request over the connection and then waits for a response.
// If the response is not an error, it will be decoded into result.
// result must be of a type you an pass to json.Unmarshal.
Call sends a request over the connection and then waits for a response.
If the response is not an error, it will be decoded into result.
result must be of a type you an pass to json.Unmarshal.
// Call sends a request over the connection and then waits for a response . // If the response is not an error it will be decoded into result . // result must be of a type you an pass to json . Unmarshal .
func (c *Conn) Call(ctx context.Context, method string, params, result interface{}) (_ ID, err error) {
	id := ID{number: atomic.AddInt64(&c.seq, 1)}
	call, err := NewCall(id, method, params)
	if err != nil {
		return id, fmt.Errorf("marshaling call parameters: %v", err)
	}
	ctx, done := event.Start(ctx, method,
		tag.Method.Of(method),
		tag.RPCDirection.Of(tag.Outbound),
		tag.RPCID.Of(fmt.Sprintf("%q", id)),
	)
	defer func() {
		recordStatus(ctx, err)
		done()
	}()
	event.Metric(ctx, tag.Started.Of(1))
	rchan := make(chan *Response, 1)
	c.pendingMu.Lock()
	c.pending[id] = rchan
	c.pendingMu.Unlock()
	defer func() {
		c.pendingMu.Lock()
		delete(c.pending, id)
		c.pendingMu.Unlock()
	}()
	n, err := c.write(ctx, call)
	event.Metric(ctx, tag.SentBytes.Of(n))
	if err != nil {
		return id, err
	}
	select {
	case response := <-rchan:
		if response.err != nil {
			return id, response.err
		}
		if result == nil || len(response.result) == 0 {
			return id, nil
		}
		if err := json.Unmarshal(response.result, result); err != nil {
			return id, fmt.Errorf("unmarshaling result: %v", err)
		}
		return id, nil
	case <-ctx.Done():
		return id, ctx.Err()
	}
}
func ( c * Conn ) Call ( ctx context . Context , method string , params , result interface { } ) ( _ ID , err error ) { id := ID { number : atomic . AddInt64 ( & c . seq , 1 ) } call , err := NewCall ( id , method , params ) if err != nil { return id , fmt . Errorf ( " " , err ) } ctx , done := event . Start ( ctx , method , tag . Method . Of ( method ) , tag . RPCDirection . Of ( tag . Outbound ) , tag . RPCID . Of ( fmt . Sprintf ( " " , id ) ) , ) defer func ( ) { recordStatus ( ctx , err ) done ( ) } ( ) event . Metric ( ctx , tag . Started . Of ( 1 ) ) rchan := make ( chan * Response , 1 ) c . pendingMu . Lock ( ) c . pending [ id ] = rchan c . pendingMu . Unlock ( ) defer func ( ) { c . pendingMu . Lock ( ) delete ( c . pending , id ) c . pendingMu . Unlock ( ) } ( ) n , err := c . write ( ctx , call ) event . Metric ( ctx , tag . SentBytes . Of ( n ) ) if err != nil { return id , err } select { case response := <- rchan : if response . err != nil { return id , response . err } if result == nil || len ( response . result ) == 0 { return id , nil } if err := json . Unmarshal ( response . result , result ) ; err != nil { return id , fmt . Errorf ( " " , err ) } return id , nil case <- ctx . Done ( ) : return id , ctx . Err ( ) } }
Call sends a request over the connection and then waits for a response.
Call sends a request over the connection and then waits for a response .
// generate a new request identifier // We have to add ourselves to the pending map before we send, otherwise we // are racing the response. Also add a buffer to rchan, so that if we get a // wire response between the time this call is cancelled and id is deleted // from c.pending, the send to rchan will not block. // now we are ready to send // sending failed, we will never get a response, so don't leave it pending // now wait for the response // is it an error response?