【问题标题】:Boolean flag received when channel closes is not as expected in Golang通道关闭时收到的布尔标志与 Golang 中的预期不同
【发布时间】:2020-10-20 13:06:21
【问题描述】:

我有一个用于重复验证的类型:

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
    }
}

这个类创建身份验证器并处理请求:

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)
}

到目前为止,我的测试都通过了这段代码。但是,我在进行报道时遇到了一个有趣的问题。考虑以下 sn-p:

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

// Begin authentication
client.Authorize(false)

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

如果我将它嵌入到测试中并尝试使用它运行代码覆盖率,我注意到指示的行永远不会运行。此外,我在此处添加的调试消息显示如下:

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

Closed 消息不会打印。那么,我在这里做错了什么?

【问题讨论】:

  • "我有一个正在使用的类..." 注意:Go 没有任何类。
  • 在没有看到它的情况下调试你的测试用例将是非常困难的。您可以在您的问题中添加minimal, reproducible example 吗?
  • client := Requestor{} 应该是client := Requester{}

标签: go channel


【解决方案1】:

当频道关闭时ok 将是false。试试

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    • 2022-01-10
    • 2014-06-02
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    相关资源
    最近更新 更多