Reading Concurrency in Go.
Trying to understand the or-done-channel pattern.
Having trouble wrapping my head around the execution flow.
I have mentioned number against the line where my doubt is from.
Why no
return
statement in inner<-done
like we have in outerselect
? Because of noreturn
statement, the next iteration will run and what if in that iteration we have both<- done
and<-c
available. We knowselect-case
will choose any of the case arbitrarily if multiple cases are available. Does this mean there is a possibility that<-c
will run even if<-done
was available?Since
select-case
arbitrarily chooses a case when multiple case are available, is it correct to assume that the<- done
will be chosen eventually but it is not necessary that it is chosen immediately as soon as it is closed. Of Course, this doubt is when both case i.e.<-done
and<-c
were available.There is a possibility that
<- v
is not written ontovalStream
whendone
is closed and it is lost forever, correct?
orDone := func(done, c <-chan interface{}) <-chan interface{} {
valStream := make(chan interface{})
go func() {
defer close(valStream)
for {
select { //2
case <-done:
return
case v, ok := <-c:
if ok == false {
return
}
select {
case valStream <- v: //3
case <-done: //1
}
}
}
}()
return valStream
}
Basically, either correct me if I'm wrong or confirm that my understanding of the execution is correct. There indeed are "loopholes" with the code and that is just channel behaviour here.
Similar Question here
Reading Concurrency in Go.
Trying to understand the or-done-channel pattern.
Having trouble wrapping my head around the execution flow.
I have mentioned number against the line where my doubt is from.
Why no
return
statement in inner<-done
like we have in outerselect
? Because of noreturn
statement, the next iteration will run and what if in that iteration we have both<- done
and<-c
available. We knowselect-case
will choose any of the case arbitrarily if multiple cases are available. Does this mean there is a possibility that<-c
will run even if<-done
was available?Since
select-case
arbitrarily chooses a case when multiple case are available, is it correct to assume that the<- done
will be chosen eventually but it is not necessary that it is chosen immediately as soon as it is closed. Of Course, this doubt is when both case i.e.<-done
and<-c
were available.There is a possibility that
<- v
is not written ontovalStream
whendone
is closed and it is lost forever, correct?
orDone := func(done, c <-chan interface{}) <-chan interface{} {
valStream := make(chan interface{})
go func() {
defer close(valStream)
for {
select { //2
case <-done:
return
case v, ok := <-c:
if ok == false {
return
}
select {
case valStream <- v: //3
case <-done: //1
}
}
}
}()
return valStream
}
Basically, either correct me if I'm wrong or confirm that my understanding of the execution is correct. There indeed are "loopholes" with the code and that is just channel behaviour here.
Similar Question here
Share Improve this question edited Feb 6 at 16:39 Burak Serdar 51.5k4 gold badges48 silver badges69 bronze badges asked Feb 6 at 16:03 user10089194user10089194 3692 gold badges5 silver badges16 bronze badges1 Answer
Reset to default 1- Inner select
<-done
case should also have a return. This code is relying on the outer select to capture<-done
, which may not happen immediately - If
<-done
is available it will be chosen eventually. It is likely that it will be chosen quickly, but you are correct. There is no guarantee that even if the inner select chooses<-done
, the outer will chose it as well in its next iteration. - If
<-done
is available, then yes, there is a possibility thatv
will be read but won't be written