-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
CircuitBreaker per downstream node, with shared named HttpClient #624
Comments
@shagilt. You need to define and maintain a separate circuit-breaker instance per downstream system for which you want circuits to break independently. There's more about this in the documentation here and here. Some other documentation also related to circuit-breaker and HttpClientFactory (only in case you haven't already seen them) : here and here. Here is an answer to a similar question recently. It suggests how you could use When you say:
is that a If so, you could:
Does that give you enough information to put / start putting a solution together? I may be able to find time to code this up more fully, but I would need to find couple of hours +/- somewhere - no promises exactly when that would be - I may not have that time in the coming 7 days or so (am in seminars all next week). So I'm preferring to get you some information/pointers today (this reply) rather than leave you waiting 7 or more days. Hope that helps. Let me know how you get on. |
Thank you @reisenberger . I will go thru the documentation you shared and update this thread sometime next week. Thanks again! |
@reisenberger Yes, your proposal worked, and my tests are working as expected now. What I did: Some of my downstream service instances has different keys.So, I have different key generation for different URL. So, I am planning to introduce a Func<HttpRequestMessage, string> to generate key from request’s URL or properties.
As per my understanding, we need different policy for different downstream service instances. Did you see this requirement more often? Are you planning to add this in Polly? I was thinking of writing new handler(same as PolicyHttpMessageHandler) and add key selection as argument. This way, user can provide their key selection logic and handler can keep track of policy for each down stream service. Do you see any issue with this?
Probably this can be added in PolicyHttpMessageHandler itself. Thoughts? |
@shagilt , glad this is working for you so far 👍 Re:
We are not planning to add anything in Polly around this, except ingredients which make the existing approach easier: the PolicySelector approach (or similar) could probably usefully be surfaced more clearly, either in Polly or Polly.Contrib. There was an early architectural decision whether to put dictionaries-of-policy-usage-circumstance-by-key inside policies (such as could have been placed inside circuit-breaker), or outside (like PolicyRegistry). We consciously chose outside because it offers more flexibility, and separation of concerns. And because multiple policy types (not just circuit-breaker) fall into this pattern. So, I am not sure if this was your question, but there are no plans to introduce a circuit-breaker policy which maintains an internal dictionary of states-by-key; we consciously chose not to. Re:
Something like this seems reasonable. It does not strictly need to be a new handler. If the intention is for the selection of policy by key from
(various defensive checks omitted for brevity - would want adding). EDIT: This code example only encompasses select-from-registry using the There are also some similar overloads in Hope that helps / let us know how you get on. |
Hi @shagilt . Here is an extension method on It combines your nice Internally, it uses a Does this cover your needs?
If this is looking good, we can consider adding this either to Polly, Polly-Contrib, or to HttpClientFactory (note: HttpClientFactory is outside my control; that would be a Microsoft decision); or to Polly documentation. Sidenote: The above code ^ doesn't make |
Hi, @reisenberger sorry for the delay in my response. Yes, this new extension will work for me, awesome! I am attaching my test code for key selection function. You can add this in sample or in test code of Polly as a reference.
Instead of documentation, we can add this as a new extension in Polly or HttpClientFactory. What is the process of getting this in HttpClientFactory? Other open question we need to document is: developer has to mange the life cycle of these new key based circuit breaker policies. Or how to mange stale policies in PolicyRegistry? |
@shagilt Glad this works for you. Great to have your enthusiasm to contribute! You can propose an extension to If the conclusion is (or if you prefer) for this to live on the Polly side rather than directly in (I'm proposing we manage (++) = (that link will not work yet; I will create that repo if we go this route) |
Re:
Can you expand a little on your thinking/questions here? PolicyRegistry has dictionary-like semantics including a .Remove(string key), so it is certainly possible to manually remove policies known to be no longer needed. That does raise broader questions (outside the scope of the code discussed so far) about how users may be managing the set of downstream endpoints. |
Note: I also didn't necessary propose |
What do you recommendation here? I think adding this to Polly side make more sense because it is clear that the new extension in Polly not in HttpClientFactory(.NET).
Say, a service instance is moved from Node1 to Node2. So, policy created for Node1 is no longer valid. I want to remove Node1 policy if it is not accessed in past 1 day. I know we can clean stale policies by using .Remove() method from PolicyRegistry. To do this, I need to know Last[Access][Used]Time for each policy. Is this possible with current Polly implementation? |
@shagilt Thanks - hoping to get back to this at the weekend. |
Hi @shagilt . Re:
I am good with having some extensions to @rynowak / @glennc : Do you have any concerns with the Polly team maintaining a package such as Polly.Contrib.HttpClientFactoryExtensions with more specialist extension overloads? Or would you like to see these all on the Microsoft side? Thus far, we are talking about an extension on
(circuit-breaker being the prime example - the principle extends to other Polly stateful policies) @shagilt Pending answers from the MS team, I've created the Polly.Contrib.HttpClientFactoryExtensions repo and invited you to the Polly-Contrib team. It would not be wasted to have developed and tested the concept there even if the MS teams do decide to take the overload to the MS side officially. /cc @joelhulen for info |
@reisenberger Thanks. I will setup the dev environment. |
We've merged this PR into aspnet/Extensions. I think this issue can be closed. Thanks @shagilt |
@shagilt @reisenberger do you have any examples of how to implement the scenario using the new extension method provided by @shagilt This is the exact scenario i need to implement into my solution: Try "https:/host1.example.com" I have tried following the docs and the PR but i am unable to see how to correctly implement. i feel an example would be useful for anyone trying to implement this scenario |
@shagilt Do you have any fully-worked sample on this? @theCorb1nator I might be able to put a small fully-worked sample together, but it would take a few hours to create, and might not happen for some weeks. The summary is:
... you might typically define a Retry policy outside the CircuitBreaker, with that retry policy specifically handling Something (pseudo-code, abbreviated) conceptually like:
As I say, this is a pseudo-code/conceptual sketch. Of course, you don't want to hard-code the nodes in
and make a Your configuration of the HttpClient might then change to:
@theCorb1nator The above is a 45-minute sketch to get you an answer now rather than leave you waiting a few weeks; please extrapolate from it, or query if necessary. @shagilt If you have a full example - or can see any missing elements or enhancements to the above - please say! |
Thanks for this @reisenberger i will keep you updated how i get on |
@reisenberger @theCorb1nator Sorry for the delay in my response, I was away for past few days. |
@reisenberger I don't see anything missing in your last post; your sample looks good. Thanks! |
Summary: What are you wanting to achieve?
We have multiple instances(10 instances on 10 different nodes) of a stateless service. One of our handlers, will select different endpoint(destination node) each time for load balancing.
We also used shared http client which is created using IHttpClientFactory.
When I wrote the test, I see error from one bad instance of my stateless destination service. This is opening the Circuit and not allowing any request at all.
Ideally, I want to open the circuit for bad instance and allow traffic for other instances. Is this possible with client created using IHttpClientFactory? What is your recommendation to achieve this?
What code or approach do you have so far?
It is always useful to see:
Configuring handlers:
serviceCollections.AddHttpClient(clientName)
.AddRetryPolicy() <-Polly retry policy
.AddHttpMessageHandler()
.AddCircuitBreakerPolicy() <-Polly circuit breaker policy
.AddHttpMessageHandler();
Create code:
var client = clientFactory.CreateClient(clientName);
The text was updated successfully, but these errors were encountered: