From 751ae9dde40e5ac713c0d567450bc6a3c0fcefc9 Mon Sep 17 00:00:00 2001 From: Khosrow Afroozeh Date: Wed, 18 Sep 2024 16:43:54 +0200 Subject: [PATCH 1/5] [CLIENT-3122] Fix nil deref in Tend logic --- CHANGELOG.md | 9 ++++++++- go.mod | 5 ++++- internal/seq/seq.go | 10 ++++------ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c32e9daa..d20206f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change History +## September 18 2024: v7.7.1 + + Hot Fix release. This version fixes a major bug introduced in v7.7.0. You should use this release instead. + +- **Fixes** + - [CLIENT-3122] Fix `nil` dereference in the tend logic. + ## September 13 2024: v7.7.0 Minor improvement release. @@ -51,7 +58,7 @@ - **Improvements** - [CLIENT-2997] Scans should work in a mixed cluster of v5.7 and v6.4 server nodes. - [CLIENT-3020] Change `ReadModeSC` doc from server to client perspective. - + - **Fixes** - [CLIENT-3019] Prevent Goroutine leak in `AuthInterceptor` for the Proxy Client. diff --git a/go.mod b/go.mod index 63df5f31..6f2b6d8e 100644 --- a/go.mod +++ b/go.mod @@ -29,4 +29,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) -retract v7.3.0 // `Client.BatchGetOperate` issue +retract ( + v7.3.0 // `Client.BatchGetOperate` issue + v7.7.0 // nil deref in tend logic +) diff --git a/internal/seq/seq.go b/internal/seq/seq.go index 1b6da158..a04100e4 100644 --- a/internal/seq/seq.go +++ b/internal/seq/seq.go @@ -37,10 +37,10 @@ func ParDo[T any](seq []T, f func(T)) { wg := new(sync.WaitGroup) wg.Add(len(seq)) for i := range seq { - go func() { + go func(t T) { defer wg.Done() - f(seq[i]) - }() + f(t) + }(seq[i]) } wg.Wait() } @@ -77,8 +77,6 @@ func Clone[T any](seq []T) []T { } res := make([]T, len(seq)) - for i := range seq { - res[i] = seq[i] - } + copy(res, seq) return res } From 8ffe7bec9676eaeb51d55dec83d6b70bfcc08252 Mon Sep 17 00:00:00 2001 From: Khosrow Afroozeh Date: Fri, 1 Nov 2024 15:31:29 +0100 Subject: [PATCH 2/5] [CLIENT-3156] Fix as issue where rack policy always returns the master node --- CHANGELOG.md | 7 +++++++ partition.go | 8 ++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d20206f4..5f57fb4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change History +## November 1 2024: v7.7.2 + + Minor fix release. + +- **Fixes** + - [CLIENT-3156] Fix an issue where rack policy always returns the master node. Resolves #455 + ## September 18 2024: v7.7.1 Hot Fix release. This version fixes a major bug introduced in v7.7.0. You should use this release instead. diff --git a/partition.go b/partition.go index 58396273..38b63633 100644 --- a/partition.go +++ b/partition.go @@ -249,21 +249,25 @@ func (ptn *Partition) getSequenceNode(cluster *Cluster) (*Node, Error) { func (ptn *Partition) getRackNode(cluster *Cluster) (*Node, Error) { replicas := ptn.partitions.Replicas + // Try to find a node on the same rack first: for _, rackId := range cluster.clientPolicy.RackIds { seq := ptn.sequence for range replicas { - index := ptn.sequence % len(replicas) + index := seq % len(replicas) node := replicas[index][ptn.PartitionId] if node != nil && node != ptn.prevNode && node.hasRack(ptn.Namespace, rackId) && node.IsActive() { ptn.prevNode = node - ptn.sequence = seq + ptn.sequence = seq + 1 // start from the next node and save a comparison return node, nil } seq++ } } + // A node on the same Rack was not found, so try other options. + // Same node as the previous will be the last option, + // since it is the least desirable. for range replicas { index := ptn.sequence % len(replicas) node := replicas[index][ptn.PartitionId] From 9ff03e8dd550182be156ee849bfb99d32bc8491e Mon Sep 17 00:00:00 2001 From: "Eugene R." Date: Fri, 29 Nov 2024 14:09:12 +0200 Subject: [PATCH 3/5] Parse nil keys properly in query operations (#457) [CLIENT-3196] Parse nil keys properly in query operations --------- Co-authored-by: Khosrow Afroozeh --- key_helper.go | 1 + value.go | 3 +++ 2 files changed, 4 insertions(+) diff --git a/key_helper.go b/key_helper.go index 38ead4ff..f237fc89 100644 --- a/key_helper.go +++ b/key_helper.go @@ -150,5 +150,6 @@ func (vb *keyWriter) writeKey(val Value) Error { return nil } + // TODO: Replace the error message with fmt.Sprintf("Key Generation Error. Value type not supported: %T", val) return newError(types.PARAMETER_ERROR, "Key Generation Error. Value not supported: "+val.String()) } diff --git a/value.go b/value.go index 1b60a8a4..297581a3 100644 --- a/value.go +++ b/value.go @@ -1275,6 +1275,9 @@ func bytesToKeyValue(pType int, buf []byte, offset int, length int) (Value, Erro } return ListValue(v), nil + case ParticleType.NULL: + return NewNullValue(), nil + default: return nil, newError(types.PARSE_ERROR, fmt.Sprintf("ParticleType %d not recognized. Please file a github issue.", pType)) } From c9ccec314ab26c4f9deb35ff2d34187ab35d5126 Mon Sep 17 00:00:00 2001 From: Khosrow Afroozeh Date: Fri, 29 Nov 2024 13:11:57 +0100 Subject: [PATCH 4/5] Updated CHANGELOG --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f57fb4a..6ae33281 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change History +## November 29 2024: v7.7.3 + + Minor fix release. + +- **Fixes** + - [CLIENT-3196] Parse nil keys properly in scan/query operations. + ## November 1 2024: v7.7.2 Minor fix release. From ab899d55450a8827099d2c8c0baef919f8cfaea4 Mon Sep 17 00:00:00 2001 From: Khosrow Afroozeh Date: Fri, 29 Nov 2024 13:15:41 +0100 Subject: [PATCH 5/5] Add -use-services-alternate to test arguments --- aerospike_suite_test.go | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/aerospike_suite_test.go b/aerospike_suite_test.go index 478c46d4..af301d88 100644 --- a/aerospike_suite_test.go +++ b/aerospike_suite_test.go @@ -39,18 +39,19 @@ import ( ) var ( - hosts = flag.String("hosts", "", "Comma separated Aerospike server seed hostnames or IP addresses and ports. eg: s1:3000,s2:3000,s3:3000") - host = flag.String("h", "127.0.0.1", "Aerospike server seed hostnames or IP addresses") - nativeHosts = flag.String("nh", "127.0.0.1:3000", "Native Aerospike server seed hostnames or IP addresses, used in tests for GRPC to support unsupported API") - port = flag.Int("p", 3000, "Aerospike server seed hostname or IP address port number.") - user = flag.String("U", "", "Username.") - password = flag.String("P", "", "Password.") - authMode = flag.String("A", "internal", "Authentication mode: internal | external") - useReplicas = flag.Bool("use-replicas", false, "Aerospike will use replicas as well as master partitions.") - debug = flag.Bool("debug", false, "Will set the logging level to DEBUG.") - proxy = flag.Bool("proxy", false, "Will use Proxy Client.") - dbaas = flag.Bool("dbaas", false, "Will run the tests for a dbaas environment.") - namespace = flag.String("n", "test", "Namespace") + hosts = flag.String("hosts", "", "Comma separated Aerospike server seed hostnames or IP addresses and ports. eg: s1:3000,s2:3000,s3:3000") + host = flag.String("h", "127.0.0.1", "Aerospike server seed hostnames or IP addresses") + nativeHosts = flag.String("nh", "127.0.0.1:3000", "Native Aerospike server seed hostnames or IP addresses, used in tests for GRPC to support unsupported API") + port = flag.Int("p", 3000, "Aerospike server seed hostname or IP address port number.") + user = flag.String("U", "", "Username.") + password = flag.String("P", "", "Password.") + authMode = flag.String("A", "internal", "Authentication mode: internal | external") + useReplicas = flag.Bool("use-replicas", false, "Aerospike will use replicas as well as master partitions.") + debug = flag.Bool("debug", false, "Will set the logging level to DEBUG.") + proxy = flag.Bool("proxy", false, "Will use Proxy Client.") + dbaas = flag.Bool("dbaas", false, "Will run the tests for a dbaas environment.") + namespace = flag.String("n", "test", "Namespace") + UseServicesAlternate = flag.Bool("use-services-alternate", false, "Will set ClientPolicy.UseServicesAlternate to true.") certFile = flag.String("cert_file", "", "Certificate file name.") keyFile = flag.String("key_file", "", "Key file name.") @@ -100,6 +101,7 @@ func initTestVars() { // setup TLS tlsConfig = initTLS() clientPolicy.TlsConfig = tlsConfig + clientPolicy.UseServicesAlternate = *UseServicesAlternate var dbHosts []*as.Host