Professional Documents
Culture Documents
Go Context
Go Context
Go Context
com/chap-37-context
• Linked list
• Cancellation
• Timeout
• Deadline
3 Introduction
This chapter is dedicated to the context package. In the first part of this chapter, we will discover what is a “context” and what its purposes
are. In the second part, we will see how we can use the context package in real-life programs.
The paper and the digital edition of this book are available here. ×
I also filmed a video course to build a real world project with Go.
Things, actions, words have a context, have links with other things. And if we take something out of its context, we reduce it to something
that we can misunderstand. Context is an aggregation of information that improves decisions. What is part of context? Here is a partial list :
1 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
• Location
• Date
• History
• People
To better understand why context is important to us, let’s take some examples :
Alice
Did you see the match last week?
Bob
Yes!
Alice
After this, I’m sure they will win the next one!
Bob
Sure, I will bet one thousand on that
They speak about a “match”. A team has won a match last week and has a lot of chance to win another match next week. We have no idea
about which team and which kind of sport it is.
The context of the conversation can help us to understand it. If the conversation is happening in New York, we can guess that it has to do
with baseball or basketball because those sports are very popular there. If this conversation happens in Paris, the chance that they are
speaking about football is very high.
What we are doing here is that we add context to understand something. Here we spoke about the place. We can also add the time factor in
the context of the conversation. If we know when it happened, we will be able to browse through the week’s sports results to understand
better.
• Do you have better manners when you are in your home country and in another country?
• Do you use the same language level at the office and with your family?
The response is probably “No” to those three questions. That’s because of context. We are acting differently depending on the context.
Context is affecting our behaviors. The environment has an impact on our actions and reactions.
The idea of context-oriented programming is to introduce variations in programs that are influenced by context. Abowd gives an interesting
definition of context in 1999 : “Context is any information that we can use to characterize the situation of an entity. An entity is a person,
place, or object that is considered relevant to the interaction between a user and an application, including the user and applications
themselves.”[@abowd1999towards].
Implicit and explicit information are the building blocks of the context. Programmers should consider context to build applications that can
adapt their behavior at runtime.
What does it mean to be intelligent? The word “intelligence” comes from the Latin root “intellego” which means to discern, to unravel, to
notice, to realize. Something is intelligent if it can discern and understand. Introducing context into applications does not make them
intelligent, but they tend to make them aware of their environment and their users.
2 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
5.2 Usages
The context package has two main usages :
Paris’s city has missioned this company to build a gigantic pool. The mayor of Paris has defended its idea among representants of the
population, and the project has been approved. The company begins to work on the project; the project manager has ordered all the raw
materials needed to build the pool. Four months have passed, but the mayor has changed, and the project has been canceled!
The project manager from FooBar is mad; the company has to cancel 156 orders. He starts to join them by phone one by one. Some of them
have also ordered raw materials from other construction companies. Everybody is suffering from this rapid situation evolution.
Now let’s imagine that the project manager does not cancel subcontractors’ orders. The other companies will produce the desired goods, but
they will not be paid. This is a big waste of resources.
As you can visualize in figure 1 cancellation of the project is propagating to all the workers that were involved indirectly. The city Council
cancels the project; the FooBar company is also canceling the orders to contractors.
In construction and other human activities, we always have a way to cancel work. We can introduce a cancellation policy into our programs
with the context package. When a request is made to a web server, we can cancel all the work chain if the client has dropped the connection!
Cancellation propagation[fig:Cancellation-propagation]
3 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
When a request is made to a web server, the web server function responsible for its treatment will not do the job alone. The request will pass
through a chain of functions and methods, and then the response will be sent. A single request can generate new requests to other
microservices in a microservice architecture! This chain of a function call is the “call stack”. We will see in this section why it can be useful to
transmit data along with the call stack.
We will take another example: the development of a web server for a shopping application. We have a user that interacts with our
application.
• The user will go to the login page with its web browser
• The web browser will send an authentication request to the server that will forward the request to the Authentication Service
• The server will build the “My Account” page (via a template, for instance) and send the user’s response.
• If the user requests the “last orders” page then, the server will need to call the Order Service to retrieve them.
An application sequence
• We can keep into context the type of device that sent the request.
◦ If the device is a cellphone, we can choose to load a lightweight template to improve the user experience.
◦ The order service can also load only the last five orders to reduce the page’s rendering time.
◦ The authentication layer can use it to block suspicious activity (introduction of a blocklist, detection of false, multiple login
attempts)
• Another very common use case is to generate a single request id. The requestId is passed to each layer of the application. With the id,
the team that will cope with maintenance will have the ability to trace in logs the request.
• You develop a server, and your client has a specified timeout of 1 second.
• You can set a context with a timeout of 1 second; after this duration, you know that the client will drop the connection.
4 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
6 Linked list
The context package is built with a standard data structure: the linked list. To fully understand how context works, we first need to understand
linked lists.
A linked list is a collection of data elements. The type of data stored in the list is not restricted; it can be integers, strings, structs, floats ...etc.
Each element of the list is a node. Each node contains two things :
• The address in memory of the next element in the list. In other words, this is a pointer to the next value.
The list is “linked”, nodes in the list have a child (the next element in the list) and a parent (the last element in the list). Note that this remark
is not true; the first node in the list has no parent. It’s the root, the origin, the head of the list. There is another notable exception the final
node does not have any child.
Linked List[fig:Linked-List]
5 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
ctx := context.Background()
The call to the Background() function will return a pointer to an empty context. Internally the call to Background() will create a new
context.emptyCtx .
The underlying type of emptyCtx is int . This type implements the four methods that are required by the Context interface:
Note that the emptyCtx type also implements the interface fmt.Stringer . This allows us to do a fmt.Println(ctx) :
fmt.Println(reflect.TypeOf(ctx))
// *context.emptyCtx
fmt.Println(ctx)
// context.Background
The paper and the digital edition of this book are available here. ×
I also filmed a video course to build a real world project with Go.
6 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
In the previous listing, you note two Go idioms that are widely used inside go projects :
9 Deriving context
We have created our root context in the previous section. This context is empty; it does nothing. What we can do is derive another child
context from our empty context :
Deriving Contexts[fig:Deriving-Contexts]
• WithCancel
• WithTimeout
• WithDeadline
• WithValue
10 WithCancel
The function WithCancel takes only one argument named parent . This argument represents the context that we want to derive. We will
create a new context, and the parent context will keep a reference to this new child context.
This function returns the next child context and a CancelFunc. CancelFunc is a custom type of the context package :
CancelFunc is a named type, its underlying type is func() . This function “tells an operation to abandon its work” (Golang sources). Calling
WithCancel will give us a way to cancel an operation. Here is how to create a derived context :
cancel()
7 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
11 WithTimeout / WithDeadline
• A timeout is the maximum amount of time attributed to a process to finish normally. For any process that takes a variable amount of
time to execute, we can add a timeout, i.e., a fixed amount of time allowed to wait. Without timeouts, our application can wait
indefinitely for a process to finish.
• A deadline is a specified point in time. When you set a deadline, you specify that a process will not exceed it.
The paper and the digital edition of this book are available here. ×
I also filmed a video course to build a real world project with Go.
12 Example usage
12.1 Without context
Let’s take an example: we will design an application that has to make an HTTP request to a web server to get data and then display it to its
user. We will first consider the application without context then we will add context to it.
12.1.1 Client
package main
import (
"log"
"net/http"
)
func main() {
req, err := http.NewRequest("GET", "http://127.0.0.1:8989", nil)
if err != nil {
panic(err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
log.Println("resp received", resp)
}
We have here a simple http client. We create a GET request that will call "http://127.0.0.1:8989" . If we cannot create the request, we make
our program panic. Then we use the default HTTP client ( http.DefaultClient ) to send the request to the server (with the method Do ).
12.1.2 Server
We have set up our client. We now have to set up our fake server.
8 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Println("request received")
time.Sleep(time.Second * 3)
fmt.Fprintf(w, "Response") // send data to client side
log.Println("response sent")
})
err := http.ListenAndServe("127.0.0.1:8989", nil) // set listen port
if err != nil {
panic(err)
}
}
The code is simple. We first begin by setting our http handler with the function. http.HandleFunc . This function takes two parameters, the
path and the function that will respond to requests.
We wait 3 seconds with the instruction time.Sleep(time.Second * 3) then we write the response. This sleep is here to fake the time needed
for the server to answer. In this case, the response is simply "Response" .
Then we launch our server that will listen to 127.0.0.1:8989 (localhost, port 8989).
$ go run server.go
2019/04/22 12:17:11 request received
2019/04/22 12:17:14 response sent
$ go run client.go
2019/04/22 12:17:14 resp received &{200 OK 200 HTTP/1.1 1 1 map[Content-Length:[8] Content-Type:[text/plain; charset=utf-8]
Date:[Mon, 22 Apr 2019 10:17:14 GMT]] 0xc000132180 8 [] false false map[] 0xc00011c000 <nil>}
As you can see, our client has to deal with 3 seconds latency. Let’s increase this in the server’s cod; let’s say that we now sleep for 1 minute.
Our client will wait for 1 minute; it will block our application for 1 minute.
We can note here that our client application is condemned to wait for the server even if it takes an infinite amount of time. This is not a very
good design. The user will not be happy to wait indefinitely for the application to answer. In my opinion, it is better to say to the user that
something wrong happened than to let him wait indefinitely.
rootCtx := context.Background()
Then we will derive this context into a new one called ctx :
• I suggest you create a config variable in a real-world application to hold the timeout duration. By doing so, you avoid the need to
recompile your program to change the timeout.
9 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
2. a cancel function
The cancel function can be called to warn a sub-process that it should abandon what it is doing. Calling cancel will free resources that are
associated with the context. To be sure that the cancel function will be called at the end of our program, we will use a defer statement :
defer cancel()
The next step consists of creating the request and attach to it our brand new context :
The other lines are the same as the version without context.
// context/client-side/main.go
package main
import (
"context"
"fmt"
"net/http"
"time"
)
func main() {
rootCtx := context.Background()
req, err := http.NewRequest("GET", "http://127.0.0.1:8989", nil)
if err != nil {
panic(err)
}
// create context
ctx, cancel := context.WithTimeout(rootCtx, 50*time.Millisecond)
defer cancel()
// attach context to our request
req = req.WithContext(ctx)
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
fmt.Println("resp received", resp)
}
Now let’s test our new client. Here are the logs of the server :
We see that we have received a request and sent a response 3 seconds later. Here are the logs of our client :
• Our request has been canceled because our server took 3 seconds to do its job. Even if the client has canceled the request, the server
continued to do the job. We have to find a way to share that context between the client and the server.
10 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
An HTTP request comprises a set of Headers, a body, and a query string. When we send the request, Go will not transmit any information
about the request context.
If you want to visualize the headers of the request, you can add the following lines in the server code :
fmt.Println("headers :")
for name, headers := range r.Header {
for _, h := range headers {
fmt.Printf("%s: %s\n", name, h)
}
}
We iterate through the request’s headers with a loop and print them. Here are the headers that are transmitted with our client :
headers :
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip
We have just two headers. The first one gives more information about the client used. The second informs the server that the client can
accept gzipped data. Nothing about an eventual timeout.
But if we take a look at the http.Request object, we can note that there is a method named Context() . This method will retrieve the
context of the request. If it has not been defined, it will return an empty context :
The documentation says that “the context is canceled when the client’s connection closes”. This means that inside the go server
implementation, when the client connection is closed, the cancel function is called.
It means that inside our server, we have to listen to the channel returned by ctx.Done(). When we receive a message on that channel, we have
to stop what we are currently doing.
For the example, we will introduce a new function doWork . It will represent a compute-intensive task handled by our server. This doWork is
a placeholder for a CPU-intensive operation.
11 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
We will launch the doWork function in a separate goroutine. This function will take as parameter the context and a channel where it will write
its result. Let’s take a look at the code of this function :
// context/server-side/main.go
//...
In the figure 5 you can see the activity diagram for the doWork function.
In this function, we will use a channel to communicate with the caller. We create a for loop, and inside that loop, we will put a select
12 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
• The channel returned by ctx.Done() has been closed. It means that we receive the order to finish our work
◦ In this case, we will interrupt the loop, log a message and return.
• The default case (executed if any previous case are not executed)
◦ If the variable sum is becoming greater strictly than 1.000, we will send the result on the result channel ( resChan )
13 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
// context/server-side/main.go
//...
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Println("[Handler] request received")
// retrieve the context of the request
rCtx := r.Context()
// create the result channel
resChan := make(chan int)
// launch the function doWork in a goroutine
go doWork(rCtx, resChan)
// Wait for
// 1. the client drops the connection.
// 2. the function doWork to finish it works
select {
case <-rCtx.Done():
log.Println("[Handler] context canceled in main handler, client has diconnected")
return
case result := <-resChan:
log.Println("[Handler] Received 1000")
log.Println("[Handler] Send response")
fmt.Fprintf(w, "Response %d", result) // send data to client side
return
}
})
err := http.ListenAndServe("127.0.0.1:8989", nil) // set listen port
if err != nil {
panic(err)
}
}
We have changed the code of the handler to use the request context. The first thing to do here is to retrieve the context of the request :
rCtx := r.Context()
Then we set up a channel of integers ( resChan ) that will allow you to communicate with the doWork function. We will launch the doWork
function in a separate goroutine.
Then we will use a select statement to wait for two possible events :
1. The client closes the connection; consequently, the cancel channel will be closed.
2. The function doWork has finished its job. (We receive an integer from the resChan channel)
In option 1, we log a message, and then we return. When option 2 occurs, we use the result from the resChan channel, and we write it to
the response writer. Our client will receive the result of the doWork function computation.
Let’s run our server and our client. On figure 6 you can see the execution logs of the client and the server program.
You can see that the handler receives a request, then launch the doWork function. Then the handler receives the cancellation signal. This
signal is then propagated to the doWork function.
14 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
13 WithDeadline
13.1 Definition
WithDeadline and WithTimeout are very similar. If we look at the source code of the context package, we can see that the function
WithTimeout is just a wrapper of WithDeadline :
If you look at the previous snippet you can see that the timeout duration is added to the current time. Let’s see the signature of the
WithDeadline function :
1. A parent context
2. A specific time.
13.2 Usage
As we said in the previous section, deadline and timeout are similar notions. A timeout is expressed as a duration, but a deadline is expressed
as a particular point in time (see figure 7)
Timeout vs Deadline[fig:Timeout-vs-Deadline]
WithDeadline can be used where you use WithTimeout. Here is an example of the standard library :
15 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
• For each network (UDP or TCP), it derives the context passed as parameter.
• The input context is derived by calling context.WithDeadline . The deadline time is created by adding the timeout duration to the
current time : time.Now().Add(timeout)
• Note that immediately after creating the derived context, there is a deferred call to the cancel function returned by
context.WithDeadline . It means that when the function exchange will return the cancel function will be called.
• For instance, if the dial function returns an error for some reason, the exchange function will return, the cancel function will be called,
and the cancellation signal will be propagated to the child context.
14 Cancellation propagation
This section will dive deeper into the mechanism of cancellation propagation. Let’s take an example :
func main(){
ctx1 := context.Background()
ctx2, c := context.WithCancel(ctx1)
defer c()
}
In this small program, we begin by defining a root context : ctx1 . Then we derive this context with a call to context.WithCancel .
Go will create a new structure. The function that will be called is the following one :
// src/context/context.go
A cancelCtx struct is created, and our root context is embedded inside. Here the type struct cancelCtx :
// src/context/context.go
16 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
• the Context (the parent) which is an embedded filed (it has no explicit field name)
• A mutex (named mu )
• A field named children that is a map. Keys are of type canceller and value of type struct{}
Canceller is an interface :
A type that implements the interface canceller must implement to functions : a cancel function and a Done function.
What happens when we execute the cancel function ? What happens to ctx2 ?
• The mutex ( mu ) will be locked. Hence no other goroutine will be able to modify this context.
• All children of ctx2 will also be canceled (in this case, we have no children...)
17 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
func main() {
ctx1 := context.Background()
ctx2, c2 := context.WithCancel(ctx1)
ctx3, c3 := context.WithCancel(ctx2)
//...
}
Here we create ctx3 , a new object of type cancelCtx . The children context ctx3 will be added to the parent ( ctx2 ). The parent context
ctx2 will keep memory of its children. For the moment, it only has one child ctx3 (see 9).
Now let’s see what is going on when we call the cancel function c2 .
• The mutex ( mu ) will be locked. Hence no other goroutine will be able to modify this context.
• All children of ctx2 will also be canceled (in this case, we have no children...)
• Here ctx1 (the parent of ctx2 ) is an emptyCtx , hence ctx2 will not be removed from ctx1 .
18 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
func main() {
ctx1 := context.Background()
ctx2, c2 := context.WithCancel(ctx1)
ctx3, c3 := context.WithCancel(ctx2)
ctx4, c4 := context.WithCancel(ctx3)
}
3 derived contexts[fig:3-derived-contexts]
• As you can see in figure 10 we have one root context and three descendants.
19 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
• When we call c2 it will cancel ctx2 but also its children ( ctx3 ).
• When ctx3 will be canceled it will also cancel all its children, and ctx4 will be canceled.
Cancellation propagation[fig:Cancellation-propagation-1]
The key information of this section is “when you cancel a context, the cancel operation will be propagated from parent to children”.
20 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
You can encounter those lines in the standard library but also in many libraries. As soon as we derive an existing context, the cancel function
is called in a defer statement.
As we have seen before, the cancellation instruction propagates from parents to children; why do we need to call cancel explicitly? When
building a library, you are not sure that somebody will effectively execute the cancel function in a parent context. By adding the call to cancel
in a deferred statement, you ensure that cancel will be called :
• when the function returns (or reach the end of its body)
First, we define two functions: doSth and doSth2 . Those two functions are dummy. They are taking a context as first parameter. Then they
are waiting indefinitely for the channel returned by ctx.Done() close :
// context/goroutine-leak/main.go
// ...
We will now use those two functions in a third function called launch :
// context/goroutine-leak/main.go
// ...
func launch() {
ctx := context.Background()
ctx, _ = context.WithCancel(ctx)
log.Println("launch first goroutine")
go doSth(ctx)
log.Println("launch second goroutine")
go doSth2(ctx)
}
In this function, we are first creating a root context (returned by context.Background ). Then we derive this root context. We call the method
WithCancel() to get a context that can be canceled.
Then we launch our two goroutines. Let’s now take a look at our main function :
// context/goroutine-leak/main.go
// ...
func main() {
log.Println("begin program")
go launch()
time.Sleep(time.Millisecond)
log.Printf("Gouroutine count: %d\n", runtime.NumGoroutine())
for {
}
}
21 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
We start the function launch in a goroutine. Then we make a small pause (1 millisecond), and we count the number of goroutines. There is a
very convenient function that is defined in the runtime package :
runtime.NumGoroutine()
The number of goroutines here should be 3: 1 main goroutine + 1 goroutine that execute doSth + 1 goroutine that execute doSth2 . If we
do not call cancel, the two last goroutines will be running indefinitely. Note that we have created another goroutine in the program: the one
that starts launch . This goroutine will not be counted because it will return almost instantaneously.
When we cancel the context, our two goroutines are returning. Hence the number of goroutines will be reduced to 1 (the main). But here, we
do not call the cancel function at all.
In the main function, we have no way to cancel our context (because it was defined inside the launch function). We have 2 leaked goroutine!
To fix that, we can just modify the function launch and add a deferred statement :
// context/goroutine-leak-fixed/main.go
// ...
func launch() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
log.Println("launch first goroutine")
go doSth(ctx)
log.Println("launch second goroutine")
go doSth2(ctx)
}
Now let’s take a look at the logs that are obtained by running this modified version of our program :
The paper and the digital edition of this book are available here. ×
I also filmed a video course to build a real world project with Go.
16 WithValue
A Context can carry data with it. This feature is intended to be used with request-scoped data like :
16.1 Example
22 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
// context/with-value/main.go
package main
import (
"context"
"fmt"
"log"
"net/http"
uuid "github.com/satori/go.uuid"
)
func main() {
http.HandleFunc("/status", status)
err := http.ListenAndServe(":8091", nil)
if err != nil {
log.Fatal(err)
}
}
const (
requestID key = iota
jwt
)
23 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
• We derive the request context ( req.Context() ) with ctx := context.WithValue(req.Context(), requestID, uuid.NewV4().String())
The context values are then accessible into isMonitoringUp and isMonitoringUp :
reqID, ok := ctx.Value(requestID).(string)
if !ok {
return false, fmt.Errorf("requestID in context does not have the expected type")
}
The arguments key and val are of type interface{} . In other words, they can have any type. Only one restriction should be respected,
the type of key should be comparable.
• You might want to restrict the access to context values outside the package where values were added.
const (
requestID key = iota
jwt
)
In the previous example, we created a type key with underlying type int (comparable). Then we defined two unexported global constants.
Those constants are then used to add a value and to retrieve a value from the context :
// add a value
ctx := context.WithValue(req.Context(), requestID, uuid.NewV4().String())
// get a value
reqID, ok := ctx.Value(requestID).(string)
16.2.0.1 Missing value & type expected different than the actual type
• When the key-value pair is not found in the context, ctx.Value will return nil .
• That’s why we are making a type assertion: to protect us against missing values or values that have not the required type.
16.3 Questions
1. What is the difference between a deadline and a timeout ?
2. Fill in the blanks. Each node of a linked list contains a ____ value and an ____.
5. When the key-value pair is not found in the context, what is returned by ctx.Value(key) ?
16.4 Answers
1. What is the difference between a deadline and a timeout?
24 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
2. Fill in the blanks. Each node of a linked list contains a ____ value and an ____.
1. Each node of a linked list contains a data value and an the address in memory of the next element
1. ctx := context.Background()
4. With which method(s) can you derive a context?
1. WithCancel
2. WithTimeout
3. WithDeadline
4. WithValue
5. When the key-value pair is not found in the context, what is returned by ctx.Value(key)
1. nil
17 Key Takeaways
• Context is a package from the standard library
◦ Cancellation propagation (ex: cancel all the work chain if the API consumer has dropped the connection)
• Timeout = a duration
• A linked list is a collection of data. Each node of a linked list contains a data value and an address in memory of the next element.
ctx := context.Background()
• When you cancel a context, the cancel operation will be propagated from parent to children contexts.
• To add a value, derive the context like this : ctx := context.WithValue(req.Context(), requestID, uuid.NewV4().String())
• When no values are retrieved with the given key ctx.Value will return nil
25 of 26 02/01/2023, 02:22
Context - Practical Go Lessons https://www.practical-go-lessons.com/chap-37-context
1. https://github.com/golang/go/wiki/SubRepositories↩
Bibliography
• [abowd1999towards] Abowd, Gregory D, Anind K Dey, Peter J Brown, Nigel Davies, Mark Smith, and Pete Steggles. 1999. “Towards a Better
Understanding of Context and Context-Awareness.” In International Symposium on Handheld and Ubiquitous Computing, 304–7. Springer.
Previous Next
Table of contents
Did you spot an error ? Want to give me feedback ? Here is the feedback page! ×
Newsletter:
Like what you read ? Subscribe to the newsletter.
@ my@email.com
Practical Go Lessons
By Maximilien Andile
Copyright (c) 2023
Follow me Contents
Posts
Book
Support the author Video Tutorial
About
The author
Legal Notice
Feedback
Buy paper or digital copy
Terms and Conditions
26 of 26 02/01/2023, 02:22