Skip to content
This repository has been archived by the owner on May 7, 2024. It is now read-only.

Configurable client for faster timeouts #50

Merged
merged 8 commits into from
May 9, 2017
Merged

Configurable client for faster timeouts #50

merged 8 commits into from
May 9, 2017

Conversation

marians
Copy link
Member

@marians marians commented May 5, 2017

This PR adds a way to configure the API client for

  • quicker timeouts where appropriate, e. g. when listing organizations
  • Setting a user agent string

This is applied for all API requests.

The motivation were lots of timeouts when using our current leaseweb-g8s backend, especially in commands like list clusters, where multiple requests are made.

Technically this could have been part of gsclientgen, but in fact I don't want to add code there, as all code in that repository is generated by swagger.

@marians marians requested review from xh3b4sd and oponder May 5, 2017 09:20
}
apiClient := NewClient(clientConfig)
_, _, err := apiClient.GetUserOrganizations("foo", "foo", "foo", "foo")
if err == nil || !strings.Contains(err.Error(), "Client.Timeout exceeded") {
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to not compare strings for error assertions. Isn't there an error type we can compare against?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll give that a try

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately, the error type isn't specific enough: *url.Error.

Copy link
Contributor

Choose a reason for hiding this comment

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

When it is a URL error, we can check if it is an timeout error. See https://golang.org/pkg/net/url/#Error.Timeout.


func TestTimeout(t *testing.T) {
clientConfig := Configuration{
Endpoint: "http://httpbin.org/delay/2?",
Copy link
Contributor

Choose a reason for hiding this comment

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

This test now depends on the network and some remote service. When either of these fails, the test fails. An alternative would be to start a test server and sleep in its handler to simulate the delay. See https://golang.org/pkg/net/http/httptest/.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think depending on the network for tests should be fine. But I will look at the alternative. Having it totally internal is definitely better.

responseBody, apiResponse, _ := client.AddCluster(authHeader, addClusterBody, requestIDHeader, createClusterActivityName, cmdLine)
clientConfig := client.Configuration{
Endpoint: cmdAPIEndpoint,
Timeout: 60 * time.Second,
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be cool to define a default timeout which we can use where needed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

client := gsclientgen.NewDefaultApiWithBasePath(cmdAPIEndpoint)
clientConfig := client.Configuration{
Endpoint: cmdAPIEndpoint,
Timeout: 3 * time.Second,
Copy link
Contributor

Choose a reason for hiding this comment

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

What is actually the reasoning behind the very different timeouts?

Copy link
Member Author

@marians marians May 9, 2017

Choose a reason for hiding this comment

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

I want to fail fast in situations where multiple GET calls are made in sequence. E. g. when listing clusters, we first fetch all the organizations (memberships). Then we look for clusters in each org. This failing after one minute (as it happened just recently with flapping API behaviour) is just a really bad waste of time for the end user. I'd rather fail after a few seconds and let the user retry.

In cases of transactions (POST, PUT, PATCH) I'd like to tolerate longer timeouts, as we expect a little bit more work to happen on the other end, and retrying might not be as easy (unless transactions are implemented for that route).

The next step of course will be doing the retrying automatically, so the user doesn't have to bother at all in most cases.

It's a tiny step, but I see it as a little piece in a bigger resiliance picture.

@codecov-io
Copy link

codecov-io commented May 9, 2017

Codecov Report

Merging #50 into master will increase coverage by 1.93%.
The diff coverage is 56%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #50      +/-   ##
==========================================
+ Coverage   28.42%   30.36%   +1.93%     
==========================================
  Files          22       23       +1     
  Lines         781      830      +49     
==========================================
+ Hits          222      252      +30     
- Misses        535      554      +19     
  Partials       24       24
Impacted Files Coverage Δ
commands/commands.go 34.21% <0%> (-2.94%) ⬇️
commands/logout.go 6.45% <0%> (-0.96%) ⬇️
commands/delete_cluster.go 11.11% <0%> (-1.02%) ⬇️
config/config.go 31.5% <0%> (-0.89%) ⬇️
commands/login.go 6.38% <0%> (-0.6%) ⬇️
commands/create_cluster.go 8.69% <0%> (-0.17%) ⬇️
commands/list_clusters.go 64.28% <100%> (+3.75%) ⬆️
client/client.go 100% <100%> (ø)
commands/create_keypair.go 64.44% <100%> (+2.53%) ⬆️
commands/create_kubeconfig.go 43.95% <100%> (+3.95%) ⬆️
... and 3 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 329fbff...6b312f3. Read the comment docs.

@marians
Copy link
Member Author

marians commented May 9, 2017

@xh3b4sd Thanks for the review! Happy for a re-check.

Copy link
Contributor

@xh3b4sd xh3b4sd left a comment

Choose a reason for hiding this comment

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

Maybe sort out the URL timeout error check using the types and methods they provide instead of string matching. That would be cool. LGTM otherwise. Thanks for taking care.

// enforce a timeout longer than the client's
time.Sleep(3 * time.Second)
fmt.Fprintln(w, "Hello")
}))
Copy link
Contributor

Choose a reason for hiding this comment

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

I like that way more than before. Cool.

@marians
Copy link
Member Author

marians commented May 9, 2017

Changed error type checking.

@marians marians merged commit 3f4fe62 into master May 9, 2017
@marians marians deleted the faster-timeouts branch May 9, 2017 11:32
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants