Comments (5)
Thanks to reporting. I will create a test case to reproduce and confirm.
from diehard.
hi @iarenaza , I'm not sure if I understand correctly. According to your description, this added case should fail but it passed:
from diehard.
I probably expressed myself wrong, but maybe an example might be more clear. Try this in both diehard 0.7.2 and 0.8.x:
(require '[diehard.core :refer :all])
(let [counter (atom 0)]
(with-retry {:fallback (fn [& _] (swap! counter inc))
:max-retries 5}
(println "Trying...")
(swap! counter inc)
(throw (Exception.)))
(prn @counter))
In 0.7.2 you get:
Trying...
Trying...
Trying...
Trying...
Trying...
Trying...
7
nil
That is, in 0.7.2, the body of the retry block is executed 6 times (the original one, plus the 5 configured retries). And because all the retries end up in an exception (which is the default condition for a failed block), the fallback is executed and we get the result produced by it: 6 produced by the retry-block body (including the retries), plus 1 added by the fallback.
While in 0.8.x you get:
Trying...
2
nil
While in 0.8.x, the body of the retry block is executed just one time and there are no retries at all (in spite of the 5 configured retries). The fallback is directly executed after the first block execution failure and we get the result produced by it: 1 produced by the retry-block body (as there are no retries), plus 1 added by the fallback.
This is even more evident if you attach listeners to :on-retry
. On 0.7.2:
(require '[diehard.core :refer :all])
(let [counter (atom 0)]
(with-retry {:fallback (fn [& _] (swap! counter inc))
:on-retry (fn [v e] (println "Failed, gonna retry"))
:max-retries 5}
(println "Trying...")
(swap! counter inc)
(throw (Exception.)))
(prn @counter))
you get:
Trying...
Failed, gonna retry
Trying...
Failed, gonna retry
Trying...
Failed, gonna retry
Trying...
Failed, gonna retry
Trying...
Failed, gonna retry
Trying...
7
nil
On 0.8.x you get:
Trying...
2
nil
So a it's a major change in behavior, as the fallback is executed instead of the retries stated by the retry policy.
As I said in my initial comment, this is due to the way the policies are composed in 0.8.x (fallback has become a regular policy in failsafe 2.0.x, instead of a special case). The fallback policy is executed before the retry policy. And as the fallback policy produces a value that is not considered a failed execution for the next policy (the retry policy in this case), then the whole retry block is considered as executed successfully. And thus there are no retries at all.
By swapping the way the policies are composed (as shown in my initial comment), the behaviour stays the same as in versions prior to 0.8.x
I'll address why your test doesn't fail in a separate comment.
from diehard.
@iarenaza Thanks! I can reproduce this issue and confirm this behaviour in 82b6b51
from diehard.
Released in 0.8.3
from diehard.
Related Issues (20)
- Document types and arity of circuit breaker options HOT 1
- :backoff-ms documentation does not match failsafe docs HOT 1
- question on future(...) contruct use HOT 1
- callback on-failure
- Get rid of reflection warnings HOT 1
- Allow retry on Throwable HOT 6
- upgrade to 0.9.3 produces Execution error, 'Unable to resolve spec: ...' HOT 5
- Cannot use listeners with predefined policy HOT 2
- 0.10.1 regression: max-retries not respected HOT 3
- Thank you 🤗 and link to a similar tool
- Use of getFailure is deprecated in FailSafe HOT 2
- cljdoc not accessible since 0.11.4 HOT 2
- Instant cannot be cast to Duration HOT 3
- `Fallback` doesn't support `.handleResult` HOT 6
- NullPointerException when combining with-retry and with-timeout HOT 1
- Cljdoc build failure HOT 4
- Circuit breaker not opening HOT 2
- Exceptions thrown from :on-failure or :on-retries-exceeded are swallowed HOT 3
- Fallback value is not used
- Reflection warnings HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from diehard.