

Go Context
A way to think about context package in go is that it allows you to pass in a “context” to your program. Context like a timeout or deadline or a channel to indicate stop working and return. For instance, if you are doing a web request or running a system command, it is usually a good idea to have a timeout for production-grade systems. Because, if an API you depend on is running slow, you would not want to back up requests on your system, because, it may end up increasing the load and degrading the performance of all the requests you serve. Resulting in a cascading effect. This is where a timeout or deadline context can come in handy.Go Context example
package main
import (
"context"
"fmt"
)
func main() {
ctx := context.Background()
ctx = addValue(ctx)
readValue(ctx)
}
func addValue(ctx context.Context) context.Context {
return context.WithValue(ctx, "key", "test-value")
}
func readValue(ctx context.Context) {
val := ctx.Value("key")
fmt.Println(val)
}
Output
test-value
Go Context with timeout
WithTimeout and WithDeadline are basically the same in terms of usage and function, they both indicate that the context will be automatically canceled after a certain time, the only difference can be seen from the definition of the function, the second parameter passed to WithDeadline is of type time.Duration type, which is a relative time, meaning how long after the timeout is cancelled.package main
import (
"runtime"
"fmt"
"time"
"context"
)
func monitor2(ctx context.Context, index int) {
for {
select {
case v := <- ctx.Done():
fmt.Printf("monitor2: %v, the received channel value is: %v, ending\n", index, v)
return
default:
fmt.Printf("monitor2: %v in progress...\n", index)
time.Sleep(2 * time.Second)
}
}
}
func monitor1(ctx context.Context, index int) {
for {
go monitor2(ctx, index)
select {
case v := <- ctx.Done():
// this branch is only reached when the ch channel is closed, or when data is sent(either true or false)
fmt.Printf("monitor1: %v, the received channel value is: %v, ending\n", index, v)
return
default:
fmt.Printf("monitor1: %v in progress...\n", index)
time.Sleep(2 * time.Second)
}
}
}
func main() {
var ctx01 context.Context = nil
var ctx02 context.Context = nil
var cancel context.CancelFunc = nil
ctx01, cancel = context.WithCancel(context.Background())
ctx02, cancel = context.WithDeadline(ctx01, time.Now().Add(1 * time.Second)) // If it's WithTimeout, just change this line to "ctx02, cancel = context.WithTimeout(ctx01, 1 * time.Second)"
defer cancel()
for i := 1; i <= 5; i = i + 1 {
go monitor1(ctx02, i)
}
time.Sleep(5 * time.Second)
if ctx02.Err() != nil {
fmt.Println("the cause of cancel is: ", ctx02.Err())
}
println(runtime.NumGoroutine())
println("main program exit!!!!")
}
Output
1
main program exit!!!!
main program exit!!!!
Conclusion
In this page (written and validated by A. Gawali) you learned about Go Context . What's Next? If you are interested in completing Go tutorial, your next topic will be learning about: Go Enum.
Incorrect info or code snippet? We take very seriously the accuracy of the information provided on our website. We also make sure to test all snippets and examples provided for each section. If you find any incorrect information, please send us an email about the issue: mockstacks@gmail.com.
Share On: |
Mockstacks was launched to help beginners learn programming languages; the site is optimized with no Ads as, Ads might slow down the performance. We also don't track any personal information; we also don't collect any kind of data unless the user provided us a corrected information. Almost all examples have been tested. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. By using Mockstacks.com, you agree to have read and accepted our terms of use, cookies and privacy policy.