 On today's Visual Studio Toolbox, Carl is going to show us a tool called Poly, which gives us the ability to handle transient errors caused by service outages. Yeah. Hi, welcome to Visual Studio Toolbox. I'm your host, Robert Green, and on today's show, we're going to address the problem of services in the Cloud that can go down, and what can you do to make your applications more resilient? To do that, I asked my good friend, Mr. Carl Franklin to join us to talk about a tool called Poly. Hey, Carl, how are you? Hey, how are you doing? Welcome to the Caves of Altamira. Hey. My wine cellar. Welcome to Visual Studio Toolbox. Carl, of course, is the co-host of the iconic and long-running .NET Rocks podcast. You were a guest in the 40s or something, right? When I was in my 40s? No, no, no. Show number 40 something. Episode number 43, if I recall correctly, December 15th, 2003, when I was the Product Manager for Visual Studio Tools for Office. Yes. Now, 17 years later, I'm returning the favor and having you on Toolbox. I appreciate it. Thanks. I wanted to wait until you were good at this thing. So, Poly gives us resiliency, transient error handling. We're going to do this as two parts. We're going to do a shorter introduction, and then in the second part, we'll dive into more detail. Right. Yes. So, Poly is an interesting project that I noticed in the early 2000s, or the mid-2000s, I suppose. But the whole idea with this is that what happened to my thing? What happened to my thing, Robert? The whole idea with this is that you have services that are in the Cloud that are talking to each other. It's a microservices world. We're just living in it. So, the problem is when services go down, that you need to talk to, and you're counting on them being there, what do you do about that? I mean, it's one thing if you've got an application that's in the browser and your Wi-Fi goes down, you get a 500 and people expect that. They're like, well, my Internet's down, I think I'll figure out why that happened, and I'll come back and try again, and everything's fine. But that doesn't happen in the Cloud. So, in the Cloud, you've got these issues where one microservice is talking to another one downstream and nothing goes through. You'd make an HTTP request and nothing happens, and that could be for a number of reasons. One reason is that there's an Internet outage in the Cloud. That usually doesn't happen. But another reason is that the service is struggling. The service may be under a heavy load. The person who configured that service may not have given enough resources in order to handle the network load. So, what happens is that if you're just like in a steady retry loop, you're just retrying, retrying, retrying, you're putting even more load on that struggling service. It's almost like a denial of service fact that you didn't expect to get. You're not making the users happy, you're not giving them any useful information, they just think your app's terrible. Exactly. Exactly what happens. So, there are different scenarios and I think Netflix did a really good job of managing this with a circuit breaker pattern. The circuit breaker is we're going to do a few retries and maybe we'll spread them out and we'll get more time in between each retry. But after a minute or two, we're just going to stop. Right. We're going to stop sending requests. It reminds me of that old I Love Lucy episode where Lucy and Ethel were taking strawberries off a conveyor belt or something and trying to, and they just kept coming too fast and they're like throwing stuff in their mouth and stuff. I mean, this happens occasionally, little trial, trial, spin, spin, spin, and then it says we're having trouble playing this video. Right. Right. Which, yes, it's annoying, but at least it gives me the sense that they're going to stop trying so I can either watch something else or I can try again. It's better than just leaving me hanging. Yeah, exactly. And Gmail is a really good example of this, right? If your Wi-Fi goes down while you're using Gmail, it says, oops, at the top of it, it says, oops, something happened. We're going to try again in 30 seconds and it counts down, right? But if you want to retry now, you can. You can push that button. So Polly gives us the ability to do that in our .NET apps? Yeah, Polly gives you the ability to create policies and that's what Polly is really short for, policy, to create policies that say, we're going to retry three times and we're going to wait first 200 milliseconds and then times 10, times 10, whatever, maybe we'll do an exponential backoff and then maybe we'll stop, we'll do a circuit breaker, we'll just stop all requests from coming in. But this all happens at a policy level. So you have an HTTP client that actually the Polly mechanisms are built now into HTTP client factory in .NET Core. So essentially you can configure it all with a policy and then you just make a call and all the retries and stuff happen under the hood. You don't even worry about it. You just wait for the result to come back. That sounds cool. How's it work? Yeah, it's great. So what I like to tell people, the flip answer is Polly is a giant wrapper around try catch. And it's good to think of it like that because we use try catch all the time but the problem is, okay, you've caught an error. Now what do you do? Right. And most people just, I mean, the classic problem is like we ship that off to the user or we log the real exception details and then we tell the user a problem happened. Sorry, I don't know what to do. We'll just, I don't know, press this button. Right? So if you show my screen, I will show you the Polly repository on GitHub. And this is the standard repository and that look at how long this page is. I mean, the documentation is really good and it shows you all the different kinds of policies and samples and stuff, but if there's also a different samples repo. Oh, cool. That's what I'm gonna show you here. There's been a lot of work on Polly over the years and in fact, can I just mention some stats real quick? Sure. So we're getting almost 150,000 downloads of Polly every day. Wow. And the, it's definitely in the top 20 of open source projects to be downloaded, but if you take out duplicates like multiple X unit packages and Newton soft stuff, Polly is in the top 10. So it's a very, very popular, a very popular framework. So this is the Wiki right here and the Wiki is great if you wanna keep up with, the roadmap and where things are going and suggest stuff. But I think we should just jump over to some code, right? Yeah. Let's see how it works. So I've got, there's two parts to the project right here. There's a client application, which is just a console app. And we actually have this Polly test stop out on Azure if you wanna use that, but you can also use a local API. And the API project is actually running. Now this API project has a values controller right here. It's very simple, right? You pass an ID and it says response from server to request ID. So it's basically easy for you to use as a measuring device. But if you look in app settings JSON, there are these rules where we have this throttling engine that throttles based on a period of time and a number of requests. So this essentially says that the first three requests with any five second interval will come through just fine. On the fourth request within five seconds, we're gonna throw a 500 error, all right? So that's just how we can test. Now in the sample application, and this is in Polly samples, got a bunch of async and synchronous demos. I'm gonna use the async ones. So the first demo is no policy. In other words, this is in all of these demos, follow the same pattern. So you're gonna see the same code pretty much except for the policy and maybe a little bit of stuff. So let's go back to the demo here and you'll see what we've got here. We've got an execute async with a cancellation token and we're reporting some progress. We're creating a new HTTP client. There's no policy here, there's no failback. So this is like a typical kind of application, right? You have a try catch and in the try, we call this web API root API values and the total request, which is the number and we'll display that. And if we get an exception, we'll report that. And then we're gonna wait half a second and we'll go back and continue doing this demo. And then it shows some statistics. So this is the sort of pattern of these demos. So let me show you what happens with no error handling. And you can see the errors are in red, the good requests are in green. So one, two, three within five seconds happen and then these other ones through 10 don't, like this is what you'd expect, right? Right. Okay, when I press control C, we can close that. Now let's go to the next demo, which is a retry for N number of times. So this is the way that you create a policy in Poly. So here's the policy. We're handling a regular exception and you can put in whatever exceptions you want, right? You can list them out. And the policy name is retry async. So we're gonna retry three times. Okay. Okay, there's no delay in between each retry. It's just gonna retry three times. And by the way, these demos aren't, how shall I say, prescriptive. Like these aren't, hey, do it this way. We're showing you these demos to exercise the different policies so you can realize, you can understand what they do. Right. All right, so then we're reporting the progress. So now we have our HTTP client and within the try, we do an await policy execute async with a Lambda. And this is the code that we're gonna execute within the context of the policy. All right. And so this is essentially what happens. So we're calling, you know, it's the same deal except that we're executing it within the context of the policy. And there you go. So let's try this. We're gonna retry three times. And what happens is, boom, boom, boom. Too many requests, right? Then we call again, we get an error, boom, boom, boom. Those three in yellow are retries. Okay. All right, so the first three go through, we do three retries right in a row. So that's what happens when you just do a retry. What you really need to do is sort of wait in between each retry. And by the way, this right here, this code right here, this is essentially the exception handler. This is the code that executes when a retry happens. Right, you get the exemption in the attempt and this is what is shown in yellow right here. All right, let's go to the next one. And you can tell me when we need to stop and save the rest for the next show. Okay. I'll leave that up to you. So this is wait and retry a number of times, but the wait is the key here. We're waiting in between each retry. And you can see those yellow guys are taking a little bit longer to execute. That's because, let me pull up this code right here. What we're doing is we're saying our policy has a wait and retry three times, but we're waiting 200 milliseconds between each try. Otherwise, this code is exactly the same. All right. Okay. So we're getting the same failures. We just now have the ability to detect and do something about it, is that correct? Yeah, and these different types of policies give you the ultimate flexibility. And I'll show you how you can stack them and use them together. And that's where it really gets fun. Yeah. So why don't we stop here? Okay. So we'd keep these nice and short. And in the next, in the part two of this, in the second episode, we'll keep looking at the samples and get a little more in depth. Sounds good. But before we go, show me one thing. Show me how I hooked this all up. What do I need to add to my project? Oh, it's so free. Library. Yeah, it's so easy. You just install it via NuGet. Install dash package poly. Poly. If you can remember poly, you can install NuGet package poly. That's it. All right, excellent. So this would be a good place to stop. And in the next episode, we'll keep looking at this and see some additional scenarios.