Created
April 23, 2021 10:24
-
-
Save SkYNewZ/36b5256e0f0c4094cadfc1d9f1f96547 to your computer and use it in GitHub Desktop.
Context cancellation example in Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"fmt" | |
"math/rand" | |
"os" | |
"time" | |
) | |
var ( | |
contextTimeOut time.Duration | |
jobDuration time.Duration | |
) | |
func init() { | |
rand.Seed(time.Now().UnixNano()) | |
contextTimeOut = time.Second * 10 | |
jobDuration = time.Second * time.Duration(rand.Intn(20)) | |
} | |
func main() { | |
fmt.Printf("timeout of %.f seconds\n", contextTimeOut.Seconds()) | |
ctx, cancel := context.WithTimeout(context.Background(), contextTimeOut) | |
defer cancel() | |
s := 0 | |
err := foo(ctx) | |
if err != nil { | |
s = 1 | |
} | |
fmt.Println(err) | |
os.Exit(s) | |
} | |
// foo describes a long cancellable job | |
func foo(ctx context.Context) error { | |
// out simulate a this job output | |
out := make(chan struct{}) | |
defer close(out) | |
// this is the job | |
go func() { | |
defer fmt.Println("job completed") | |
// Wait a random time between now and 20 seconds | |
fmt.Printf("job duration will be %.f seconds\n", jobDuration.Seconds()) | |
time.Sleep(jobDuration) | |
// Publish to simulate end of the job | |
out <- struct{}{} | |
}() | |
// If ctx cancelled of timed out, return the error | |
// Else, no error to return | |
for { | |
select { | |
case <-ctx.Done(): | |
return ctx.Err() | |
case <-out: | |
return nil | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment