-
Notifications
You must be signed in to change notification settings - Fork 167
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
Faraday retry middleware #490
Conversation
cc @astencel-sumo who knows more about faraday than me at this point. and @grosser. I'm fine in principle with adding
If we already decided to expose
This sounds interesting! A possibly overlapping goal: for auth renewal #393, I believe we'll need a new object that can be used by multiple Feels like kubeclient might be decomposed into 2 halves:
(plus compat code for current However, the division of work is a bit trickier than [Sorry for getting off-topic. Trying to get some idea which direction we should navigate towards... This faraday stuff is new to me 😁] |
This is very useful, thanks @timothysmith0609 ! Nice piece of middleware, too. I like how it says it will honor the As for lazy initializing of the Faraday client, I think I didn't put much thought into it. I believe this is how it's been before my changes (in the |
lib/kubeclient/common.rb
Outdated
if block_given? | ||
yield(connection) | ||
else | ||
connection.use(FaradayMiddleware::FollowRedirects, limit: @http_max_redirects) | ||
connection.response(:raise_error) | ||
end |
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.
It might just be easier to slip the block in here and always use lines 323, 324; that might actually be the behaviour people would expect, now that I think about it....
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.
Ok, I've changed this to always include :raise_error
and FollowRedirects
. I think those assumptions are baked into the client enough to justify their forced inclusion (I'll be sure to document that in the README, mind you)
lib/kubeclient/common.rb
Outdated
def with_faraday_config(&block) | ||
@faraday_client = create_faraday_client(&block) | ||
end | ||
|
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.
I've changed my approach following your suggestion to expose this method which takes a block that yields the Faraday::Connection
object, which is really the only place we can specify all the middlewares and other config. Let me know if you think this is on the right track. (Once we settle on an approach I'll do the relevant README updates as well)
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.
nice 👍
lib/kubeclient/common.rb
Outdated
@@ -99,6 +99,10 @@ def initialize_client( | |||
end | |||
end | |||
|
|||
def with_faraday_config(&block) |
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.
it looks like this could be called multiple times, but it can't ... so maybe call it replace_faraday_config
... and would seem more intuitive to specify this during initalization anyway like configure_faraday: -> {|c| stuff }
I've started looking into this more closely. I think it's somewhat orthogonal to what I'm trying to do here (we can probably opportunistically refresh tokens on I do think you're right that the way forward is to clean up our abstractions a little bit. The manner in which information flows from config -> client seems too opaque and inflexible, and it would be beneficial to get a global sense of all the clients in use so we can centralize e.g. their token refresh. |
FYI for some basic retry logic: #493 |
Thanks! Some hesitation I had around writing a non-configurable retry logic were the following:
|
True, but I'd also like there to be a simple `retry a bit` option that does
not involve learning faraday middlewares :)
…On Fri, Mar 5, 2021 at 1:05 PM Timothy Smith ***@***.***> wrote:
FYI for some basic retry logic: #493
<#493>
Thanks! Some hesitation I had around writing a non-configurable retry
logic were the following:
- Different clients may have different appetites for retrying certain
operations (e.g. by HTTP verb)
- A generic configuration allows injection of custom middlewares,
which can support wider use-cases
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#490 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAACYZ3YMK42U6G5D2KTVO3TCFBQ7ANCNFSM4YG3CGUQ>
.
|
I see 2 arguments to prefer a generic
Could the "learning faraday middlewares" concern be covered by adding an example to the README for retries? I'm OK with merging either of them if you reach consensus which you prefer. |
I like this point a lot. It would be great if we could untangle the
For 99% of people, they will probably be happy to completely ignore this feature, and a quick blurb in the README for the rest of us should be sufficient 🎉 |
@timothysmith0609 please add documentation in README and I'll merge this. |
dfb78a0
to
eb673a1
Compare
README is updated 🎉 |
cc @cben (it's been a while since I've played around in this repo. Hope you're doing well!)
We find ourselves rewriting retry logic around kubeclient handlers to deal with intermittent API-server unavailability and figured it would be convenient to declare retry logic inside kubeclient itself. There's definitely some discussion to be had on the actual implementation but I wanted to post my work so far to get the ball rolling.
How it works
Expose a
retry_options
option toKubeclient::Client.new
that is passed into the Faraday client initializer. This is convenient because:Discussion
I see the Faraday client is lazily instantiated at the moment, though I've proactively initialized it in order to pass in the retry options inside the client initializer. I'm tempted to always initialize it, and refactor things so that we don't need a separate Faraday client for API vs. explicit-REST requests. Alternatively, we can simply leave retry options as an instance var itself, and pass them into Faraday when necessary. An even more engineered solution might be to extract Faraday client building into its own object 🤭
Interested to hear your thoughts