Skip to content

Commit 5976062

Browse files
committed
client: manually implement Wait backoffs
When calling client.Wait, we want to avoid the default backoff behavior, because we want to achieve a quick response back once the server becomes active. To do this, without modifying the entire client's exponential backoff configuration, we can use conn.ResetConnectBackoff, while attempting to reconnect every second. Here are some common scenarios: - Server is listening: the call to Info succeeds quickly, and we return. - Server is listening, but is behind several proxies and so latency is high: the call to Info succeeds slowly (up to minConnectTimeout=20s), and we return. - Server is not listening and gets "connection refused": the call to Info fails quickly, and we wait a second before retrying. - Server is not listening and does not respond (e.g. firewall dropping packets): the call to Info fails slowly (by default after minConnectTimeout=20s). After the call fails, we wait a second before retrying. Signed-off-by: Justin Chadwell <[email protected]> (cherry picked from commit f1d7f2e) Signed-off-by: Justin Chadwell <[email protected]>
1 parent 37d534c commit 5976062

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

client/client.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/url"
99
"os"
1010
"strings"
11+
"time"
1112

1213
contentapi "github.com/containerd/containerd/api/services/content/v1"
1314
"github.com/containerd/containerd/defaults"
@@ -186,16 +187,29 @@ func (c *Client) Dialer() session.Dialer {
186187
}
187188

188189
func (c *Client) Wait(ctx context.Context) error {
189-
opts := []grpc.CallOption{grpc.WaitForReady(true)}
190-
_, err := c.ControlClient().Info(ctx, &controlapi.InfoRequest{}, opts...)
191-
if err != nil {
192-
if code := grpcerrors.Code(err); code == codes.Unimplemented {
190+
for {
191+
_, err := c.ControlClient().Info(ctx, &controlapi.InfoRequest{})
192+
if err == nil {
193+
return nil
194+
}
195+
196+
switch code := grpcerrors.Code(err); code {
197+
case codes.Unavailable:
198+
case codes.Unimplemented:
193199
// only buildkit v0.11+ supports the info api, but an unimplemented
194200
// response error is still a response so we can ignore it
195201
return nil
202+
default:
203+
return err
204+
}
205+
206+
select {
207+
case <-ctx.Done():
208+
return ctx.Err()
209+
case <-time.After(time.Second):
196210
}
211+
c.conn.ResetConnectBackoff()
197212
}
198-
return err
199213
}
200214

201215
func (c *Client) Close() error {

0 commit comments

Comments
 (0)