Woody1193
Woody1193

Reputation: 7970

Boolean flag received when channel closes is not as expected in Golang

I have a type that I use for repeated authentication:

type Authorizer struct {
    requester    *Requester
    closeChannel chan error
}

func (requester *Requester) Authorize(autoClose bool) {

    // Create a new authorizer from the requester and the close-channel
    authorizer := Authorizer{
        requester:    requester,
        closeChannel: requester.closer,
    }

    // Ensure that the requester has a reference to the authorizer so we can access the
    // updated token
    requester.authorizer = &authorizer

    // Begin the authentication loop concurrently
    go authorizer.manageAuthorization()
}

func (authorizer *Authorizer) manageAuthorization() {

    for {

        select {
        case _, ok := <-authorizer.closeChannel:
            if ok {
                fmt.Printf("Closed\n")
                return // NEVER RUNS
            }
        default:
            break
        }

        fmt.Printf("Not closed\n")
        // Do inner authorization logic
    }
}

And this class creates the authenticater and handles the requests:

type Requester struct {
    authorizer   *Authorizer
    client       *http.Client
    closer       chan error
}

func NewRequester() *Requester {

    requester := Requester{
        client: new(http.Client),
        closer: make(chan error),
    }

    requester.Authorize(false)
    return &requester
}

func (requester *Requester) Close() {
    fmt.Printf("Closing...\n")
    close(requester.closer)
}

So, far, my tests are all passing with this code. However, I'm having an interesting issue when doing coverage. Consider, the following snippet:

// Create the test client
client := Requester{}
client.closer = make(chan error)

// Begin authentication
client.Authorize(false)

// Now, close the channel
close(client.closer)

If I embed this into a test and attempt to run code coverage with it I notice that the indicated line never runs. Furthermore, the debugging messages I added here show the following:

Not closed
Not closed
Not closed
Closing...
Not closed
Not closed
Not closed

At not point does the Closed message print. So, what am I doing wrong here?

Upvotes: 0

Views: 669

Answers (1)

AJR
AJR

Reputation: 1661

ok will be false when the channel is closed. Try

case _, ok := <-authorizer.closeChannel:
    if !ok {
        return // RUNS
    }

Upvotes: 2

Related Questions