Open noam-ma-ma opened 1 month ago
PartitionFilter
object is not designed nor intended to be used concurrently. It's a cursor, designed specifically to hold the state and progress of one ongoing query. You can reuse that object if the query is finished (for pagination) or if it errors out and terminates. Otherwise, the behavior is undefined.
In your example, you reuse that object while the original query is ongoing, which is not how that object is intended to be used.
PartitionFilter
object is not designed nor intended to be used concurrently. It's a cursor, designed specifically to hold the state and progress of one ongoing query. You can reuse that object if the query is finished (for pagination) or if it errors out and terminates. Otherwise, the behavior is undefined. In your example, you reuse that object while the original query is ongoing, which is not how that object is intended to be used.
The example in aerospike docs reuses the partitionFilter
the same way I used in the code block provided.
Do you have an example for proper pagination then?
Thanks for bringing this to my attention. I don't know what that code is trying to achieve. I'll contact my colleagues and get it fixed. You can take a look at the correct way of using Query/Scan filters, including pagination here.
The following code should work without the race condition:
package bla
import (
"github.com/aerospike/aerospike-client-go/v7"
"log"
"testing"
)
func TestRace(t *testing.T) {
// Establishes a connection to the server
client, err := aerospike.NewClient("127.0.0.1", 3000)
if err != nil {
log.Fatal(err)
}
defer client.Close()
policy := aerospike.NewWritePolicy(0, 0)
// Create the record key
key, err := aerospike.NewKey("myns", "ufodata", 5001)
if err != nil {
log.Fatal(err)
}
mybin := aerospike.NewBin("mybin", 20220531)
err = client.PutBins(policy, key, mybin)
if err != nil {
log.Fatal(err)
}
key, err = aerospike.NewKey("myns", "ufodata", 5002)
err = client.PutBins(policy, key, mybin)
if err != nil {
log.Fatal(err)
}
// Create query policy
queryPolicy := aerospike.NewQueryPolicy()
queryPolicy.FilterExpression = aerospike.ExpBinExists("mybin")
queryPolicy.MaxRecords = 1
// Create statement
stmt := aerospike.NewStatement("myns", "ufodata")
partitionFilter := aerospike.NewPartitionFilterAll()
recordSet, err := client.QueryPartitions(queryPolicy, stmt, partitionFilter)
if err != nil {
log.Fatal(err)
}
for {
for result := range recordSet.Results() {
if result.Err == nil && result.Record != nil {
log.Printf("Record found: %v", result.Record.Bins)
}
}
if partitionFilter.IsDone() {
break
}
// Execute the query reusing the partitionFilter until all records returned
recordSet, err = client.QueryPartitions(queryPolicy, stmt, partitionFilter)
if err != nil {
log.Fatal(err)
}
}
recordSet.Close()
}
While running a primary index query with pagination (page size = 1, total records = 2), I saw that there is a DATA RACE violation. Client version v7.1.0
Full example to reproduce:
go test -v -race race_test.go