For example usage of cancellation token needs throwing OperationCancelledException, but currently it's not possible to express that I don't want to retry such exceptions
SlyNet,
You could do this
Policy.Handle<Exception>(ex => !(exception is OperationCancelledException))
Yes, thanks. But fluent interface like Handle<Exception>().Except<OperationCancelledException> would be readable?
SlyNet,
Thanks for you input, I will consider adding this. In the meantime, If you wanted to, your could add this as an extension method in your code.
Hi, Michael
Something like .Except
Common case I have came across is not wanting to retry on Timeout.
Reasonings are:
Could you probably suggest better solution to handling this type of situation?
Thank you.
Hi @kbabiy (Michael Wolfenden has stepped back from Polly by the way; the AppvNext team have now taken stewardship.)
I'll reflect further on an .Except(...) feature: I can see a syntax like this would suit some situations.
Aspects to think through would be how it played alongside the existing syntax. For instance, what would be meant by the following?
Policy
.Handle<X>()
.Or<Y>()
.Except<A>()
.Or<B>()
Should B be taken to be excluded or included by that? (And would the decision be clear to all users, whichever we chose?). It would probably be clearer to say that 'whitelisting' and 'blacklisting' exceptions could not be mixed, and 'all except' was an entirely alternative fluent stream. eg
Policy
.HandleAllExcept<X>()
.Or<Y>(); // Clearer here that Y is not handled?
We'd also then need a way to combine that with the fact that Polly can also now handle return results. We probably wouldn't want to mix blacklisting and whitelisting in the same syntax, so result-handling would have to follow the 'all except' pattern too.
Policy
.HandleAllExcept<X>()
.Or<Y>()
.AndAllResultsExcept<TResult>(...)
.OrResult<TResult>(...) // etc
Beginning to become quite complex to follow ...
We always have to consider whether extra API surface/complication adds sufficient benefit ... jury slightly still out for me on this one, given that there is already a workround (and taking into account the complex play with handling results). _Very happy however for further community feedback on this_.
@kbabiy Regarding other ways to handle the scenario:
Timeout quite probably means that requested resource is in trouble (working on top of its capacity)
and adding retries makes things even worse
... you have described the classic case for using a CircuitBreaker wrapping (or wrapped by) the Retry policy. See the very similar description about when retries become counter-productive, in the introductions to Retry and CircuitBreaker in the wiki.
Perhjaps consider wrapping a CircuitBreaker (perhaps breaking specifically on TimeoutException) in with your Retry.
Hi, @reisenberger
Thank you for suggestion about CircuitBreaker. I know of this concept and reviewed it again after your suggestion, but i think it doesn't exactly fit (seems to be too radical) in my case, though generally makes a lot of sense in the similar scenarios.
As far as i understand problem with the Except originally proposed probably comes from the existing Or API being the only option to extend the Handle clause - therefore adding any And-like condition (like Except, AndNot, And etc.) leads to the unnecessary complex binary expressions being possible
Therefore adding the blacklisting approach (like HandleAllExcept) looks like a cleaner solution, even though needing symmetrical changes in the results handling (which probably also makes sense to extend with blacklisting).
Hopefully the benefit of such changes will overweight the needed API complications
Most helpful comment
SlyNet,
You could do this
Policy.Handle<Exception>(ex => !(exception is OperationCancelledException))