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.