Reputation: 1550
Similar: golang: goroute with select doesn't stop unless I added a fmt.Print()
I am writing a code in go, where a goroutine keeps receiving and processing requests on a socket. To stop the execution of current goroutine, I send true
to a channel from some other goroutine, for which the current goroutine keeps listening in select
statement.
But the problem here is that even after sending signal on channel, default
block keeps executing forever. And case
block is never executed. Following is the code snippet I am having problem with.
for {
select{
//goroutine should return when something is received on channel 's.stopInbox'
case <-s.stopInbox:
fmt.Println("stopInbox")
return
//keep receiving and processing requests until anything is received on channel 's.stopInbox'
default:
fmt.Println("default case")
msg, err := responder.Recv(0)
if err != nil {
fmt.Println("Error receiving message", err.Error())
break
}
envelope := msgToEnvelope(msg)
s.inbox <- &envelope
}
}
I have searched for the problem and found solutions as
With a default statement select will run the default statement every time there is nothing to read from the channels. And because of this, scheduler will never get a chance to schedule another goroutine. Putting the
fmt.Print
statement in is allowing the scheduler to schedule other goroutines.
As per suggestion, I tried putting a print statement in default case, also I tried putting a sleep statement in default case. But nothing is working.
Is there any way to make this work? Also is it possible to achieve the intended by completely avoiding select
statement?
Upvotes: 2
Views: 544
Reputation: 49187
If you do responder.Recv
without a timeout, your code will block there forever and you won't get to the default
part. So I guess try setting a timeout ;)
Upvotes: 3