rpc/client: check the context before sending message

We observe failure in TestEthClient/TxInBlockInterrupted which can be reproduced
by

	go test -test.v -run=^TestEthClient/TxInBlockInterrupted --count=100

	=== RUN   TestEthClient/TxInBlockInterrupted
	    ethclient_test.go:399: transaction should be nil
	--- FAIL: TestEthClient (0.03s)

The testcase expects to get context cancel error when cancelling context passed
to the ethclient call before doing the call. However, the rpc client's send does
not guarantee that order. It uses select to wait on sending action and
context.Done() simultaneously, so it is possible that the branch of sending
action is taken and we get the response without error. This commit adds a
non-blocking wait on context.Done() to catch the cancelled context before doing
the actually send.
This commit is contained in:
Bui Quang Minh 2023-11-22 14:00:04 +07:00
parent e9f59b5d5e
commit 6b9cd1847d
No known key found for this signature in database
GPG key ID: 9591AA13D0891B99

View file

@ -559,6 +559,13 @@ func (c *Client) newMessage(method string, paramsIn ...interface{}) (*jsonrpcMes
// send registers op with the dispatch loop, then sends msg on the connection.
// if sending fails, op is deregistered.
func (c *Client) send(ctx context.Context, op *requestOp, msg interface{}) error {
// Check the context before actually sending message
select {
case <-ctx.Done():
return ctx.Err()
default:
}
select {
case c.reqInit <- op:
err := c.write(ctx, msg, false)