Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpcclient: Use passed contexts over websocket connections. #2198

Merged
merged 2 commits into from
May 27, 2020

Conversation

JoeGruffins
Copy link
Member

rpcclient: Stop client on ctx done.

The passed context was ignored until a reconnect. This kills the client
when the passed context is done. This is much more useful for consumers
who need the clien to shut down when their context if finished.

rpcclient: Add a lifetime to requests.

Requests over websocket would block indefintely waiting for a response.
This adds a way for the caller to cancel requests, such as using a
context with deadline.

@JoeGruffins JoeGruffins force-pushed the wsctx branch 3 times, most recently from d952fc6 to f1067f5 Compare May 9, 2020 05:00
@JoeGruffins JoeGruffins marked this pull request as ready for review May 9, 2020 05:03
@JoeGruffins
Copy link
Member Author

Can write tests if needed.

rpcclient/infrastructure.go Outdated Show resolved Hide resolved
@JoeGruffins JoeGruffins force-pushed the wsctx branch 3 times, most recently from ce45637 to 0d483f5 Compare May 16, 2020 12:34
Copy link
Member

@davecgh davecgh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The updates look good overall. I've left some inline comments that address a few things, including a bug.

rpcclient/infrastructure.go Outdated Show resolved Hide resolved
rpcclient/infrastructure.go Outdated Show resolved Hide resolved
rpcclient/mining.go Outdated Show resolved Hide resolved
@davecgh
Copy link
Member

davecgh commented May 20, 2020

This will also need a rebase over master as it conflicts with #2205.

The passed context was ignored until a reconnect. This kills the client
when the passed context is done. This is much more useful for consumers
who need the client to shut down when their context if finished.
@JoeGruffins
Copy link
Member Author

JoeGruffins commented May 22, 2020

are futureError and newFutureError in infrastructure.go the same? It there a reason for having both? newNilFutureResult in notify.go also doesn't seem needed as it is just futureError(ctx, nil).

@davecgh
Copy link
Member

davecgh commented May 22, 2020

Both futureError and newFutureError are indeed the same. It looks to me like it's likely leftover from a merge conflict, because the only place it is used is the GetCFilterHeaderAsync and GetCFilterAsync calls, both or which were the result of merging them in from upstream. futureError can be removed.

rpcclient/infrastructure.go Outdated Show resolved Hide resolved
Store the initial context in result types and stop waiting on context
done with ErrRequestCanceled by giving all result types a context field
and having receiveFuture stop waiting on context done with an
ErrRequestCanceled. Result types have been changed from a channel of
*response to a new cmdRes type that can hold the context.

Remove duplicate function futureError and unused sendCmdAndWait.
Copy link
Member

@davecgh davecgh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good to go now. I'm going to give it a thorough testing before approval.

Copy link
Member

@davecgh davecgh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested this pretty well and everything seems to be working as expected.

In addition to just general testing in the normal positive paths, I particularly focused testing on context cancellation at various points as follows:

  • Before the call has been sent to the server
  • After the call has been sent to the server, but before the response has been received
  • After the response has been received from the server

One thing to keep in mind is that because the async receive machinery is selecting across the context and the response channel and Go has fair random channel selection, it is a coin flip as to whether or not the call to Receive will succeed in the case the context is cancelled when the response has already been received from the server.

I personally think this is both acceptable and appropriate behavior since the caller really shouldn't be trying to read a response after cancelling the context anyway, but I thought it was worth mentioning since any addition of tests around this behavior would need to account for that possibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants