Understanding Contexts in Go in 5(-ish?) Minutes

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Thank you for the recommendation! I just started learning Go and this channel looks helpful.

👍︎︎ 1 👤︎︎ u/Responsible-Read7164 📅︎︎ Dec 05 2021 🗫︎ replies
Captions
hi everyone it's heather from tutorialedge.net and in the next five minutes i'm going to be teaching you everything you need to know about context or your money back so first of all what is a context well i like to think of them as buckets that have a lot of extra functionality that allow you to do things like control cancellation through timeout deadlines and also the ability to store key value pairs so what tends to happen within your production applications is let's consider this your application now whenever somebody makes a request to enter your application via a http request or grpc request this request then hits the transport layer of our application so this is the part of our code that handles that incoming request and then sends it on to the business layer now this transport layer is typically the one that creates this context in the first place and then it will propagate it with things like a request id or a trace id which can be used thing for things like monitoring and observability now this context object that is created is then typically passed to the business layer or the application layer which will handle the business logic of your code so this is where your application will actually do things like you know processing invoices creating comments or whatever you want within your application so typically this is then propagated to that level or that layer and then if your business layer then needs to talk to a data layer such as you know postgres mysql this contact is then again passed down to this data layer into the code that handles the insertion into the database wherever so why do we do this well passing this with things like the request id and the trace id really helps us when it comes to monitoring what requests have failed so imagine we have a uuid that's generated and one two three four one thirty four so on so on this is created at the point at which we get this request in and then it's sent throughout the different layers of our application now if our business layer was to fail for any reason you know be it processing error or whatever we could then log out in this business layer that the request id has failed for one two three four one two three four now not only are contacts good for propagating information between our layers of our application they're also good for controlling things like timeouts and deadlines now let's imagine we had a time sensitive application that had to return a response to our customers within two seconds no matter what so it could be a successful response or an error response it has to return a response within that time frame now we can effectively use context here to control how long certain parts of our code takes to execute and ensure that if it does exceed a certain timeline time frame or deadline then we can return an error associated with that now this is brilliant if you want to limit or reduce the amount of compute that is wasted by your application so for example if we have a server that takes in 100 requests a second if 50 of them are going to time out then we don't want to necessarily keep processing those requests after they've turned out because it doesn't help us at all like we can immediately return a response to the customers at that point saying we've timed out and the remaining 50 requests per second are then giving more or have more of a share of compute to then process the incoming requests now not only that but also helps us to guard against some potential failure cases now imagine you had hundreds of requests coming in per second and you didn't have a deadline or a timeout associated with your server now f for any reason one or two of these requests every second does not return a response or somehow hangs for any reason then suddenly you could find yourself with a growing number of connections being used by these long-running quests and eventually your server becomes unable to handle any more incoming requests now it's imperative that when you are configuring your production applications that you do set up sensible timeouts so that you're not woken up at 3 o'clock in the morning on a saturday because of this issue okay so we've covered what contexts are and how they can be useful let's start off by seeing how we can use them within our goal applications now i'm going to import a few things i'm going to import context and i'm going to import fmt fmt now i'm going to do two things i'm going to do f and t print line go context tutorial and we're going to create a new context now in order to create a new context we can do context dot background or we can do context dot to do which essentially return the same things however if you know what you're going to be using your context for i tend to use dot background like so next we can do something like context as equal to let's say enrich context and we'll create a new function that'll take in the context and let's do funk enrich context context context.context and this is going to return that context.context cool so just to quickly highlight whenever you're working with contexts it's best practice to have the context as the first argument within your function or method and then all of the subsequent arguments after that okay so let's enrich this context and create a new context so what i'm going to do is context.with value this is going to take in our our original context and then it's going to take in a key value pair so i'm going to say request id for example and i'm going to do 1 2 3 4 5 just for demonstration next let's do something cool so let's create another function do something cool again this is going to take context.context as the first argument and let's say we want to get the request id so our id as equal to context dot value and then we can pass in the key that we want to retrieve from this context and then we can print this out our id like so now let's call this do something cool function down here and pass in the context object cool so let's just cover what we've done here quickly we've effectively taken in the original context and we've made a copy of this context using the with value method and we've assigned this to our original context object here on line 20. now we're then able to use this new context that will feature the request id key value pair within subsequent function calls now let's go into the terminal and see if we can run this go run main.go and as you can see go context tutorial is printed out and then when we hit the do something cool function it then retrieves the request id from our context and we can print that out now at this point it should be noted that whilst you certainly can use context to pass information between the layers of your application you absolutely need to use this only for things that truly need to be propagated through you shouldn't use context as a bucket for all your information it's a supplementary object that you can store things like request ids for example or trace ids cool so what about deadlines and using things like timeouts well within the context object if we scroll up here we can see that the context interface features a done channel now this is the channel that we're going to use in order to control certain aspects of our code and ensure the timeout in a manner that suits us so let's navigate back to our do something cool function and i'm going to do something that simulates a long running process so i'm going to create a for loop and then i'm going to do a select statement and the first case is going to be waiting for a read from context.done and what i'm going to say here is fmt print line and timed out and then i'm going to return from this function to ensure that it cancels this function and below this i'm going to create a default case and i'm going to say fmt print line doing something cool and then just so that my terminal isn't completely spammed with print statements i'm going to do a time.sleep 500 times time dot and we'll say millisecond and remember to import the time package at the top here and let's move this up here and the next thing i'm going to do is i'm going to come down into the main function below and we have the context.background object here but what i'm going to do is i'm going to do context or cancel is equal to context and i'm going to do with timeout and i'm going to move the creation of the context into the first argument here so context.background and then i'm going to specify a timeout which is going to be time and we're going to do 2 times time dot second in this example cool next i'm going to call defer cancel save that and the next thing i'm going to do is i'm going to do go do something cool so i'm going to effectively turn this into a go routine and then below this i'm going to do the following so select and i'm going to wait for the context.done channel to be written to so contacts are done fmt print line and let's do something like auto i've exceeded the deadline cool and then just for demonstration purposes i'm going to do time.sleep and let's do two times time.second and save that so let's cover exactly what this is going to do so on line 30 here we've created a new context and we've wrapped this with a deadline of two times time.second or two seconds now whenever this time frame is exceeded the done channel within the context object we've created is going to be closed and that'll effectively allow us to cancel the execution of our do something cool function up here and it will return and we're also going to see the same down here we're going to see case context.done is matched and it's going to print this out so let's clear this and let's go into the terminal and do go run main.go and let's see this in action cool so what we've effectively seen here is for every half a second it's then defaulted to doing something cool and we've seen that printed out four times and then when the two second time frame has exceeded we've then seen that that's being printed out as this case has been matched and we've also seen that this case matched as well so that's then printed timed out which is then called return and then the application that we're working with has then finished or terminated now say for example we wanted to cancel our context sooner than the timeout well what we could do is we could use this cancel function that we've got here now in this example i've deferred the cancel function to the end of the main function as i want i've wanted all of this code to execute without it being cancelled prematurely however just to show an example if i remove the first statement it called cancel immediately what we'd see is that the context would be immediately canceled for us and as you can see yep oh no i've exceeded the deadline which is down here one two three four and it's timed out so it's never actually able to process anything the context was cancelled before our application could do anything cool so the final thing i want to cover is the errors i know we've gone over the five minutes i said at the start but there's a lot to cover in context and you're not paying for this so i don't have to give you any money back cool so let's have a look at this context object and as you can see within the context interface on line 62 here there is an error function here now the error function if we call it and the done channel that we've talked about is not yet closed then we don't receive any error if this done channel is closed and we call error then it's going to return an error that effectively tells us that the context has been cancelled now let's see this in action so i'm going to go down here and i'm going to say fmt dot print line context dot error i'm going to save this and we're going to rerun this application so go run main.go so it's doing something cool and yes context deadline exceeded which has been printed out here so the done channel has been closed on our context and this case has been matched and then when we call this error function here then it will print out that error for us now just to tell you or just to show you that i'm not lying let's move this up here and we should see a nil statement getting printed out i'm going to clear this and run this again and yes when we call this before the done channel has been closed and now value is returned cool so that is all we're going to cover in this video now in this video we've covered the basics of contacts what they can be used for and we then looked at some examples of using context to do things like propagate values between our code using the width value function and also the dot value method here and then we've also looked at how we can do things like implementing timeouts within our code now if you liked this video and found it useful then please let me know in the comment section down below and leave a like and as always please subscribe to my channel for more cool programming content cheers
Info
Channel: TutorialEdge
Views: 1,887
Rating: undefined out of 5
Keywords:
Id: h2RdcrMLQAo
Channel Id: undefined
Length: 15min 14sec (914 seconds)
Published: Sun Dec 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.