-
Notifications
You must be signed in to change notification settings - Fork 20.1k
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
rpc: add method to test for subscriptions #25942
Conversation
Does it make any difference though? Like, even if you can pre-check IsHttp, does it make the caller code cleaner? if !cli.IsHttp(){
// handle cannot subscribe
}
sub, err := cli.SubscribeFilterLogs(ctx context.Context, ...)
if err := nil{
// handle cannot subscribe
} The So I'm sceptical, but maybe you have some better examples than I could come up with. |
Yeah it's also possible to deal with the returned error, but in that case the caller has to distinguish the category of error and needs to have something to subscribe to to actually call the |
I think IsHttp is the wrong level of abstraction to expose. For example, we might implement http2. Which arguably is http. But might very well support streaming. A more suitable thing to expose would be e.g. |
Make sense, changed accordingly. |
I have been thinking about this for a while today, and have made some edits. My conclusion is that we can add it, but the method will not help with the case where the server doesn't support subscriptions even when the transport protocol could support it. There is no way to query for support on the server other than just trying the operation itself, and so we're back to the approach that @holiman suggested: It's the best to just call It's always possible to check the error code. In the case where subscriptions are not supported, the error code will be
|
What we should verify, is whether the geth RPC server does indeed return the correct error code when calling |
Closing for the reason given in #25942 (comment) |
I've checked this, and it does not:
So that's what we should fix instead.
if errors.Is(err, rpc.ErrNotificationsUnsupported) {
/// ...not supported...
} Somehow that |
I have implemented the idea above. We should still debate if this is a useful direction or not. One thing I noticed is, changing the error code for 'notifications not supported' makes it impossible to distinguish the error from 'subscription not found', which also uses code -32601. We should probably change the latter error to return a different code, since the actual RPC method (e.g. |
@zhiqiangxu let me know what you think about the proposed solution |
TBH it seems too complicated, what I originally wanted was just to expose the underlying protocol and let the caller decide what to do. @holiman what do you think? |
I understand that. But what we found while exploring it, is that there also exist situations where the server does not support subscriptions even when the transport protocol is compatible. It is a great idea that your app or library should have a fallback for the case where subscriptions are not supported. We just want to ensure it will decide correctly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
rpcErr, ok := other.(Error) | ||
if ok { | ||
code := rpcErr.ErrorCode() | ||
return code == -32601 || code == legacyErrcodeNotificationsUnsupported |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What we might want to add add here, is a condition where this will only be considered equal when the method was XXX_subscribe
. That's pretty hard to do though.
This adds two ways to check for subscription support. First, one can now check whether the transport method (HTTP/WS/etc.) is capable of subscriptions using the new Client.SupportsSubscriptions method. Second, the error returned by Subscribe can now reliably be tested using this pattern: sub, err := client.Subscribe(...) if errors.Is(err, rpc.ErrNotificationsUnsupported) { // no subscription support } --------- Co-authored-by: Felix Lange <fjl@twurst.com>
)" This reverts commit e851e46.
)" This reverts commit e851e46.
ethclient.Client
has methods which're only valid whenisHTTP
is false(e.g.:Subscribe
), thus it's convenient to expose aIsHTTP
method so that users can do different things based on whether the underlying connection is http or not.