Skip to content

Commit fac9fc2

Browse files
committed
Use golang.org/x/sync/singleflight for version negotiation
This allows multiple requests to be executed concurrently, without hammering the _ping endpoint and version-negotiation to happen for each request. Signed-off-by: Sebastiaan van Stijn <[email protected]>
1 parent 8f64a1e commit fac9fc2

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

client/client.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import (
5555
"github.com/docker/docker/api/types/versions"
5656
"github.com/docker/go-connections/sockets"
5757
"github.com/pkg/errors"
58+
"golang.org/x/sync/singleflight"
5859
)
5960

6061
// ErrRedirect is the error returned by checkRedirect when the request is non-GET.
@@ -84,6 +85,10 @@ type Client struct {
8485
// manualOverride is set to true when the version was set by users.
8586
manualOverride bool
8687

88+
// negotiate allows API version negotiation to be called concurrently,
89+
// reusing the API Ping call.
90+
negotiate singleflight.Group
91+
8792
// negotiateVersion indicates if the client should automatically negotiate
8893
// the API version to use when making requests. API version negotiation is
8994
// performed on the first request, after which negotiated is set to "true"
@@ -228,8 +233,11 @@ func (cli *Client) ClientVersion() string {
228233
// added (1.24).
229234
func (cli *Client) NegotiateAPIVersion(ctx context.Context) {
230235
if !cli.manualOverride {
231-
ping, _ := cli.Ping(ctx)
232-
cli.negotiateAPIVersionPing(ping)
236+
cli.negotiate.Do("negotiateAPIVersion", func() (interface{}, error) {
237+
ping, _ := cli.Ping(ctx)
238+
cli.negotiateAPIVersionPing(ping)
239+
return nil, nil
240+
})
233241
}
234242
}
235243

0 commit comments

Comments
 (0)