 My name is Glenn Gondren and I'm Ryan Noach. I'm a developer on the ASP net team at Microsoft. Cool I am a program manager on the dot net server team include which includes everything that he works on As well as some other stuff Some of you probably saw my talk earlier, I hope and today what we're going to do is Dive kind of deep into a bunch of upcoming.net core stuff 2.1 stuff. We originally had planned to do Kind of stuff for today stuff using 2.0 things that you might know today But then we watched all the talks and all of this schedule and when you know what these guys kind of got this covered So instead let's talk about stuff that we're more uniquely positioned to talk about and talk about some 2.1 Some future things stuff things like that right some guidance and best practices and stuff along the way ban So if there is a fire You should leave if you think that our talk is straight fire That's a different thing. Yeah, you should not leave you should come talk to us afterwards. Yeah, that's right You definitely should that's it. That's all the slides we have. I Hope that was as good for you as it was for us apparently I need to save this okay What are you gonna show them Glenn? That's super valuable Okay, so let's let's let's talk about this. I have here An ill-prepared presenting machine which by that I mean my fonts aren't big enough Scott Hanselman will be most disappointed in me So what I have here is just a file new web application. I've opened Visual Studio. I said file new web app Okay, I hope most have most of you done file new web app before and you have an appropriate amount of context on what that means So I haven't I've I cheated a little bit. I'll talk about that at the end That's mostly to get a couple of new packages in there But otherwise they're still exactly the same as as you could go do file new today And what I'm going to do is I'm going to come over here I'm gonna write some code that connects to the github API and pulls back the user data So I'm gonna go get github to give me the JSON that represents me and we'll put some of it on a web page Yeah, if any of you done this type of how many have any of you talked to the github API before? We'll try to write code to talk to github some of nobody. Excellent. This is gonna be an experience for you Okay, so first thing I'm gonna do is I'm gonna come over here into my configure services method Can we I'm quick poll of the audience? How many of you have already built something with ASP.net core before? Wow, okay. That's a good number. Good job. All right So so what I'm gonna do in here since most of you are certainly generally familiar with this I'm gonna say services dot ad HTTP client. How many people have used HTTP client before? I'm gonna say get smaller number than I expected. Yeah, github client And I'm gonna do this now. What is github client? I haven't heard of that before. Yeah, that's because I'm about to make it Look now it's thing now. This is how we make a feature done Okay, so what I've done here is I have said services dot ad HTTP client of T and I've given it a class called HTTP client I just generate. I just use visual studio to generate it So there's nothing in that class right now. What I'm gonna what I'm attempting to do here is to effectively Use that github client is like a repository. It's like a github repository pattern. It's kind of what I'm building here based around HTTP Now there's a few things here to talk about so I know that the API to talk to github All this is the base of their API It's API dot github.com So I'm gonna go over here, and I'm gonna go I'm gonna create Do this and then I'm gonna say client dot base address equals new URI Okay, like this Okay This is this is literally I used to be client in here this client I'm talking about and this is gonna become clear. It's a journey. Just bear with me Okay, it's all right. You can try and make it out. It's like a detective story. It'll be okay So the other thing the github needs is I want to send this except header every time I make any requests to github Okay, so now I'm gonna come over here. I'm gonna see dots. I'm gonna say default request headers dot add Let's just do this if you haven't done it should be client before you can add Headers that get set on every request that you yeah that you do you can configure the client to do certain things for you by Default another thing that I'm sure somewhere in the github doc shows you but isn't right there is that every Request to the github APIs requires a user agent All right, so I'm gonna create a user agent. Is that the correct user agent string for a user agent here? Awesome I Am the best around Okay, that's my user agent someone at github is gonna have a great day if they read these logs Okay, and that's what I'm gonna do Okay, so what I've defined here is the default configuration for when I want to talk to github using my github client, okay? So now what I'm gonna do is I'm gonna F12 on this github client gonna make it public because internal is bullshit and Then I'm gonna make a constructor Right and I'm gonna accept in here a HTTP client All right, and then I'm gonna control dot my way to glory like all good developers and Then you're gonna do this and it's gonna be great So this HTTP client in the constructor of this type will always have the code I just put in my configure services method already run on it Whenever I get it Right, so within this class. It's always configured the way that I just defined in that one place Okay, and so what I've basically built here is github client is my repository I'm gonna use it to always talk to github. Here's my configuration for HTTP client to talk to that I've got past my client in and I'm away. I can use it. I'm ready to go. So What did I say I was gonna do I'm gonna talk to the github API I'm gonna pull back the user Jason and return a user right so that means I want to do something like This is normal code, right? It's probably acing because I'm talking over the network That means I need a task Let's make a github user Get user will give it a string username. Does that seem reasonable? Some method like this. Has anybody written a method like this before? Probably have once again. I'm gonna control dot my way to glory and I'm gonna make this class in a new file That's gonna be good Okay, so this is what I want to do Right. I don't have a github user that seems problematic So I'm gonna jump over here. I'm gonna go into the user's part of the github API docs They conveniently provide me a sample Jason payload for what the user API returns. So I'm gonna copy this All right like this control C jump over here to this here I'm gonna f12 on my github user so that I've so I'm in here and delete this because I'm about to recreate it again I'm gonna go edit Paste special paste Jason as class bam Now I've got C sharp representation of that Jason payload that I just had then I'll rename it to github user, right? and now one thing I know By painful experience is that my particular user doesn't have a hireable state as a note as bull It happens to return null and the generated code didn't handle that So this needs to be a question mark to make the ball mullable If I had actually taken an actual payload from myself I would have seen that but because I took a sample payload that had all the data filled out filled out It's not too hard to work out. This by the way is a fantastic way to get started talking to a Jason based API. It's amazing So I have a type I know it's got every single property that the payload could return because I just copy and pasted it from the sample payload now I need to Talk to the github API. So now what I'm going to do is say via response equals oh wait Client dot get async and what I want to do here is I know From looking here that I that I want to go to this URL This is relative to the base API URL that we set back in our base configuration, right? So I'm just going to do that slash users slash username Sure, no one will ever write it call this method with any string that's going to cause a problem with string interpolation in a URI, right? Then I'm going to go response dot ensure success this method basically throws if it returns anything other than you know A 200 or something it'll do for now We'll ship it then I'm going to say return a wait Client dot content. Oh Not max for someone something to rather I've got to fix my weight because it says away. Where are you on that one? This is your accent. You had one job Okay, now client dot content Don't body on start content. I response not client. What am I thinking? Got a developer here to coach the PM on how to code. Yeah Now read async read as async github user BAM How's that look is that going to work? You par, huh? Nobody knows but they're just gonna say yes because otherwise I wouldn't have asked that question It wouldn't be a very good demo if it didn't work. Oh, no Okay, and so this is gonna go talk to the github API. It's gonna return me some content So let's go into our pages. I'm gonna go to the about page I want to look at the code behind the about page now in here I want to use that repository that we just created Right, we called it github client. All right, so I'm gonna accept github client, you know Let's call it that and I'm gonna control dot my way to glory again And then this message here doesn't want to be this anymore instead. I want to say bar user equals ghclient dot get user And I'm gonna get Glen C Which is my username then I'm gonna say string interpolation You're gonna need an await to yeah, I'm gonna need an await because that's not gonna work And that means I need to change this to async task And then user dot login Seems right, and then I'm gonna say what are the what are the data do I care about knowing about myself? I think you want other people to care about your follower account. Yeah, I do I do Yeah, that's what Twitter and github is all about right Followers how many followers do you have right? Do you know I think I have like a hundred seventy something. Yeah, I don't know it went up Since since we started working on blazer. Is it gonna be as many as me? I don't know maybe about to find out Okay, so then I'm gonna run it I'm running it here not with is just in the command line in the console click about What's it say it says crash? Look at that. I did got a Ensure status code failed before I fall not found right Now Let's look at I closed the browser and he closed my logs. That was a log stream. I was gonna look at some logs It was gonna be great. We're gonna see how good the logging information was. Thank you visual studio. Thank you our tooling I think your follower account just went down by three or four by four It's entirely possible So I got a 404 for the sake of time because you don't really have we don't really have lots of time Ryan needs to Get to his cool demo demos or talks stuff So what I believe I did wrong he is over here in github client. I suspect it's something like that But let's find out What I would have been able to see in the logs would have been the URL that was actually generated that got called How long it took why we got a 404 could have copied and pasted it into the browser We could have done that whole dance right checked it against the logs You'd think it was deliberate. I actually did it accidentally But I was gonna roll with it and just say look this time meant this the whole time look how good our logs are 215 boom that's pretty good. Yeah, that's pretty good. Okay. So now I've gone and talked to github Let's talk at some of our logs because I didn't get to see some of our logs before Can I control control control plus good job windows? Okay, so This code just here This code right here. This would be a little bit harder to see so that's okay I'm gonna describe it to you what this code is saying this code is showing you The get request going through the outgoing pipeline through the outgoing HTTP client. So what this says is it took 554 milliseconds to go and grab that user payload and bring it back shows me the URI that was made and the reason it's three or four statements is because the when you say get in the in my configuration code over here in startup CS The value of this isn't just that I made a repository and I managed to abstract away HTTP client so that I could do things like unit test my about page like over here in my about page now if I'm gonna Unit test if I'm gonna test this page I could just new it up and pass in a mock of my github client with my methods I don't need to worry about a should be client right it also codifies an outgoing middleware pipeline the same as incoming middleware Which means you can stitch together pieces of code that act upon an outgoing request For example, perhaps I could make a request against github and then have some like service discovery middleware piece That says takes that github resolves what the actual URI is and then like stamps and then like modifies the request or Built into our thing is a bunch of interesting diagnostics that we could talk about Ryan is gonna talk about the middleware pipeline What's our timing like do we have time to show structured logging right now? Let's show let's show real quick. Okay, so One of the things I did to cheat was added a package called Seq or any of you already familiar with seq or serilog No couple of people. Okay, good. Thanks. You just saved me. I was like man. I'm gonna have to okay So there that's basically just a logging framework like an analog or something like any of those lady logging framework You're familiar with it's one of them One of the things it does though is it analyzes log streams and kind of pulls information out in formats And it can understand and makes it kind of searchable and structured a bit like Elk does a lot of similar things like this So what we can do in here is say configure logging You can say log factory And now we're just gonna add the seq Log provider so now logs will go to the console as well as going off to this thing called seq right now I run my application and The now I've run my application and then I'm going to go to the browser once the browser pops I'm gonna click on about and It's gonna go say hey Glenn. You've got an amazing amount of followers Then I'm gonna click over here to this This browser window is what I've got is a local Windows service running seq all the logs are going to that This is a UI that's just hosted in that service so you can go search through logs It's just a quick way to set up a local kind of structured logging setup production. You can use this It's a product that a there's an open-source project that people support You're probably more familiar with this sort of thing coming from something like Elk or Kibana things like that But in here what I can start to see now is things like These right. Oh, I made a request against github and here's every all the information about that thing Right. Here's the uri that I did. Hey, look. There's my there's my user agent I could search for github in the search bar and it'll be like, okay. Here's all the things you did that talk to github right and then Somewhat more impressively if I clear this And I come over here and I go into my app settings if you were using steel toe You could have done this without restarting my project, right? Instead of changing this to trace and then rewriting my application if any of you saw the steel toe demos I'll do that on the fly in cloud foundry. It's amazing So now if I do that again, we have some extra trace information that you can get hold of and now In here we can start to see hopefully I don't see any trace information. Do I yeah, we can see this Right. So this log level this this information here, which only comes from trace He's basically like every header and every piece of information about the entire request pipeline that I just did So this is the entire response From github right now, that's cool cool as one log message But also if you notice every individual field of this thing is also an individual property in this list Which means every individual header is individually searchable Right and it knows which ones are ince so you can do things like search for status code greater than 400 And it will return you all log messages that have a status code property that's greater than 400 right It's kind of the value of structured logging and This information comes big you get this and this type of log statements for free as long as you're using that HGP pipeline to get to do your HTTP requests if you were to knew our patiently be client yourself You wouldn't get as much of this stuff We we added middle we added kind of outgoing middleware that looks at all the requests that comes through and makes a bunch of log statements for you right and So if you were to post this on cloud foundry because the log all the loggers because we're logging to the common logging system steel To if you're using steel, so they inject the logger that goes to the right places. No, they don't they just scrape console out Yeah, just console out. So you get all of this in the Cloud Foundry logs as well because the logging system does that for you And yeah, that's about all of my demos right good. That's good. So now should we take over Ryan is going to take over We're gonna do where to do an awkward mic switch and laptop switch here go Fast as you can. Okay. So what Ryan's gonna do is we're gonna switch lap switch switch the laptops over he is going to show you Running an application using a bunch of these features that we just talked about HGP client factory and such in cloud foundry with steel So talk about the integrations and how that works What he did is take the current music start if any of you've seen the music you I sample that the steel Guys show where they deploy it to cloud foundry. So he's got that he's got it running So we got a problem here and my business guys are telling me that we're losing lots of money We have a live site issue right now. That sounds bad So I know that we've been having reliability problems with this back-end service that we've been talking to mm-hmm, right? It's a it's a partner partner company that provides this data that we listen to and they've been having outages and things Have been getting flaky. So can we change the text to say not say better take your money elsewhere? I mean, I mean, that's what that's what my boss told me is is effectively what we're telling our customers So I put it in the code. Okay. So let's go and let's add I Want to fix this is a live site issue. We want to get this going So let's go and add some retries here and you'll see similar kind of stuff to what we saw before here So what you're saying here is the service just fails sometimes it just fails sometimes It's gonna retry we're just gonna retry. This is a networking connected application expect failure prepare for failure. That's great ship it so let's do it so Glenn talk Glenn talk to you about the concept of outgoing middleware And this is our outgoing middleware pipeline that should look pretty familiar based on what you saw before The only thing here that might be a little bit new is add message handler because we're using service discovery based on Steel toe and I discovery client This is using the same discovery stuff from the steel toe project just inside that pipeline that we talked about and then It's got a type client here that has an interface So if you have a type client here that has an interface for the repository pattern, you want to use it with your unit test This is the way you do that. That's what this is. So I'm gonna add another handler here And I'm gonna call this add transient hdb error policy. That's a lot of jargon So what this is is this is an opinionated method to configure an hdb handler that we created with the authors of the Poly library is anybody here heard of poly before or use poly before? So poly is a great library. You should check it out It's a dotnet foundation project. It's open source. It's one assembly. You can use it anywhere and it's great So we're gonna create a handler for this policy and This is going to be called when you have an exception Because you can't connect or 500 or like a 408 timeout. I think yeah, and so we're gonna get When we have a failure, we're gonna wait and retry We're gonna do it three times and We're gonna take the count and we're gonna very simply here Do an exponential back off? Sounds fancy. It is fancy and if you go to their docs You'll find it's right in there read me because it's a really common kind of thing for them, right? Yeah, so the so what what we're gonna do here is we want this We want to call the music store API back in that's running as another service on cloud foundry But we know it's a little bit flaky because we write bad code. So we're going to We're gonna hit it if it fails retry Really quickly then the second retrial be exponentially longer and then the third retrial be exponentially longer again So you don't want to go too much to like overloading it by by retry retry retry retry, right? So basically that's just that is just a three three retry where we wait a little bit longer between each one So not like flood the thing with with with our own retries And so while Glenn is doing that I'm gonna see if I can figure out why this why this thing is failing Yeah, so I'm gonna look at the it's saying crash because I just did a CF push and it's redeploying this app in the background So I'm gonna dig into real good at redeploying things and keeping it up at the same the logs of this back-end service here And see if we can figure out what's going on. So we see we've got this System.exception computer says no Pierce says no, that's kind of weird. I don't I don't know that I've seen that before So there's a commit hash here. I guess I'm gonna go look at I'm gonna go look at what's deployed here. I'm gonna go to the repo for our important sample. Yeah, and let's go Let's go here, and I just want to look at some of the recent commits And see what's going on here. So we have this commit here fixed resiliency issues I merged it, but I wasn't sure I was really paying attention to what was going on. Oh, yeah I remember this commit. This is um, yeah, the guys told us that they were having like crashing problems Yeah, yeah, but they didn't really tell me like how much they wanted it to crash. So I made it configurable Okay, so we've got this resiliency middleware here on our other service. It's gonna crash based on a configurable percentage of the time Great. That's great. That's great. So let's let's check on it met all the requirements, right? Yeah I said the service is crashing too much. I said, okay So we're waiting configurable and then they can decide how much they wanted to crash So while we're waiting for the app to start I want to say that while these packages are part of the dotnet core 2.0 release You do not have to be doing dotnet core to use them. Yeah So if you are on dotnet core, we hope that you'll update to one That's the best way to use them Yeah, to one is when this stuff all comes out But we also have some demos of how to use it in kind of dotnet framework applications and things like that That we hope you'll try out and let us know how it goes if you're doing that So you can see we're back up here and let's just we can go to a couple different pages here And we can see sometimes it's going to be kind of slow right because it's retrying It's gonna wait two seconds and retry and then wait four seconds and retry and so on so you can see that it's So you know that you manage to successfully hide the fact that our service just sometimes crashes and we don't know why yeah So to kind of drive this home a little bit more Let's look at let's look at some of this logs because we showed we showed Glenn showed you the stuff And I think it's pretty great. So I'm gonna go We don't want music store. We want music UI, which is running again, which is great And we're gonna go to logs here, and I'm gonna configure The log levels. So let's take default. Let's leave it. Let's leave it here. So we don't have a lot of spam We'll keep this focus. So I know that the log categories that we write to our System net HTTP HP client and what you see here is for all these named clients that you've defined a configuration for They've all got their own set of like logging knobs and dials, right? So I'm just gonna take because there's a demo I'm gonna take all of these guys All the way up to trace so all the HTTP client stuff is all up to trace And then if I come back here, and I start hitting more of these pages you can see this one's taking a while So that's good. Mm-hmm. Maybe it'll fail. We're only retrying three times. Yeah Who can calculate the percentage chance that it will fail? I don't know what was a configuration set? 30% resiliency somebody go fail. Yeah, so there's possibility that it's gonna fail three times and we should see some logs coming out while we're doing this so we can see that there's a lot of So this is just this is CF logs that you're right. Yeah, and we're missing we're missing the logs that I expected to be there I'm gonna make sure that that seems to you seems that you took I might have to I might have to save this It might be below the fold here. I don't know. I'm gonna have to close this for that to happen. I Don't know that but team does he's over there. Yeah, I'm gonna help us. Mm-hmm. Let's try it. Let's try this again So let's go to another okay, so that works. Let's get one that's taken a while here So there we're that probably was a retry So let's look at the log so you can see all that beautiful logging and tracing that Glenn showed you before and seek in at the command line And if you dial in on this, I've got my font set properly, which is great. Good job You'll be a PM if you dial in on this you can see that we've got a logical handler and a client handler And it's a little bit off the screen, but I think you can see here when you're in the logical handler The URL is HTTP shopping cart, which is a logical name for the service And we're using steel toes service discovery Infrastructure which is based on Eureka and you can see that by the time we get to the client handler Which is the thing that actually goes out and does the network call That the URL has been rewritten to be shopping cart apps dot CF net So it's been replaced with the real URL and this is this is service discovery in action, right? It's not too surprising that it would work this way And then we should be able to if we look here and get past the shopping cart We should be able to see a retry somewhere in here and you will see a You'll see a response from I'm look. I'm kind of scanning through one. Let me know if you see one that is an internal server error from Somebody coming back and then you should be able to see that it it tries again. So we've got okay. Okay Okay Well, maybe we won't find one But what you will what you will see is you will see logical handler calls client handler Client handler comes back and says hey I failed and then client handler goes again and calls again And that's kind of that yeah nested pipeline So you can you can see the timing so it'll say like it came back in 20 milliseconds and it failed So then it read it again, and it took another 20 milliseconds then the overall request time was you know 40 milliseconds, right? Yeah, so we're at we're at 232. What do you want to do now? Do you want to take questions? Yeah Yeah, if that's that's that's most that that's most of the content we had planned where there's lots lots more stuff We could keep talking about but this is our last time here. Yeah, we're on the net team If any of you have questions that you want to ask us Or you want to do like a I can I can give you the mic Questions or whatever feel free if anybody has anything they want to yell out No, no questions no takers. No, no takers Okay, well in that case Thank you very much. Hopefully come and talk to us at the end. This was all This is all we didn't make it super clear here. So there's a couple of things. I'll talk about Ship shipping in ASP. Nicole 2.1 So if you go grab the preview of 2.1, which we've been shipping you'll be able to try out all the things We just showed you The and so you'll be able to get the HB client factory about to use that pattern to do HTTP You're about to get the retries by a polly all these things It should be our seeing an RTMing. It'll be our seeing an RTMing this year like before the end of quarter two With the outgoing HTTP you form a pipeline So what you'll see in the logs when you start to do this is HTTP request outgoing started handler one handler two handler three handler four Right handler three handler two handler one back, right? So you basically stick together all your classes and then it goes through and it goes back So you can imagine diagnostics service discovery error handling, right? Like all the things that you could stitch together into that pipeline to make it work And you're free to go do that as you want and that was the main point of HTTP client factory, but if you are Using HTTP client today raw then there are several other lifetime patterns that the factory works around Basically, if you knew up a HTTP client and you keep it around forever Then you'll never get you don't it doesn't refresh DNS Which means you're slowly like eventually you won't you'll have DNS update anomalies potentially If you don't keep it around forever and you don't and you just keep creating one every time then every time you create one It consumes a socket on the server and then eventually you run out of sockets on the server and something crashes So you basically need to do the middle of those two things You need to sometime keep it around as long as you can but recycle it sometimes to get DNS updates, right? If you're behind IAS and you're in a web application You're making HTTP This is probably not not not a problem because IAS is probably recycling you frequently enough to avoid the DNS problem And you can just keep it alive If using full framework, you can use things like service point manager to avoid it lots and lots of things to avoid those problems But the factory does it already, right? In ASP net core 2.1 It also uses the managed HTTP client handler like full of written in C sharp Which is much faster and also helps avoid those same problems that I just talked about So we think it's pretty cool. You should check it out. Let us know Yeah, yeah, do you want to look at one? Where did I put it? I put it right here to 35. Good. Great. You have less than one minutes I can be really fast to 36 you have so minus time looks like this, right? So if you've if you've done ASP net core before, you know, we have middleware for incoming requests Middleware for outgoing requests is the decorator pattern. It's a decorator pattern no matter what, right? So you're in a delegating handler and what a delegating handler is is like You get called to do an HTTP request You can apply policy and then call next to send on to the next like link in the chain And then that returns and then you can apply policy and then you can return the response or You could implement a circuit breaker and say well I don't want to call the next guy the circuits open or you could like in this case say I don't like that You are I let's get a different one, right? Let's resolve the logical name to the actual name. So cash circuit breaker Bulwark service discovery Authentication most of those things that he's just not outside of any authentication a lot of those things are already implemented in poly and you Can just use them today some of them are going to come with When of the a lot of a lot of things that steel tow does today We will work in we are working getting integrated into this as well like the service discovery for fire Eureka So like hystrix has and I forget how to open this thing up But this this app is using hystrix and is using the hystrix, you know PCF cloud service, which is great So hystrix is providing circuit breakers and timeouts and a few other things here, but hystrix doesn't do retries So like poly's a great usage for that if you're not using hystrix or like say you're not running in the cloud today You can use poly for all these things so the integration that you're seeing here is For htb client and for sort of the middleware kind of pattern and that's something we work with them to build If you want to you can use poly to just like decorate an arbitrary piece of code and say call this handle exceptions retry or call This with a timeout. It's great. You should you should check it out Okay, great thanks