santosh-patil
santosh-patil

Reputation: 1550

Default case of select statement keeps executing

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

Answers (1)

Not_a_Golfer
Not_a_Golfer

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

Related Questions