使用Go客户端的Query()函数时,Aerospike随机返回nil错误。

huangapple go评论96阅读模式
英文:

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

问题

我正在经历一些奇怪的行为。我正在尝试设置一个小的Web应用程序,使用运行在Ubuntu 12.04服务器上的Aerospike 3.5 Community来获取一些数据。我正在使用默认的aerospike.conf文件(使用'test'命名空间),并且正在按照这里的示例进行查询。

当我尝试使用过滤器查询一些记录时,错误通道_randomly_返回一个空错误。(此示例指向我的开发数据库实例)。

为了复制这个问题,多次编译和运行以下代码,你会看到要么返回数据,要么发生panic:

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 {

	// 使用过滤器获取一些记录
	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)
	}

	// 将结果收集到一个切片中
	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
}
英文:

I'm experiencing some strange behavior. I'm trying to set up a small webapp that fetches some data using Aerospike 3.5 Community running on an Ubuntu 12.04 server. I'm using the default aerospike.conf file (using the 'test' namespace) and am following the example of how to query here.

When I attempt to query some records with a filter, the Errors channel randomly is returning a nil error. (This example points to my dev database instance).

To replicate, compile and run the following multiple times, you'll see either data returned or a panic:

package main

import (
	&quot;fmt&quot;

	&quot;github.com/aerospike/aerospike-client-go&quot;
)

func main() {

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

	recs := liststuff(c)

	fmt.Printf(&quot;got results: %v&quot;, recs)
}

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

	// fetch some records with a filter
	stm := aerospike.NewStatement(&quot;test&quot;, &quot;products&quot;)
	stm.Addfilter(aerospike.NewEqualFilter(&quot;visible&quot;, 1))
	fmt.Println(&quot;querying...&quot;)
	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 := &lt;-recordset.Records:
			if !chanOpen {
				break L
			}
			fmt.Println(&quot;found record %v&quot;, rec)
			recs = append(recs, rec)
		case err := &lt;-recordset.Errors:
			if err != nil {
				panic(err)
			} else {
				panic(fmt.Errorf(&quot;error nil when it should exist&quot;))
			}
			return nil
		}
	}

	return recs
}

答案1

得分: 3

只是为了发布一个更新,当服务器端的记录流结束时,错误通道和记录通道都会自动关闭,因此从错误通道中得到的值是nil。

所以这实际上并不是一个错误。我们已经相应地更新了我们在Aerospike用户论坛中的帖子。

英文:

Just to post an update, both Errors and Records channels are closed automatically when the record stream is over from the server-side, hence the nil value from the Errors channel.

So this wasn't an error after all. We've updated the thread in our Aerospike user forum post accordingly.

答案2

得分: 1

我对aerospike包不太熟悉,但运行你的示例代码显示,无论是否返回数据,它都会引发panic。

这意味着Errors通道始终发送errornil。如果这是预期的行为,你需要相应地处理它,并且只在错误不为nil时才引发panic。

在通道上发送nil仍然意味着在通道上发送了一个值,并且它将触发select语句。因此,在nil error上引发panic。

你看到的随机性,即有时返回数据,有时不返回数据,是由于select语句的特性。如果同时发送数据和nil error,两种情况都为真,select语句将伪随机选择其中之一。

> 如果一个或多个通信可以进行,将通过均匀的伪随机选择选择一个可以进行的通信。否则,如果有默认情况,将选择该情况。如果没有默认情况,"select"语句将阻塞,直到至少有一个通信可以进行。

如果它首先选择数据通道,它将打印数据,然后在下一次迭代中选择错误通道并引发panic。如果它首先选择错误通道,它将引发panic,数据将不会打印出来。

英文:

I'm not familiar with the aerospike package but running your example code show that it always panics no matter if it returns data or not.

That means that the Errors channel always sends either an error or nil. If that's the expected behavior you'd have to handle it accordingly and only panic when the error is not nil.

Sending nil on the channel still means that a value is being sent on the channel and it will trigger the select statement. Thus the panic on a nil error.

The randomness you see, i.e. sometimes data is returned and sometimes it isn't is due to the nature of the select statement. If both data and a nil error are being sent at the same time both cases are true and select will pseudo randomly select one of the two.

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

If it selects the data channel first it will print the data and then on the next iteration select the error channel and panic. If it picks the error channel first it panics and the data never prints.

答案3

得分: 1

原文翻译如下:

原来这是一个真正的 bug,应该很快修复:https://discuss.aerospike.com/t/aerospike-randomly-returning-nil-errors-when-using-query-with-go-client/1346

英文:

Turns out it's a legit bug and should be fixed soon: https://discuss.aerospike.com/t/aerospike-randomly-returning-nil-errors-when-using-query-with-go-client/1346

huangapple
  • 本文由 发表于 2015年6月6日 06:44:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/30676900.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定