AJR
AJR

Reputation: 1671

Disable default part of select statement

I want a way to do processing in the default part of a select statement but then disable the default later.

I have used an if statement as in the code below but, after finished becomes true we just have a busy loop which (when the channels are empty) would just keep spinning testing the finished flag which would always be true. This does not seem like the right way to Go.

for {
    select {
    case p := <-subscriber.Next:
        ...
    case err := <subsriber.OnError:
        ...
    default:
        if !finished {
            subscriber.Subscribe(name, params)
            ...
            if ... { finished = true }
        }
        
    }
}

I know you can't disable the default part but there must be a better way to do this.

Upvotes: 1

Views: 96

Answers (2)

Andrew W. Phillips
Andrew W. Phillips

Reputation: 3601

You can't disable the default clause but you can disable a case clause by assigning nil to the chan. Maybe create a very fast ticker as in the code below. The code below assigns the chan C from the ticker to defaultCh then later disables it by assigning nil.

    ticker := time.NewTicker(time.Microsecond)
    defaultCh := ticker.C
    for {
        select {
            case p := <-subscriber.Next:
                ...
            case err := <subscriber.OnError:
                ...
            case <-defaultCh:
                subscriber.Subscribe(name, params)
                ...
                if finished {
                    defaultCh = nil
                    ticker.Stop()
                }
            }
        }
    }

Upvotes: 1

xarantolus
xarantolus

Reputation: 2029

I'm not aware of anything built-in to do this, but you could enter two different select statements depending on your state.

for {
    // Without default case, wait only for cases
    if finished {
        select {
        case p := <-subscriber.Next:
            //...
        case err := <-subsriber.OnError:
            //...
        }
    } else {
        // Allow default case
        select {
        case p := <-subscriber.Next:
            //...
        case err := <-subsriber.OnError:
            //...
        default:
            subscriber.Subscribe(name, params)
        }
    }
}

This will of course lead to code duplication, but at least it does not enter the loop only to find out that nothing needs to be done.

Upvotes: 1

Related Questions