Skip to content

Commit d2258ce

Browse files
authored
Merge pull request #480 from aerospike/stage
Go Client v8.2.1
2 parents d5f672a + 2fc28bd commit d2258ce

17 files changed

+121
-47
lines changed

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Change History
22

3+
## April 14 2025: v8.2.1
4+
5+
- **Improvements**
6+
- [CLIENT-3399] Update dependencies due to snyk security reports.
7+
8+
- **Fixes**
9+
- [CLIENT-3384] Panic in BatchGet with using MRT and Filter Expression together.
10+
- [CLIENT-3397] Retries fail on PutPayload command.
11+
- [CLIENT-3398] Fix Backward compatibility broken in Connection.SetTimeout API
12+
313
## March 18 2025: v8.2.0
414

515
- **Fixes**

admin_command.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ func (acmd *AdminCommand) executeCommand(conn *Connection, policy *AdminPolicy)
396396
timeout = policy.Timeout
397397
}
398398

399-
if err := conn.SetTimeout(timeout, timeout); err != nil {
399+
if err := conn.setTimeout(timeout, timeout); err != nil {
400400
return err
401401
}
402402

@@ -426,7 +426,7 @@ func (acmd *AdminCommand) readUsers(conn *Connection, policy *AdminPolicy) ([]*U
426426
timeout = policy.Timeout
427427
}
428428

429-
if err := conn.SetTimeout(timeout, timeout); err != nil {
429+
if err := conn.setTimeout(timeout, timeout); err != nil {
430430
return nil, err
431431
}
432432

@@ -579,7 +579,7 @@ func (acmd *AdminCommand) readRoles(conn *Connection, policy *AdminPolicy) ([]*R
579579
timeout = policy.Timeout
580580
}
581581

582-
if err := conn.SetTimeout(timeout, timeout); err != nil {
582+
if err := conn.setTimeout(timeout, timeout); err != nil {
583583
return nil, err
584584
}
585585

batch_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ var _ = gg.Describe("Aerospike", func() {
427427
// gm.Expect(err.Matches(types.BATCH_MAX_REQUESTS_EXCEEDED)).To(gm.BeTrue())
428428
})
429429

430-
gg.It("XXXShould return the error for invalid namespace", func() {
430+
gg.It("Should return the error for invalid namespace", func() {
431431
var brs []as.BatchRecordIfc
432432

433433
for i := 0; i < 1; i++ {

cdt_context.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,6 @@ func CtxMapKeyCreate(key Value, order mapOrderType) *CDTContext {
198198
}
199199

200200
// CtxMapValue defines Lookup map by value.
201-
func CtxMapValue(key Value) *CDTContext {
202-
return &CDTContext{ctxTypeMapValue, key}
201+
func CtxMapValue(value Value) *CDTContext {
202+
return &CDTContext{ctxTypeMapValue, value}
203203
}

client_policy.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ type ClientPolicy struct {
3131
// in hashed format. Leave empty for clusters running without restricted access.
3232
Password string
3333

34-
// ClusterName sets the expected cluster ID. If not nil, server nodes must return this cluster ID in order to
34+
// ClusterName sets the expected cluster ID. If not nil, server nodes must return this cluster ID in order to
3535
// join the client's view of the cluster. Should only be set when connecting to servers that
3636
// support the "cluster-name" info command. (v3.10+)
3737
ClusterName string //=""
3838

39-
// Initial host connection timeout duration. The timeout when opening a connection
39+
// Initial host connection timeout duration. The timeout when opening a connection
4040
// to the server host for the first time.
4141
Timeout time.Duration //= 30 seconds
4242

@@ -115,7 +115,7 @@ type ClientPolicy struct {
115115
TendInterval time.Duration //= 1 second
116116

117117
// A IP translation table is used in cases where different clients
118-
// use different server IP addresses. This may be necessary when
118+
// use different server IP addresses. This may be necessary when
119119
// using clients from both inside and outside a local area
120120
// network. Default is no translation.
121121
// The key is the IP address returned from friend info requests to other servers.
@@ -125,7 +125,7 @@ type ClientPolicy struct {
125125
// UseServicesAlternate determines if the client should use "services-alternate" instead of "services"
126126
// in info request during cluster tending.
127127
//"services-alternate" returns server configured external IP addresses that client
128-
// uses to talk to nodes. "services-alternate" can be used in place of providing a client "ipMap".
128+
// uses to talk to nodes. "services-alternate" can be used in place of providing a client "ipMap".
129129
// This feature is recommended instead of using the client-side IpMap above.
130130
//
131131
// "services-alternate" is available with Aerospike Server versions >= 3.7.1.

client_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ var _ = gg.Describe("Aerospike", func() {
472472

473473
binMap := as.BinMap{
474474
"Aerospike": "value",
475-
"Aerospike1": "value2",
475+
"Aerospike1": strings.Repeat("a", 1e5+1e4),
476476
}
477477

478478
wcmd, err := as.NewWriteCommand(nil, wpolicy, key, nil, binMap)

connection.go

+14-5
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func newConnection(address string, timeout time.Duration) (*Connection, Error) {
156156
newConn.limitReader = &io.LimitedReader{R: conn, N: 0}
157157

158158
// set timeout at the last possible moment
159-
if err := newConn.SetTimeout(timeout, timeout); err != nil {
159+
if err := newConn.setTimeout(timeout, timeout); err != nil {
160160
newConn.Close()
161161
return nil, err
162162
}
@@ -333,7 +333,16 @@ func (ctn *Connection) updateDeadline() Error {
333333
}
334334

335335
// SetTimeout sets connection timeout for both read and write operations.
336-
func (ctn *Connection) SetTimeout(totalTimeout, socketTimeout time.Duration) Error {
336+
func (ctn *Connection) setTimeout(totalTimeout, socketTimeout time.Duration) Error {
337+
var deadline time.Time
338+
if totalTimeout > 0 {
339+
deadline = time.Now().Add(totalTimeout)
340+
}
341+
return ctn.SetTimeout(deadline, socketTimeout)
342+
}
343+
344+
// SetTimeout sets connection timeout for both read and write operations.
345+
func (ctn *Connection) SetTimeout(deadline time.Time, socketTimeout time.Duration) Error {
337346
now := time.Now()
338347
ctn.socketTimeout = _DEFAULT_TIMEOUT
339348
ctn.deadline = time.Time{}
@@ -343,10 +352,10 @@ func (ctn *Connection) SetTimeout(totalTimeout, socketTimeout time.Duration) Err
343352
}
344353

345354
// keep the deadline.IsZero() == true if totalTimeout is not set
346-
if totalTimeout > 0 {
347-
ctn.deadline = now.Add(totalTimeout)
355+
if !deadline.IsZero() {
356+
ctn.deadline = deadline
348357
if socketTimeout <= 0 {
349-
ctn.socketTimeout = totalTimeout
358+
ctn.socketTimeout = deadline.Sub(now)
350359
}
351360
}
352361
return nil

connection_heap.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ func (h *singleConnectionHeap) RefreshIdleTail(tendInterval time.Duration) bool
165165

166166
// refresh in a goroutine asynchronously
167167
go func() {
168-
conn.SetTimeout(time.Second, time.Second)
168+
conn.setTimeout(time.Second, time.Second)
169169
conn.refresh()
170170
if _, err := conn.RequestInfo("build"); err == nil {
171171
// return to the pool

connection_test.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ var _ = gg.Describe("Connection Test", func() {
4343
})
4444

4545
gg.It("Dealines should be calculated correctly", func() {
46+
deadline := func(timeout time.Duration) (res time.Time) {
47+
if timeout > 0 {
48+
res = time.Now().Add(timeout)
49+
}
50+
return res
51+
}
52+
4653
testMatrix := []testExpectations{
4754
{0, 0, time.Time{}, time.Now().Add(as.DefaultTimeout()), as.DefaultTimeout()},
4855
{0, time.Second, time.Time{}, time.Now().Add(time.Second), time.Second},
@@ -52,7 +59,7 @@ var _ = gg.Describe("Connection Test", func() {
5259

5360
for _, matrix := range testMatrix {
5461
gg.By(fmt.Sprintf("TotalTimeout: %v, SocketTimeout: %v", matrix.totalTimeout, matrix.socketTimeout))
55-
err := conn.SetTimeout(matrix.totalTimeout, matrix.socketTimeout)
62+
err := conn.SetTimeout(deadline(matrix.totalTimeout), matrix.socketTimeout)
5663
gm.Expect(err).ToNot(gm.HaveOccurred())
5764

5865
expTotalDeadline, expSocketDeadline, expSocketTimeout, err := conn.UpdateDeadline()
@@ -62,7 +69,7 @@ var _ = gg.Describe("Connection Test", func() {
6269

6370
gm.Expect(expTotalDeadline).To(gm.BeTemporally("~", matrix.expTotalDeadline, time.Millisecond))
6471
gm.Expect(expSocketDeadline).To(gm.BeTemporally("~", matrix.expSocketDeadline, time.Millisecond))
65-
gm.Expect(expSocketTimeout).To(gm.Equal(matrix.expSocketTimeout))
72+
gm.Expect(expSocketTimeout).To(gm.BeNumerically("~", matrix.expSocketTimeout, time.Millisecond))
6673
}
6774
})
6875

go.mod

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
module github.com/aerospike/aerospike-client-go/v8
22

3-
go 1.23
3+
go 1.23.0
44

55
require (
66
github.com/onsi/ginkgo/v2 v2.22.2
77
github.com/onsi/gomega v1.36.2
88
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad
99
github.com/yuin/gopher-lua v1.1.1
10-
golang.org/x/sync v0.10.0
10+
golang.org/x/sync v0.12.0
1111
)
1212

1313
require (
@@ -17,10 +17,10 @@ require (
1717
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
1818
github.com/kr/pretty v0.3.1 // indirect
1919
github.com/stretchr/testify v1.10.0 // indirect
20-
golang.org/x/net v0.33.0 // indirect
21-
golang.org/x/sys v0.28.0 // indirect
22-
golang.org/x/text v0.21.0 // indirect
23-
golang.org/x/tools v0.28.0 // indirect
20+
golang.org/x/net v0.37.0 // indirect
21+
golang.org/x/sys v0.31.0 // indirect
22+
golang.org/x/text v0.23.0 // indirect
23+
golang.org/x/tools v0.31.0 // indirect
2424
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
2525
gopkg.in/yaml.v3 v3.0.1 // indirect
2626
)

go.sum

+10-10
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad h1:W0LEBv82YCGEtc
3131
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad/go.mod h1:Hy8o65+MXnS6EwGElrSRjUzQDLXreJlzYLlWiHtt8hM=
3232
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
3333
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
34-
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
35-
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
36-
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
37-
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
38-
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
39-
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
40-
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
41-
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
42-
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
43-
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
34+
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
35+
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
36+
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
37+
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
38+
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
39+
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
40+
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
41+
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
42+
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
43+
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
4444
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
4545
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
4646
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

login_command.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func (lcmd *loginCommand) login(policy *ClientPolicy, conn *Connection, hashedPa
9393

9494
lcmd.writeSize()
9595

96-
conn.SetTimeout(policy.LoginTimeout, policy.LoginTimeout)
96+
conn.setTimeout(policy.LoginTimeout, policy.LoginTimeout)
9797

9898
if _, err := conn.Write(lcmd.dataBuffer[:lcmd.dataOffset]); err != nil {
9999
return err

multi_command.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ func (cmd *baseMultiCommand) parseVersion(fieldCount int) (*uint64, Error) {
247247
size := fieldlen - 1
248248

249249
if fieldType == RECORD_VERSION && size == 7 {
250-
version = Buffer.VersionBytesToUint64(cmd.dataBuffer, cmd.dataOffset)
250+
version = Buffer.VersionBytesToUint64(cmd.dataBuffer, 1)
251251
}
252252
}
253253
return version, nil

node.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ func (nd *Node) getConnectionWithHint(totalTimeout, socketTimeout time.Duration,
538538
return nil, ErrConnectionPoolEmpty.err()
539539
}
540540

541-
if err = conn.SetTimeout(totalTimeout, socketTimeout); err != nil {
541+
if err = conn.setTimeout(totalTimeout, socketTimeout); err != nil {
542542
nd.stats.ConnectionsFailed.IncrementAndGet()
543543

544544
// Do not put back into pool.
@@ -718,7 +718,7 @@ func (nd *Node) usingTendConn(timeout time.Duration, f func(conn *Connection)) (
718718
}
719719

720720
// Set timeout for tend conn
721-
if err = (*conn).SetTimeout(timeout, timeout); err != nil {
721+
if err = (*conn).setTimeout(timeout, timeout); err != nil {
722722
return
723723
}
724724

txn_test.go

+47
Original file line numberDiff line numberDiff line change
@@ -793,5 +793,52 @@ var _ = gg.Describe("Aerospike", func() {
793793
}
794794
})
795795

796+
gg.It("must succeed BatchGet with expressions and transaction", func() {
797+
client.Truncate(nil, "test", "", nil)
798+
799+
startKey := 0
800+
endKey := 999
801+
num := 300 // example value, change to test others like 0, 600, 1010
802+
// Generate keys
803+
keys := make([]*as.Key, 0, endKey-startKey+1)
804+
for i := startKey; i <= endKey; i++ {
805+
key, err := as.NewKey(ns, set, i)
806+
gm.Expect(err).ToNot(gm.HaveOccurred())
807+
808+
keys = append(keys, key)
809+
}
810+
811+
// Create the expression: bin_i > num
812+
expr := as.ExpGreater(
813+
as.ExpIntBin("bin_i"),
814+
as.ExpIntVal(int64(num)),
815+
)
816+
817+
// Create MRT transaction
818+
txn := as.NewTxn()
819+
820+
// Create policy with expression and txn
821+
policy := as.NewBatchPolicy()
822+
policy.BasePolicy = *as.NewPolicy()
823+
policy.FilterExpression = expr
824+
policy.Txn = txn
825+
826+
// Perform BatchGet
827+
records, err := client.BatchGet(policy, keys)
828+
gm.Expect(err).ToNot(gm.HaveOccurred())
829+
830+
// Check filtered-in records
831+
for _, rec := range records {
832+
if rec != nil {
833+
val := rec.Bins["bin_i"]
834+
gm.Expect(val).NotTo(gm.BeNil())
835+
gm.Expect(val.(int)).To(gm.BeNumerically(">", num))
836+
}
837+
}
838+
839+
_, err = client.Commit(txn)
840+
gm.Expect(err).ToNot(gm.HaveOccurred())
841+
})
842+
796843
}) // describe
797844
})

value.go

+5
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,11 @@ func (vl FloatValue) String() string {
782782
// Supported by Aerospike server v5.6+ only.
783783
type BoolValue bool
784784

785+
// NewBoolValue generates a BoolValue instance.
786+
func NewBoolValue(b bool) BoolValue {
787+
return BoolValue(b)
788+
}
789+
785790
// EstimateSize returns the size of the BoolValue in wire protocol.
786791
func (vb BoolValue) EstimateSize() (int, Error) {
787792
return PackBool(nil, bool(vb))

write_payload_command.go

+4-8
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ func (cmd *writePayloadCommand) getPolicy(ifc command) Policy {
6060
}
6161

6262
func (cmd *writePayloadCommand) writeBuffer(ifc command) Error {
63-
cmd.dataBuffer = cmd.payload
64-
cmd.dataOffset = len(cmd.payload)
63+
if err := cmd.sizeBufferSz(len(cmd.payload), false); err != nil {
64+
return err
65+
}
66+
cmd.dataOffset = copy(cmd.dataBuffer, cmd.payload)
6567
return nil
6668
}
6769

@@ -75,12 +77,6 @@ func (cmd *writePayloadCommand) prepareRetry(ifc command, isTimeout bool) bool {
7577
}
7678

7779
func (cmd *writePayloadCommand) parseResult(ifc command, conn *Connection) Error {
78-
// make sure the payload is not put back in the buffer pool
79-
defer func() {
80-
cmd.dataBuffer = cmd.conn.origDataBuffer
81-
cmd.dataOffset = 0
82-
}()
83-
8480
// Read header.
8581
if _, err := conn.Read(cmd.dataBuffer, int(_MSG_TOTAL_HEADER_SIZE)); err != nil {
8682
return err

0 commit comments

Comments
 (0)