Skip to content
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

By default, retry only HTTP methods known to be idempotent, user can optionally configure other methods - fixes #298 #340

Merged
merged 2 commits into from
Feb 11, 2014

Conversation

mauricio
Copy link
Contributor

This changes the default at the retry middleware to retry only on methods known to be idempotent, other methods (POST, PATCH) will not be retried by default but the user can do so by sending in a :retryable_methods option when creating the connection.

Fixes #298.

@@ -86,7 +93,7 @@ def call(env)
env[:body] = request_body # after failure env[:body] is set to the response body
@app.call(env)
rescue @errmatch
if retries > 0
if retries > 0 && @options.retryable_methods.include?(env[:method])
Copy link
Contributor

Choose a reason for hiding this comment

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

I would rather encapsulate the check in a retry_request?(env) method and use it in this conditional

@mislav
Copy link
Contributor

mislav commented Feb 10, 2014

This is a good direction. However, I think it's essential that we allow configurability not just by HTTP method, but by the type of exception as well.

How about we allow injecting a lambda via options that will be given the exception instance and the env object prior to each retry, and repeat the request only if the lambda returned true? That way we can offload fine-grained control to the user.

@mauricio
Copy link
Contributor Author

@mislav whooops, sorry for the whitespace stuff, that's an unintended change.

@mislav
Copy link
Contributor

mislav commented Feb 10, 2014

I've tackled the unrelated CI failures on master. Please rebase to get CI passing for your PR

@mauricio
Copy link
Contributor Author

@mislav and there it is, made it a block (much nicer, definitely) and removed all the horrible whitespace changes.

And thanks for the incredibly fast and awesome feedback 👍

rescue @errmatch
if retries > 0
rescue @errmatch => exception
if retry_request?( retries, env, exception )
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: we don't use spaces inside parentheses

@mislav
Copy link
Contributor

mislav commented Feb 10, 2014

Yep, looks much cleaner now. Good work.

I still think we need to stop retrying non-idempotent requests by default. Yes, that will break backwards compatibility, but we can ship it in a next major release. Users who want to retry POST in some cases can explicitly do so via the retry configuration block.

Could you add the restriction as a separate commit? As for the old tests that do post() all over the place, they will break again as before, and you're free to change them to get() (or put() if they have a request body).

@mauricio
Copy link
Contributor Author

@mislav should I make the default for non-idempotent methods at the default handling block or have it as as separate parameter?

@mislav
Copy link
Contributor

mislav commented Feb 10, 2014

Let's always retry idempotent methods, as that should be safe theoretically. retry_if block would only be consulted for methods that otherwise wouldn't be retried, such as POST.

So, the internal logic hierarchy would be this:

retry_limit > idempotent_method > retry_if

@mislav
Copy link
Contributor

mislav commented Feb 10, 2014

Also, the next time you're rebasing: commit message subjects should be shorter, ~50 chars, and issue and other references put in the commit message (not subject).

adds a new option for the retry middleware allowing clients to give it a 768c4f0 mauricio_faraday

Sorry, I'm super-nitpicky about this stuff 😈

@mauricio
Copy link
Contributor Author

@mislav included the idempotent_methods option and better commit messages as well 😋

@mislav
Copy link
Contributor

mislav commented Feb 11, 2014

Looks great, thanks!. Although, I don't think idempotent methods list needs to be configurable. We know which methods are idempotent according to spec, and for every other method a person can use retry_if. Less configuration options = less for us to maintain.

So if you could take that option out, this will be ready to merge. You should rebase to master once again, as I pushed some changes to reduce possiblity for intermittent CI failures you were getting here.

retry_if allows users to provide a block that
will receive the env and exception objects
and should decide if the call should be retried
or not.

Fixes lostisland#298.
Only run retries if the method is known to be
idempotent. If it isn't, switch to use the retry_if
block to make the final decision, if it is known to
be idempotent allow it to be retried by default.
@mauricio
Copy link
Contributor Author

@mislav rebased and removed option :D

mislav added a commit that referenced this pull request Feb 11, 2014
Retry only HTTP methods known to be idempotent

User can optionally configure other methods.

Fixes #298
@mislav mislav merged commit 90faa57 into lostisland:master Feb 11, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Retry middleware should only retry GET, PUT, and DELETE requests by default
2 participants