Closed
Description
Currently it can silently retry requests, but now it's forbidden:
http://tools.ietf.org/html/rfc7230
A user agent MUST NOT automatically retry a request with a non-
idempotent method unless it has some means to know that the request
semantics are actually idempotent, regardless of the method, or some
means to detect that the original request was never applied.
related to #258
Activity
ValleZ commentedon Sep 4, 2014
When connection timeout set to 6 seconds OkHttp retries requests (even POST requests) in 6 seconds and throws InterruptedIOException in 12 seconds.
ValleZ commentedon Sep 5, 2014
Seems in my case it retries because it tries TLSv1 first and then SSLv3...
swankjesse commentedon Sep 5, 2014
What does the application layer do when it encounters a flaky network? Does it just retry anyway?
ValleZ commentedon Sep 5, 2014
No, it doesn't. Middle layer is Volley with explicit zero numbers of retries set for each request. Top application layer doesn't do retries as well without user's consent. I'm still investigating issue - for now I can only stable reproduce the retry in a "controlled environment" with mocked server, where I see fall backs to SSLv3 for second call invocation. The behavior makes sense from one point of view - it's reasonable to try another transport if first one fails, but not in case when the server is actually busy processing first request and the call changes a state on backend (i.e. it's not a GET request).
swankjesse commentedon Sep 5, 2014
Right now
HttpEngine.recover()
is quite aggressive about recovering from problems. We assume everyone is using idempotence in their application layer; that's the best way to mitigate connectivity problems.It's possible some applications are using queries to see if a broken attempt was completed and not retrying if it was. That's clumsy.
ValleZ commentedon Sep 5, 2014
The thing is that apache http implementation is much better for serious applications because it's quite hard task to implement the idempotence for case when you, for example, purchase something. In same time ALL applications expect that network request may fail, but there are very few apps which expect that request will be sent more than once. It's probably okay for regular downloads, but is is inacceptable behavior for requests which change state. Think about chat applications - how fun is to send 2 messages instead one only because you switched from apache to okhttp? How fun is to spend money twice? How great is to get response "sorry, you already did it" instead expected response? Is is much bigger problem then to break some garbage which doesn't expect that network requests fails eventually.
ValleZ commentedon Sep 5, 2014
one more time, http://tools.ietf.org/html/rfc7230#section-6.3.1:
"A user agent MUST NOT automatically retry a request with a non-
idempotent method unless it has some means to know that the request
semantics are actually idempotent, regardless of the method, or some
means to detect that the original request was never applied."
okhttp don't know if a request is actually idempotent. Only app layer knows that, that's why say Volley have ability to retry calls. OkHttp have no idea if request is idempotent in therefore must not retry it silently.
ValleZ commentedon Sep 5, 2014
related: http://www.ravellosystems.com/blog/beware-http-requests-automatic-retries/
ValleZ commentedon Sep 6, 2014
my quick fix is https://github.com/ValleZ/okhttp/commit/7b108596e531fc367ebd7840228939b3a862f6ed
For better backward comparability there probably should be a switch which turns the retries off for a request, but seems I cannot quickly implement it with grateful switching route for next requests.
ValleZ commentedon Sep 10, 2014
The fix above is bad because it breaks recovery of closed connections :-(
ValleZ commentedon Sep 10, 2014
This should work better but it doesn't guarantee that a request will not be sent twice
https://github.com/ValleZ/okhttp/commit/a58b2f27eda3862a75d3f5adeb89f4565e542e32
briancarlstrom commentedon Sep 22, 2014
okhttp implements the silent fallback from TLS to SSL v3.0 similar to Chrome as part of supporting TLS intolerance: https://www.imperialviolet.org/2011/02/04/oppractices.html However, it probably is a good thing to let clients talking to known TLS tolerant servers disable this behavior.
swankjesse commentedon Sep 28, 2014
I think we want to write tests to require that non-GET requests are never retried (possibly breaking compatibility with HttpURLConnection). And
GET
requests will be retried, so that users don't see broken images etc. when connection reuse is in play.[-]OkHttp must not silently retry requests[/-][+]Don't recover if a non-GET request fails[/+]swankjesse commentedon Sep 28, 2014
(Fixing this may also permit us to nuke
RetryableSink
and all of its related complexity)10 remaining items
yogurtearl commentedon Nov 12, 2014
Any change of getting this into 2.1? :)
In general, it would be nice to have a configurable retry policy. Something like:
swankjesse commentedon Nov 12, 2014
You've missed the boat on 2.1. We'll conquer this very soon.
Qubitium commentedon Nov 27, 2014
+1 this. Would love a global RetryPolicy setting for both GET/POST/ANY...We are in the same boat using Okhttp behind Volley and despite us disabling retries in volley, Okhttp is still retrying requests that we don't want retried.
yogurtearl commentedon Dec 1, 2014
2.2? :)
passsy commentedon Dec 3, 2014
+1
I really like the
RetryPolicy
idea from volley. But it should be possible to get the maximum request duration for every request.Fix reply twice
New API to disable retry for an OkHttpClient.
New API to disable retry for an OkHttpClient.
New API to disable retry for an OkHttpClient.