// sendOne invokes the specified RPC on the supplied client when the // client is ready. On success, the reply is sent on the channel; // otherwise an error is sent. // // Do not call directly, but instead use sendOneFn. Tests mock out this method // via sendOneFn in order to test various error cases. func sendOne(client batchClient, timeout time.Duration, rpcContext *rpc.Context, done chan batchCall) { addr := client.remoteAddr if log.V(2) { log.Infof("sending request to %s: %+v", addr, client.args) } // TODO(tamird/tschottdorf): pass this in from DistSender. ctx := context.TODO() if timeout != 0 { ctx, _ = context.WithTimeout(ctx, timeout) } if localServer := rpcContext.GetLocalInternalServerForAddr(addr); enableLocalCalls && localServer != nil { reply, err := localServer.Batch(ctx, &client.args) done <- batchCall{reply: reply, err: err} return } go func() { c := client.conn for state, err := c.State(); state != grpc.Ready; state, err = c.WaitForStateChange(ctx, state) { if err != nil { done <- batchCall{err: newRPCError( util.Errorf("rpc to %s failed: %s", addr, err))} return } if state == grpc.Shutdown { done <- batchCall{err: newRPCError( util.Errorf("rpc to %s failed as client connection was closed", addr))} return } } reply, err := client.client.Batch(ctx, &client.args) done <- batchCall{reply: reply, err: err} }() }
// sendOne invokes the specified RPC on the supplied client when the // client is ready. On success, the reply is sent on the channel; // otherwise an error is sent. // // Do not call directly, but instead use sendOneFn. Tests mock out this method // via sendOneFn in order to test various error cases. func sendOne(opts SendOptions, rpcContext *rpc.Context, client batchClient, done chan batchCall) { addr := client.remoteAddr if log.V(2) { log.Infof("sending request to %s: %+v", addr, client.args) } if localServer := rpcContext.GetLocalInternalServerForAddr(addr); enableLocalCalls && localServer != nil { ctx, cancel := opts.contextWithTimeout() defer cancel() reply, err := localServer.Batch(ctx, &client.args) done <- batchCall{reply: reply, err: err} return } go func() { ctx, cancel := opts.contextWithTimeout() defer cancel() c := client.conn for state, err := c.State(); state != grpc.Ready; state, err = c.WaitForStateChange(ctx, state) { if err != nil { done <- batchCall{err: newRPCError( util.Errorf("rpc to %s failed: %s", addr, err))} return } if state == grpc.Shutdown { done <- batchCall{err: newRPCError( util.Errorf("rpc to %s failed as client connection was closed", addr))} return } } reply, err := client.client.Batch(ctx, &client.args) done <- batchCall{reply: reply, err: err} }() }