Not able to read the record via Operate API using aerospike go client . it always returns the generation id only despite adding GET Operation in the Operations List.
Can someone help me here ?
code snippet
func (c *Aerospike) multiBinUpdate(record Record, ttl, generation uint32) (*uint32, error) {
key, err := c.key(record.GetPK(), record.TableName())
if err != nil {
return nil, err
}
policy := c.getWritePolicy()
policy.Expiration = ttl
policy.GenerationPolicy = aerospike.EXPECT_GEN_EQUAL
policy.Generation = generation
var Operations []*aerospike.Operation
bins := aerospike.Marshal(record, true)
for _, bin := range bins {
Operations = append(Operations, aerospike.PutOp(bin))
}
Operations = append(Operations, aerospike.GetHeaderOp())
var rec *aerospike.Record
if rec, err = c.client.Operate(policy, key, Operations...); err != nil {
return nil, err
}
if rec == nil {
return nil, errors.New("record is not updated")
}
return &rec.Generation, err
}
Sometime it happens that record is not updated and error is also not thrown for the same and application is not able to check if the record is updated or not without error.
if GetOp() is used instead of GetHeaderOp() then it gives parameter error.
@Khosrow_Afroozeh Used aerospike go client latest version and GetOp issue was resolved. However there seems to be an issue with the data updated to aerospike.
issue :
Thread1 and Thread 2 is reading the data at same time. first Thread2 update happens and then Thread 1 and there are no Generation error happening in go client.
code snippet
type record struct {
Counter *int `as:"counter"`
PendingTrans []string `as:"pendingTrans"`
PK *string `as:"pk"`
}
func (a *record) GetPK() string {
return *a.PK
}
func (a *record) MultiBinUpdate(generationId uint32) (*uint32, interface{}, error) {
return aerospike.MultiBinUpdate(a, 0, generationId)
}
func (a *record) GetWithHeader() (*uint32, *uint32, error) {
return aerospike.GetWithHeader(a.GetPK(), a)
}
func updateAersopike() {
var a &record{}
// aerospike data would be stored in record struct
_, generationId, exrr := record.GetWithHeader()
if exrr !=nil {
panic(exrr)
}
if record.Counter == nil {
var b int = 1
record.Counter = &b
} else {
b := *record.Counter + 1
record.Counter = &b
}
// *request.Id is uniq ID
record.pendingTrans = append(record.pendingTrans, *request.Id)
newgen, result, err := record.MultiBinUpdate(*generationId)
if err != nil {
panic(err)
}
}
func (c *Aerospike) MultiBinUpdate(record Record, ttl, generation uint32) (*uint32, interface{}, error) {
key, err := c.key(record.GetPK(), record.TableName())
if err != nil {
return nil, nil, err
}
policy := c.getWritePolicy(UpdatePolicy)
policy.Expiration = ttl
policy.GenerationPolicy = aerospike.EXPECT_GEN_EQUAL
policy.Generation = generation
var Operations []*aerospike.Operation
bins := aerospike.Marshal(record, true)
for _, bin := range bins {
Operations = append(Operations, aerospike.PutOp(bin))
}
Operations = append(Operations, aerospike.GetOp())
var rec *aerospike.Record
if rec, err = c.client.Operate(policy, key, Operations...); err != nil {
return nil, nil, err
}
if rec == nil {
return nil, nil, errors.New("record is not updated")
}
return &rec.Generation, &rec.Bins, err
}
@Anil_Kumawat As far as I can tell using your code, the server and the client are working as expected. I need a complete program, not just a part of it, to understand what you are doing and where it’s going wrong.