Recognizing Package Context With Timeout In Golang
Package introduction context.WithTimeout
In the previous article we learned context.WithCancel where we manually send the cancel signal from context. But we can also add cancel signal to context automatically by using timeout timings. By using timeout, we no longer need to manually call cancel execution, but with timeout cancel will be automatically executed if the timeout time has passed.
Why should we use context?
Using context with timeout is perfect when we query a database or http api, but want to specify a maximum timeout. When creating a context with an automatic cancel signal using timeout, we can use the context.WithTimeout(parent,duration) function.
The benefit of using context.WithTimeout is that when we will execute a function, when the function executes for a certain period of time that passes the timeout limit, the process will be automatically canceled. This happens so that the process that takes a long time does not become a * blocker* for the next processes.
Implementation and sample
We will now try to implement context.WithTimeout. We will use this method to restrict access to a function based on a certain time limit. Further, we will try to directly study the program code below.
1func main() {
2 fmt.Println("Total Goroutines : ", runtime.NumGoroutine())
3
4 parent := context.Background()
5 ctx, cancel := context.WithTimeout(parent, 5*time.Second)
6 defer cancel()
7
8 destination := CreateCounterWithTimeout(ctx)
9 fmt.Println("Total Goroutine : ", runtime.NumGoroutine())
10
11 for n := range destination {
12 fmt.Println("Counter : ", n)
13 }
14
15 fmt.Println("Total Goroutines : ", runtime.NumGoroutine())
16}
17
18func CreateCounterWithTimeout(ctx context.Context) chan int {
19 destination := make(chan int)
20 go func() {
21 defer close(destination)
22 counter := 1
23 for {
24 select {
25 case < ctx.Done():
26 return
27 default:
28 destination <- counter
29 counter++
30 time.Sleep(1 * time.Second) // simulate slow process
31 }
32 }
33 }()
34 return destination
35}The above program actually modifies the previous function that we learned in context.WithCancel. The difference from the previous article is the use of context of course and the use of defer cancel() which in the previous article we will call and execute the cancel() function manually.
Here is the result of the program when it is run below.
1✗ go run main.go
2Total Goroutines: 1
3Total Goroutines : 2
4Counters: 1
5Counter: 2
6Counter: 3
7Counter: 4
8Counter: 5
9Total Goroutines: 1Conclusion
context.WithTimeout is a very useful method when we have a process function that is not certain that the process will be completed within a certain time limit. To avoid waiting too long for the result of an api or response from the process, we need to limit the process so that it does not become a * blocker* with a timeout time limit unit so that the process will be completed or fail our program will still have a process that is not too long according to the tolerance that we have determined the time process.