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

Make settings more usable #57

Merged
merged 16 commits into from
Nov 21, 2020
Merged

Make settings more usable #57

merged 16 commits into from
Nov 21, 2020

Conversation

Ceridan
Copy link
Contributor

@Ceridan Ceridan commented Nov 18, 2020

[+] Move OnRetry, OnBreak, OnReset and OnHalfOpen actions to the ResiliencePoliciesSettings class. It allows us to initialize settings like this:

var settings = new ResiliencePoliciesSettings
{
    OnRetry = ...,
    OnBreak = ...,
};

[-]: Make all this actions internal in RetryPolicySettings and CircuitBreakerPolicySettings to avoid collisions when user possibly may set for example OnRetry action twice in different places.
[+]: Add guards to policy setters in ResiliencePoliciesSettings to avoid situation when the user pass null value to some settings. [+]: Policy setters also handle situations when for example OnRetry action property set first and then RetryPolicySettings set with new value.
[+]: Add some tests for this logic.
[-]: Get rid of IRetryPolicySettings, ICircuitBreakerPolicySettings and ITimeoutPolicySettings interfaces, because they allows users to create their own implementations which should work incorrectly.

Closes #52

TimeSpan overallTimeout,
TimeSpan timeoutPerTry,
RetryPolicySettings retryPolicyPolicySettings,
CircuitBreakerPolicySettings circuitBreakerPolicyPolicySettings)
Copy link
Contributor

Choose a reason for hiding this comment

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

I concern about the usability of this type.
Look:
I'm a client and create a new instance of CircuitBreakerPolicySettings to use this constructor. It looks strange that I cannot set up OnBreak/OnReset/OnHalfOpen in this instance directly, can it? What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought about it. Here we have a trade off between usability and "correctness" I could say. If we add OnBreak/OnReset/OnHalfOpen back to the CircuiteBreakerPolicySettings, we have to choose:

  1. Remove it from the root settings as it was before.
  2. Deal with inconsistent state. I mean settings creation like this:
var cbSettings = new CircuitBreakerPolicySettings
{
    OnBreak = myOnBreakHandler1,
};

var settings = new ResiliencePolicySettings
{
    OnBreak = myOnBreakHandler2,
    CircuitBreakerPolicySettings = cbSettings,
}

How should we choose between this two handlers? Last wins - could be confusing, because CB settings could be created somewhere in other place. Decorate CB OnBreak with root settings OnBreak? Possible, but overcomplicated in my opinion.

Copy link
Contributor Author

@Ceridan Ceridan Nov 20, 2020

Choose a reason for hiding this comment

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

I have one more idea about it. One of the major differences between our library and Polly is that Polly is like a Lego and your can build your own policies step-by-step choosing proper building blocks, but we provide a monolithic solution. You can tune it a bit, but you can't change the flow. In case of Polly it makes sense to keep OnRetry action inside the RetryPolicy because you can use it alone without other things, but in our case you can't choose to use or not one of the inner policies. It means, that our OnRetry action is actually top level action. Your choice is not to subscribe or not to action provided by RetryPolicy, you choose subscribe or not to Dodo.HttpClient.ResiliencePolicy OnRetry action. It is important difference.

@@ -2,16 +2,16 @@

namespace Dodo.HttpClientResiliencePolicies.TimeoutPolicy
{
public sealed class OverallTimeoutPolicySettings : ITimeoutPolicySettings
public class TimeoutPolicySettings
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should leave this class sealed to avoid misunderstanding the concept.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, the second thought, maybe this is an excess class because we don't have it in any public constructor at ResiliencePolicySettings. How I as a client can use it?
Two way here:

  1. Delete it (I know this was my idea to satisfy my wants for uniformity but it crashes by reality)
  2. Make it internal 😕

Copy link
Contributor Author

@Ceridan Ceridan Nov 20, 2020

Choose a reason for hiding this comment

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

Yes, you are right it should be sealed. I will fix that.
I thought about this class too. Class itself looks nice because we keep all settings in the similar manner, but when I am working on tests refactoring, creating new instance each time and passing there single argument looks boring. I think we could keep it internal and use inside the library, but the end-user should provide only TimeSpan structures. I will fix that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have made changes to this thing. I am playing a bit with TimeoutPolicy and decide to remove it. Code looks cleaner now. Also I leave only default constructor in the ResiliencePoliciesSettings because the overriden constructor solves the only problem of matching TimeSpan on TimeoutPolicySettings.

@Ceridan Ceridan merged commit 104c477 into milestone/v2.0.0 Nov 21, 2020
@Ceridan Ceridan deleted the friendly-settings branch November 21, 2020 13:54
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.

None yet

2 participants