Accessing C library from lua script in client.queryAggregate


#1

Hi all, I’m quite new to aerospike and lua scripting but I’ve been trying to read a bit around about:

-using secondary index in a RAM namespace (OK)

-query the namespaces via secondary index and passing to lua (with filter, aggregation and reduce) (OK)

-from lua, trying to call a C library (KO<—PROBLEM!!!)

I’m wondering if there are any howto that can help me to solve the problem (“how to call c code from lua aggregationfilter query”). I’ve been looking at the chapter 26 of the lua manual and at the entry at http://www.aerospike.com/docs/udf/knowing_lua.html but still have some issues I cannot figure it out. I suppose my problem is around the lua code or where/how i deploy the .so

Any hints are more than appreciate!

My snippet codes are:

java code is :

Statement stmt = new Statement();
LuaConfig.SourceDirectory = "udf";
File udfFile = new File("/home/angelo/aerospike-test/udf/testing.lua");
RegisterTask rt = client.register(null, udfFile.getPath(),udfFile.getName(), Language.LUA);
rt.waitTillComplete(100);
stmt.setNamespace("toothpicRAM");
stmt.setSetName("photo");      
stmt.setFilters(Filter.equal("ar", 1333));
ResultSet rs=client.queryAggregate(null, stmt, "testing", "testingC");

lua code (testing.lua):

local as = require "fromlua"
function testingC(stream)
info("**hello**")
--local x=as.dothis()
return stream
end

c code (fromlua.c):

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include <stdio.h>

static int myCfunc ( lua_State *L) 
{
printf ("Roses are Red\n");
return 0; 
}

static const struct luaL_reg  as_client [] = {
{"dothis", myCfunc},
{NULL,NULL} 
} ;

extern int luaopen_fromlua(lua_State *L)
{
luaL_register(L, "fromlua", as_client);
return 0; 
}

I compile the c code with: (I’ve tried also using the build_linux script in client-lua but result didn t change)

gcc -fPIC -o fromlua.so -shared fromlua.c -I/home/angelo/lua-5.1.4/src/

and copy to :

/opt/aerospike/usr/udf/lua/

I receive the error:

Exception in thread "main" com.aerospike.client.AerospikeException: org.luaj.vm2.LuaError: prova:1 module 'fromlua' not found: fromlua
    no field package.preload['fromlua']
    fromlua.lua
    no class 'fromlua'
stack traceback:
    prova:1: in main chunk
    [Java]: in ?
    at com.aerospike.client.query.QueryExecutor.checkForException(QueryExecutor.java:123)
    at com.aerospike.client.query.ResultSet.next(ResultSet.java:62)
    at org.polito.toothpic.RetrieveFromDB.prova(RetrieveFromDB.java:224)
    at org.polito.toothpic.RetrieveFromDB.main(RetrieveFromDB.java:282)
Caused by: org.luaj.vm2.LuaError: prova:1 module 'fromlua' not found: fromlua
    no field package.preload['fromlua']
    fromlua.lua
    no class 'fromlua'
stack traceback:
    prova:1: in main chunk
    [Java]: in ?
    at org.luaj.vm2.LuaValue.error(Unknown Source)
    at org.luaj.vm2.lib.PackageLib$require.call(Unknown Source)
    at org.luaj.vm2.LuaClosure.execute(Unknown Source)
    at org.luaj.vm2.LuaClosure.onInvoke(Unknown Source)
    at org.luaj.vm2.LuaClosure.invoke(Unknown Source)
    at org.luaj.vm2.LuaValue.invoke(Unknown Source)
    at com.aerospike.client.lua.LuaInstance.load(LuaInstance.java:105)
    at com.aerospike.client.query.QueryAggregateExecutor.runThreads(QueryAggregateExecutor.java:87)
    at com.aerospike.client.query.QueryAggregateExecutor.run(QueryAggregateExecutor.java:73)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

#2

I’ve been able to find a working example (from /opt/aerospike/examples/aql/lua_c ) and adapt it to my scenario. I’m really not able to track down my problem, probably several all together (folder udf in udfFile? moving local require to local function?)

anyway, for anybody interested, here a snippet codes:

java

Statement stmt = new Statement();
LuaConfig.SourceDirectory = "udf";
File udfFile = new File("udf/prova2.lua");
RegisterTask rt = client.register(null, udfFile.getPath(),udfFile.getName(), Language.LUA);
rt.waitTillComplete(100);       
stmt.setNamespace("toothpicRAM");
stmt.setSetName("photo");        
stmt.setFilters(Filter.equal("ar", 1333));
ResultSet rs=client.queryAggregate(null, stmt, "prova", "testingC", Value.get(5), Value.get("./Canon_Ixus55_0/Canon_Ixus55_0_2625.JPG_1600.JPG") );

lua code

local function aggregate_stats(lista, record)
list.append(lista, tostring(record['photoname']))
return lista
end

local function myfilter1(region)
return function(record)
local fromlua=require("fromlua")
local r= fromlua.go(5);
info(r)
return true
end
end

local function fmap(rec)
return rec['username']
end

local function reduce_stats(a,b)
return list.merge(a,b)
end

function testingC(stream, number, region)
local miofiltro = myfilter1(region)
return stream : filter(miofiltro) : aggregate(list{},aggregate_stats) : reduce(reduce_stats)
end

c code

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

static int go(lua_State * L) {
int rtrn = lua_tonumber(L, -1);   /* Get the single number arg */
lua_pushnumber(L,rtrn*rtrn);      /* square it and push the return */
return 1;
}

static const struct luaL_reg golib [] = {
{"go", go},
{NULL, NULL}
};

int luaopen_fromlua(lua_State * L) {
luaL_openlib(L, "go", golib, 0);
return 1;
}