@@ -93,11 +93,7 @@ func recvResponse(ctx context.Context, dopts dialOptions, t transport.ClientTran
93
93
}
94
94
95
95
// sendRequest writes out various information of an RPC such as Context and Message.
96
- func sendRequest (ctx context.Context , dopts dialOptions , compressor Compressor , callHdr * transport.CallHdr , t transport.ClientTransport , args interface {}, opts * transport.Options ) (_ * transport.Stream , err error ) {
97
- stream , err := t .NewStream (ctx , callHdr )
98
- if err != nil {
99
- return nil , err
100
- }
96
+ func sendRequest (ctx context.Context , dopts dialOptions , compressor Compressor , callHdr * transport.CallHdr , stream * transport.Stream , t transport.ClientTransport , args interface {}, opts * transport.Options ) (err error ) {
101
97
defer func () {
102
98
if err != nil {
103
99
// If err is connection error, t will be closed, no need to close stream here.
@@ -120,7 +116,7 @@ func sendRequest(ctx context.Context, dopts dialOptions, compressor Compressor,
120
116
}
121
117
outBuf , err := encode (dopts .codec , args , compressor , cbuf , outPayload )
122
118
if err != nil {
123
- return nil , Errorf (codes .Internal , "grpc: %v" , err )
119
+ return Errorf (codes .Internal , "grpc: %v" , err )
124
120
}
125
121
err = t .Write (stream , outBuf , opts )
126
122
if err == nil && outPayload != nil {
@@ -131,10 +127,10 @@ func sendRequest(ctx context.Context, dopts dialOptions, compressor Compressor,
131
127
// does not exist.) so that t.Write could get io.EOF from wait(...). Leave the following
132
128
// recvResponse to get the final status.
133
129
if err != nil && err != io .EOF {
134
- return nil , err
130
+ return err
135
131
}
136
132
// Sent successfully.
137
- return stream , nil
133
+ return nil
138
134
}
139
135
140
136
// Invoke sends the RPC request on the wire and returns after response is received.
@@ -183,6 +179,7 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
183
179
}
184
180
}()
185
181
}
182
+ ctx = newContextWithRPCInfo (ctx )
186
183
sh := cc .dopts .copts .StatsHandler
187
184
if sh != nil {
188
185
ctx = sh .TagRPC (ctx , & stats.RPCTagInfo {FullMethodName : method })
@@ -246,33 +243,49 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
246
243
if c .traceInfo .tr != nil {
247
244
c .traceInfo .tr .LazyLog (& payload {sent : true , msg : args }, true )
248
245
}
249
- stream , err = sendRequest (ctx , cc .dopts , cc .dopts .cp , callHdr , t , args , topts )
246
+ stream , err = t .NewStream (ctx , callHdr )
247
+ if err != nil {
248
+ if put != nil {
249
+ if _ , ok := err .(transport.ConnectionError ); ok {
250
+ // If error is connection error, transport was sending data on wire,
251
+ // and we are not sure if anything has been sent on wire.
252
+ // If error is not connection error, we are sure nothing has been sent.
253
+ updateRPCInfoInContext (ctx , rpcInfo {bytesSent : true , bytesReceived : false })
254
+ }
255
+ put ()
256
+ }
257
+ if _ , ok := err .(transport.ConnectionError ); (ok || err == transport .ErrStreamDrain ) && ! c .failFast {
258
+ continue
259
+ }
260
+ return toRPCErr (err )
261
+ }
262
+ err = sendRequest (ctx , cc .dopts , cc .dopts .cp , callHdr , stream , t , args , topts )
250
263
if err != nil {
251
264
if put != nil {
265
+ updateRPCInfoInContext (ctx , rpcInfo {
266
+ bytesSent : stream .BytesSent (),
267
+ bytesReceived : stream .BytesReceived (),
268
+ })
252
269
put ()
253
- put = nil
254
270
}
255
271
// Retry a non-failfast RPC when
256
272
// i) there is a connection error; or
257
273
// ii) the server started to drain before this RPC was initiated.
258
- if _ , ok := err .(transport.ConnectionError ); ok || err == transport .ErrStreamDrain {
259
- if c .failFast {
260
- return toRPCErr (err )
261
- }
274
+ if _ , ok := err .(transport.ConnectionError ); (ok || err == transport .ErrStreamDrain ) && ! c .failFast {
262
275
continue
263
276
}
264
277
return toRPCErr (err )
265
278
}
266
279
err = recvResponse (ctx , cc .dopts , t , & c , stream , reply )
267
280
if err != nil {
268
281
if put != nil {
282
+ updateRPCInfoInContext (ctx , rpcInfo {
283
+ bytesSent : stream .BytesSent (),
284
+ bytesReceived : stream .BytesReceived (),
285
+ })
269
286
put ()
270
- put = nil
271
287
}
272
- if _ , ok := err .(transport.ConnectionError ); ok || err == transport .ErrStreamDrain {
273
- if c .failFast {
274
- return toRPCErr (err )
275
- }
288
+ if _ , ok := err .(transport.ConnectionError ); (ok || err == transport .ErrStreamDrain ) && ! c .failFast {
276
289
continue
277
290
}
278
291
return toRPCErr (err )
@@ -282,8 +295,11 @@ func invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
282
295
}
283
296
t .CloseStream (stream , nil )
284
297
if put != nil {
298
+ updateRPCInfoInContext (ctx , rpcInfo {
299
+ bytesSent : stream .BytesSent (),
300
+ bytesReceived : stream .BytesReceived (),
301
+ })
285
302
put ()
286
- put = nil
287
303
}
288
304
return stream .Status ().Err ()
289
305
}
0 commit comments