Yes done() can be used as many times as you want.
here is an example:
package main
import (
"context"
"time"
)
func f(ctx context.Context) {
for i:=0;i<10;i++{
select {
case <- ctx.Done():
println("canceled")
default:
println(".")
}
time.Sleep(1*time.Second)
}
println("f exit")
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
go f(ctx)
time.Sleep(3*time.Second)
println("call ctx cancel()")
cancel()
time.Sleep(10*time.Second)
println("exit")
}
results:
go run cancel.go
.
.
.
call ctx cancel()
canceled
canceled
canceled
canceled
canceled
canceled
canceled
f exit
exit
See “canceled” got returned constantly after context was canceled.