Skip to content

Instantly share code, notes, and snippets.

@SkYNewZ
Created April 23, 2021 10:24
Show Gist options
  • Save SkYNewZ/36b5256e0f0c4094cadfc1d9f1f96547 to your computer and use it in GitHub Desktop.
Save SkYNewZ/36b5256e0f0c4094cadfc1d9f1f96547 to your computer and use it in GitHub Desktop.
Context cancellation example in Go
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