How the Golang Context Package Works

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
when it comes to building resilient production software in go you should be familiar with the context package you don't need to know everything about it though so I'm going to teach you in this video everything that you need to know to get started and then be able to read and build more complex applications because you probably have seen that most complex Frameworks all use the context package in a way or another so in this video I'm going to show you what it is how it works and how you can use these in your software so I'm going to show you some use cases and then finally at the end I'm going to show you a real production API example on where I'm using the context package now I can imagine the context has a box that holds information and travels with each request in your program and it is mostly used to carry contextual information about that request such as request scoped values for example here we have the user ID and the token these come from the authentication middleware here and we can also have stuff like Trace IDs the timeline and deadline for the request so if the request takes some time to to do we can have a timeout and if it doesn't fulfill the timeout we can just cancel the request and other cancellation signals really so here let's imagine that your user is making a request to your application so this is uh a micros service rest API for example so when he makes a request your off mware is going to catch up and is going to put a context on that request so if the user is successful logged in we store the user ID and the token as well and here we have for example a trace ID as we seen and we also have the cancellation timeout so that here on your user service you can have access to the contextual information of that request for example here we can know who is the user ID we can also know that token and the trace ID although the trace is not going to be useful for the user request now of course this example could just be solved by passing the user ID here on the perm but this is just an example now let's imagine that your service the user service needs to get the orders from another service and This Server here is busy so it's taking a long 30 seconds to respond or might not even respond at all who knows right and it would definitely be interesting to add a timeout to this request here so that we can fail fast and don't let the user hang when he's making a request and this is where the context come in because we can add a timeout to this request and if the request is not fulfilled within that time we have a cancellation signal that is going to be fired and we can just cancel it all together and the cool thing is that if there are more requests using that context they can also be canceled as well because if you think about it the context is an immutable tree so if you start here on the middleware where you start the context for example or the HTTP and you're going to pass around to the services this is how usual created in G so with the context out with value and here we are assigning a value to this context and we're getting the context from the background because this is an immutable tree as I've said so if you want to get the context from before and mutate it you need to create a new one this is how it's used and here is a simple example how we can add a timeout for the context so again we create another context another new one where we basically say this is the original one and you're going to add a timeout to this one here so these are the most common use cases for using the context package and I'm going to show you how to implement them all right now but let's get there incrementally and let me show you first an example on how the context works so we are on the same page and so in this example we have here potential expensive operation so he wants to make sure that we add a timeout to this guy here so that if it takes too long we can cancel and don't let the user hang so this function basically just does some work here and this work will take 2 seconds and it will fail because the cancel timeout that we are creating here is just for 1 second so the way that we have this setup is that first thing we do is that we create a context and we get the cancel function from it so we defer it to cancel the first thing we do because this is going to release the resources if for some reason the M fail we never know and here we are creating a context with timeouts where we pass in the context. backgrounds the context. background is usually used by the main function and other top level functions if you don't have any contexts to get um to create your new one you can get from the background and here we are adding a one second timeout then we start a go routine with the expensive operation and here you just wait for the operation to complete so if we run this example and we run the main. go we can see that we are here on the castle and the error is the context that line exceeded so that way the context has been cancelled if you make this a little bit faster for example it's going to be micros 2 micros seconds then the work is done and the timeout has not been triggered now let's take a look at that example from before with the microservices so here I have the user service which is just a simple rest API here where we have the user Handler and the user Handler here is very simple so we let's imagine that we'd go to the database and get the user information then we make a request to that external service on these endpoint so the users such products this is on another service mind you this here is where it might fail so if you remember the diagram here is the other service this is the request we're making then we actually do the request we close the body and here we are reading the payloads we run marshalling and we are writing that's jent to the user now here on the orders service it's pretty much the same but here we are simulating that we' go to the database again with the timer of 4 seconds so let's imagine we're doing an expensive operation and then we write the products to the user so how can we improve this and add a timeout to these get request and it's very easy because goang the standard package from goang already has everything built for us so the first thing that we need is to create a context so let's go here and create a context with a time out of 3 seconds for example then let's just defer and cancel it already then here on the new request what you're going to do is you're going to use the new request with context and here we can pass the context as first argument by the way in go it is convention to pass the context every time it has the first argument so if you have a function that receiv the context it is usually the convention to pass it as the first argument and we usually call it CTX for short so then we can just save our file and here we have our service with a timeout for these requests so let's try this out so here I'm starting the the orders and the user service on different terminals so this one is running on the 8080 and this is on the 81 and here I have my tender clients open so I'm going to send the request and what's happened is that it took way too long so the deadline expired so we have the error context deadline accidents now of course this is not the best solution to do if you are doing a production API but this is the start of it because what you could do is for example an exponential back off so if the request fails you could try again uh with an exponential back off or you could even have a circuit breaker or something like that but this is a topic for another video but yeah you can see how we made this service a little bit more resilient against failur of other dependencies now let's take a look at a more complex example and this is the e-commerce API project for my free course in case you interested I'm going to leave a link below in the description now one of the things that I say that context is very useful for is to carry contextual data on the request and here for example we have the handle checkout uh Handler endpoint here and here we don't have information about the users or anything but this endpoint is guarded with authentication so the user needs to be authenticated to access the checkout and if we take a look at this uh higher order function what it does is that it validates the the token it gets the token and does all of that stuff with JWT so if you're not familiar with this and you want to learn more then again check the course in the description but for this video you need to know that we validate the token and what we do is that we store this token in the context so here we get the request context then we get the context and we're going to create a new version of this context where you use the request context and we're going to add a key so this could be for example imagine this has a map where we have this user key map and this is the value which is the user ID and then we just update the request with the request. with context and we pass in the new context so at the end we're going to have here on the api. go on the on the Handler you're going to have access to this context here and this is just a helper function that I have created which reads the context do value gets the user key and then it Returns the user ID from there now there is a problem here that I want to show you which is that we are creating our own user key here which is a string but if I just save this file go on compiler is going to warn us that we should not use built-in types as strings for keys because this is going to create collisions in the future it might happen so what we should do to solve this problem is we should Define our own types for this so for example here I'm at the top of the file and I'm going to create a new type called context key which is going to be a string and then I'm going to create from this context key our own user key so this is from the type context key and if you use this user key down below here and I'm going to replace like so we don't have that warning anymore because this is a unique type and if you take a look at here on the Handler how we are consuming it we are using the user key value not the hardcoded string so that we avoid collisions in the future so another example that I want to show you is using the trace ID for example if you're uh using logging in your services you should have for example a trace ID so it's the request the unique request that's the for example on my projects I have Google cloud and Google cloud is adding their own Trace ID on the requests and for example here we have a trace mware and if you go inside the trace mware what is doing is that it is getting the trace from the headers so if it doesn't have a trace it's not going to do anything but if it has it's going to add this value to the context so the trace key here is another key that I have created and then it's updating the request with this context so every request that I make to the API with the trace ID it's going to be logged on the logs for example I'm logging here this should not be the best place to do it but we can log anywhere in the request life cycle this is just an example and if you go here of course we are just consuming the trace key like we did for the user ID and just to show you an example here I have my HTTP clients and I'm going to hit send for this request and I have here on the headers a request ID with just potato and if I hit send we get the response back and if I go back to the console we have here the D ID per title so we know what the ID is and of course all of this is authenticated and all of that so behind the scenes we are using the context for the user ID as well so this is pretty much it what I wanted to show you on this video about context now you are well armed with the contacts package and one last thing I want to show you if you want to go further and read more about this which is the this blog post about the it's on the official godev blog I'm going to leave a link in the description below but basically here they scraped in more detail about the context type the done channels as well the deadline and I also have here a very interesting example using the Google web search where they have multiple concurrent requests and they have control over them because they are using context and if you like these kinds of videos consider subscribing to my channel leaving a thumbs up and join the Discord Community below as well if he wants to level up and I see you on the next one
Info
Channel: Tiago
Views: 4,171
Rating: undefined out of 5
Keywords: golang context, go context, context in golang
Id: Q0BdETrs1Ok
Channel Id: undefined
Length: 12min 12sec (732 seconds)
Published: Mon Apr 08 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.