scope is a substitute for the Go context package.
It provides a more convenient context API than the standard library, while maintaining 100% compatibility.
The minimum Go version is go1.26.
The scope package can be added to a project with go get.
go get -u cattlecloud.net/go/scope@latestctx := scope.New()ctx, cancel := scope.TTL(5 * time.Second)
// ctx is canceled after 5 seconds
defer cancel()ctx, cancel := scope.Deadline(time.Now().Add(10 * time.Second))
// ctx is canceled at the specified time
defer cancel()ctx, cancel := scope.Cancelable()
// ctx can be canceled manually
defer cancel()ctx, cancel := scope.WithCancel(parentCtx)
defer cancel()ctx, cancel := scope.WithTTL(parentCtx, 3 * time.Second)
// parentCtx with a 3 second timeout
defer cancel()ctx := scope.WithValue(parentCtx, "userID", 123)userID := scope.Value[int](ctx, "userID")ctx1, cancel1 := scope.WithCancel(scope.New())
ctx2, cancel2 := scope.TTL(5 * time.Second)
joined, cancel := scope.Join(ctx1, ctx2)
// joined is canceled when ctx1 or ctx2 is canceled
defer cancel()
defer cancel1()
defer cancel2()ctx1, _ := scope.Deadline(time.Now().Add(10 * time.Second))
ctx2, _ := scope.Deadline(time.Now().Add(20 * time.Second))
joined, _ := scope.Join(ctx1, ctx2)
deadline, ok := joined.Deadline() // deadline is 10 seconds, ok is truejoined, cancel := scope.Join(ctx1, ctx2)
<-joined.Done() // blocks until either ctx1 or ctx2 is donejoined, cancel := scope.Join(ctx1, ctx2)
<-joined.Done()
err := joined.Err() // returns the error from the first canceled contextctx1 := scope.WithValue(scope.New(), "key", "value1")
ctx2 := scope.WithValue(scope.New(), "key", "value2")
joined, _ := scope.Join(ctx1, ctx2)
val := joined.Value("key") // returns value1 (ctx1's value is checked first)The cattlecloud.net/go/scope module is open source under the BSD license.