question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Proposal] Should we keep or remove the non-generic `ResilienceStrategy`

See original GitHub issue

Recent enhancements to ResilienceStrategy<T> (#1428) have significantly improved the usability of generic resilience strategies, expanding use-case scenarios:

ResilienceStrategy<object> strategy = NullResilienceStrategy<object>.Instance;

int v1 = strategy.Execute(() => 10);
string v2 = strategy.Execute(() => "val");
bool v3 = strategy.Execute(() => true);

This progress paves the way for potential removal of the non-generic ResilienceStrategy type and associated infrastructure. This proposal brings both advantages and disadvantages that should be thoroughly assessed before making a decision.

Advantages

  1. Reduced API Surface: This major advantage simplifies maintenance efforts.
  2. Inherent Support for Reactive Strategies: Currently, reactive strategies utilize OutcomeResilienceStrategy as a base class, bridging ResilienceStrategy to ResilienceStrategy<T>. This change would render the bridge class obsolete, integrating support for reactive strategies directly.

Disadvantages

  1. Complex Strategy Composition: The existing resilience strategy implements ResilienceStrategy, which lacks a generic constraint, facilitating strategy composition. If non-generic strategies are removed, the new ResilienceStrategy<T> signature would restrict composability to strategies of T or ResilienceStrategy<object>.
  2. Imposed Constraints on Non-Reactive Strategies: Strategies such as Timeout and RateLimiter are indifferent to result types and can naturally be executed across all result types. Under the new model, these strategies would no longer have this “natural implementation.”
  3. Lack of Inherent Support for Void Result Types: The removal of ResilienceStrategy would eliminate a straightforward method for executing void-based callbacks. While a VoidResult type could be introduced, usage would be more complex than the existing system.
  4. Complicated Usage of ResilienceStrategy: Presently, it’s simple to pass and flow ResilienceStrategy in the API for basic scenarios or when exceptions are exclusively handled by the consumer. In the proposed model, passing ResilienceStrategy<object> feels less intuitive.

Current Usage:

ResilienceStrategy strategy = new ResilienceStrategyBuilder()
    .AddTimeout(TimeSpan.FromSeconds(10))
    .AddRetry(new RetryStrategyOptions
    {
        RetryCount = 4,
        BaseDelay = TimeSpan.FromSeconds(10),
    })
    .Build();

ResilienceStrategyRegistry<string> registry = new ResilienceStrategyRegistry<string>();
ResilienceStrategy strategyFromRegistry = registry.GetStrategy("my-strategy");

strategy.Execute(() => "dummy");
strategy.Execute(() => 10);
strategy.Execute(() => { SomeCall(); });

New usage:

ResilienceStrategy<object> strategy = new ResilienceStrategyBuilder<object>()
    .AddTimeout(TimeSpan.FromSeconds(10))
    .AddRetry(new RetryStrategyOptions<object>
    {
        RetryCount = 4,
        BaseDelay = TimeSpan.FromSeconds(10),
    })
    .Build();

ResilienceStrategyRegistry<string> registry = new ResilienceStrategyRegistry<string>();
ResilienceStrategy<object> strategyFromRegistry = registry.GetStrategy<object>("my-strategy");

strategy.Execute(() => "dummy");
strategy.Execute(() => 10);
strategy.Execute(() => { SomeCall(); return VoidResult.Instance; });

Contributes to #1365

Would love your feedback and insights on this matter before we proceed with any modifications, as these changes could significantly affect the usability of V8.

@martincostello @joelhulen @juraj-blazek @geeknoid @PeterCsalaHbo @andrey-noskov @vany0114

Issue Analytics

  • State:closed
  • Created 2 months ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

4reactions
adamnovacommented, Jul 26, 2023

I agree that unifying the builders would improve maintainability. However, the new usage looks to me like an API limitation workaround. I believe that object should be used sparingly in a type safe language and with this change it would likely be introduced to many use cases that do not care about the result. All this adds to complexity and makes Polly more difficult to use for anyone who just picks it up.

To me generic/non-generic is the intuitive way to do it. If I care about a result, I specify the type. If I don’t I don’t specify anything. The unification would be fine, if C# had standard object type for null/void/no data. But instead it treats void special, so I think Polly should do it the same way, not try to be different.

Ease of use is probably the most important thing. If it’s too difficult, people would rather write it themselves, usually all they need is just retries and you can do that fairly easily.

3reactions
joelhulencommented, Jul 27, 2023

I agree with the others here who believe that removing non-generic strategies has more cons than pros, not least of which is adding complexity where there is no clear benefit in doing so for most developers/use cases. Explicitly using object and introducing a VoidResult type seems hacky and would give our API a bad sense of code smell. I do not think that we should remove the non-generic types.

Read more comments on GitHub >

github_iconTop Results From Across the Web

The Quest for Resilience
The Strategic Challenge: Resilience requires alternatives as well as awareness—the ability to create a plethora of new options as compelling alternatives to ...
Read more >
A Generic Quantitative Approach to Resilience: A Proposal
This paper proposes a generic quantitative approach to defining and measuring resilience. A simple resilience model is introduced using five critical states of ......
Read more >
From Resistance to Transformation: A Generic Metric of ...
We propose to do this through the development of a generalizable metric of resilience. For this we rely on a mathematical formalism—the ...
Read more >
3 Resilience and Ecosystem Services | An ...
Considerations of resilience are especially important in systems that undergo persistent and fundamental shifts in structure and function after disturbances ...
Read more >
Climate-Resilient Pathways: Adaptation, Mitigation, and SD
Adaptation is considered a response strategy to anticipate and cope with impacts that cannot be (or are not) avoided under different scenarios of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found