Help using list in UDF


#1

Hi,

I’m trying to maintain a list of strings.

This is my code when I create a record:

local function initRecord(record)
    if(not aerospike:exists(record)) then
        record.backlog = list()
        for i=1,3, 1 do
            local val = 'n/a'
            record.backlog[i] = val
        end
        local rc = 0;
        rc = aerospike:create(record)
        if( rc == nil or record == nil ) then
            error("Could not create record")
        end
    end
end

And it works fine (bins:(backlog:[n/a, n/a, n/a]), but when I want to modify this list, it does not seam to do anything with any of the following methods:

local function pushToBacklog(record, requestId)
    list.append(record.backlog, requestId)
    aerospike:update(record)
end

or

local function pushToBacklog(record, requestId)
    record.backlog[1] = requestId
    aerospike:update(record)
end

Any idea?


#2

Hi

Try adding the following code just before you call aerospike:update(…)

record.backlog = record.backlog

It seems a bit strange, but I’ll explain. To Lua, the Aerospike record “looks” like a table, and you can operate on it like you would a table; cstivers78 did a great job on implementing this.

Here is the secret: For Aerospike to know that the bin needs to be updated, the bin needs to be “touched”. You are adding to a list in the UDF, which is OK, but the Bin containing a pointer to the list has not been modified, or “touched”. So assigning the bin to itself should work.

Regards,

Peter


#3

Thanks! This works fine now.


#4

Hi Peter, sorry for reviving this thread. For improvement of DX, wouldn’t it be possible that all cdt-list write ops automatically touch the bin / mark it as dirty? It’s quite counter-intuitive to lua beginners and can potentially cost developers hours to debug with the few examples available (none explaining the need for local bincopy = rec.binname).

With the new cdt list ops, it’s also unclear if that trick does a complete copy of the list instead of operating just on the elements changed (especially for in-memory namespace) - which would degrade performance a lot (though not a priority IMHO)! When benchmarking in-memory vs. ssd namespace (record udf using cdt list ops), I saw virtually no difference which I’d interpret as it’s actually doing a clone or the record lock starts throttling at 6000 record-udf apply’s/second.

Never saw the need for this with any other program using lua, too.

Cheers, Manuel