To better understand Go’s context withTimeout functionality (and as a reference for myself), I’ve created this small self-contained demo. I didn’t find the published documentation’s example to be clear enough. The interesting part, coming from other programming languages and platforms, was that the WithTimeout function only was a signal that something happened. It doesn’t do anything when there’s a time out (like abort a goroutine or anything dramatic like that).
The essential pieces:
- Call WithTimeout passing the Background() context and specify the timeout (I’ve specified 3.2 seconds)
- Be a good citizen and defer the cancellation (to be sure that it’s called) and defer close the channel
- Start the go routine which waits for the Done channel
- When the Done is signaled, display the current time in seconds and what caused the signal
- The main app is waiting for the goroutine to end, so signal that.
- In the main function, the code sleeps and wakes emitting some time stamps to the console
-
Depending on whether cancel is called, the goroutine signal may
be one of two things.
-
If cancel is not called prior to the second sleep
in the code, the ctx.Err() returns
<-ctx.Done(): context deadline exceeded
-
If cancel however is called, the ctx.Err() returns:
<-ctx.Done(): context canceled
-
If cancel is not called prior to the second sleep
in the code, the ctx.Err() returns
- Then, the goroutine uses the channel to signal completion (wait<-true).
You can experiment with this sample here.
With cancel called (the line cancel() not commented out):
first sleep completed, 02.00 Timeout: 02.00 in <-ctx.Done(): context canceled after second sleep done, 04.00
And, with // cancel() commented out:
first sleep completed, 02.00 Timeout: 03.20 in <-ctx.Done(): context deadline exceeded after second sleep done, 04.00
Hopefully this helps someone besides me.