-
Notifications
You must be signed in to change notification settings - Fork 10
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
http client doesn't retry after error #118
Comments
It isn't necessary to create a new channel, the problem you're seeing arises in the It should also work to say, for example: client2 := jrpc2.NewClient(ch, nil) // N.B. reusing the same channel The Usually when a stream breaks, it's not recoverable—and the Client doesn't have any deeper knowledge of its Channel so it can't tell that in this one case it would be OK to keep trying. For a socket, however, that would lead to the client looping forever reading EOF or EBADF or whatever the underlying transport says when it's closed/invalid. One way to work around this might be to wrap the client rather than the channel, e.g., // Warning: schematic, untested
type Client struct{
ch *jhttp.Channel
cli *jrpc2.Client
opts *jrpc2.ClientOptions
}
func NewClient(ch *jhttp.Channel, opts *jrpc2.ClientOptions) *Client {
return &Client{ch: ch, cli: jrpc2.NewClient(ch, opts), opts: opts}
}
func (c *Client) CallResult(ctx context.Context, method string, params, result any) error {
for ctx.Err() == nil {
err := c.cli.CallResult(ctx, method, params, result)
if err == nil {
return nil
} else if !isRetryable(err) {
return err
}
backoffForRetry()
// Maybe also: limit retry count
c.cli = jrpc2.NewClient(c.ch, c.opts)
}
return ctx.Err()
} or words to that effect. (You might also need a lock if you want it to be usable concurrently, and so on). [1]: Or at least, not using the standard library's HTTP client. And reimplementing all of HTTP is out of scope here 🙂 |
I see, thanks. I was expecting the client to work like Go's http client (which doesn't bail out if it cannot connect) |
Unfortunately not, the client assumes a channel that's already connected, so there's no separate dial phase the client could use to detect that. |
I am using jrpc2 v1.2.0
This test:
fails with:
It works if I recreate the after the server, i.e.:
I don't know if it's expected behavior, but I was expecting the client to try again after getting a connection-refused error (Just like Go's http client).
I spent hours debugging what the problem was, see stellar/stellar-rpc#207
The text was updated successfully, but these errors were encountered: