将 Query() 与 Go 客户端一起使用时,Aerospike 随机返回 nil 错误

Aerospike randomly returning nil errors when using Query() with Go client

我遇到了一些奇怪的行为。我正在尝试设置一个小型网络应用程序,该应用程序在 Ubuntu 12.04 服务器上使用 Aerospike 3.5 Community 运行ning 获取一些数据。我正在使用默认的 aerospike.conf 文件(使用 'test' 命名空间)并遵循如何查询 here 的示例。

当我尝试使用过滤器查询某些记录时,错误通道随机 返回零错误。 (这个例子指向我的开发数据库实例)。

要多次复制、编译和 运行 以下内容,您将看到返回的数据或崩溃:

package main

import (
    "fmt"

    "github.com/aerospike/aerospike-client-go"
)

func main() {

    c, err := aerospike.NewClient("52.7.157.46", 3000)
    if err != nil {
        panic(err)
    }

    recs := liststuff(c)

    fmt.Printf("got results: %v", recs)
}

func liststuff(client *aerospike.Client) []*aerospike.Record {

    // fetch some records with a filter
    stm := aerospike.NewStatement("test", "products")
    stm.Addfilter(aerospike.NewEqualFilter("visible", 1))
    fmt.Println("querying...")
    recordset, err := client.Query(nil, stm)
    if err != nil {
        panic(err)
    }

    // collect results into a slice
    recs := []*aerospike.Record{}
L:
    for {
        select {
        case rec, chanOpen := <-recordset.Records:
            if !chanOpen {
                break L
            }
            fmt.Println("found record %v", rec)
            recs = append(recs, rec)
        case err := <-recordset.Errors:
            if err != nil {
                panic(err)
            } else {
                panic(fmt.Errorf("error nil when it should exist"))
            }
            return nil
        }
    }

    return recs
}

我不熟悉 aerospike 包,但是 运行 你的示例代码表明无论是否 returns 数据它总是恐慌。

这意味着 Errors 频道总是发送 errornil。如果这是预期的行为,您必须相应地处理它,并且只有在错误不是 nil.

时才会恐慌

在通道上发送 nil 仍然意味着正在通道上发送一个值,它将触发 select 语句。因此 nil error.

上的恐慌

您看到的随机性,即有时返回数据有时不返回,是由于 select 语句的性质。如果同时发送数据和 nil error 两种情况都为真,并且 select 将 pseudo randomly select 两者之一。

If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection. Otherwise, if there is a default case, that case is chosen. If there is no default case, the "select" statement blocks until at least one of the communications can proceed.

如果它 select 首先是数据通道,它将打印数据,然后在下一次迭代中 select 错误通道和恐慌。如果它首先选择错误通道,它会崩溃并且数据永远不会打印。

事实证明这是一个合法的错误,应尽快修复:https://discuss.aerospike.com/t/aerospike-randomly-returning-nil-errors-when-using-query-with-go-client/1346

只是为了 post 更新,当服务器端的记录流结束时,错误和记录通道都会自动关闭,因此错误通道的值为 nil。

所以这毕竟不是错误。我们相应地更新了 Aerospike 用户论坛 post 中的主题。