In lot of places the following pattern is used for cancelation:
for {
select {
case <-ctx.Done():
return
case x := <- ch:
foo(x)
}
}
The problem is that there select does not guarantee the order when both channels signal. Therefore if ch will have multiple values buffered then the code block would eventually return instead of returning as soon as possible. The easy way to fix it is to use the following pattern:
for {
if err := ctx.Err(); err != nil {
return
}
select {
case <-ctx.Done():
return
case x := <- ch:
foo(x)
}
}
or
for {
select {
case <-ctx.Done():
return
default:
}
select {
case <-ctx.Done():
return
case x := <- ch:
foo(x)
}
}
In lot of places the following pattern is used for cancelation:
The problem is that there
select
does not guarantee the order when both channels signal. Therefore ifch
will have multiple values buffered then the code block would eventually return instead of returning as soon as possible. The easy way to fix it is to use the following pattern:or