Hello,
I'm trying to use an existing C++ piece of code with openresty, and was able to make it work by transforming it into a .so library with a C wrapper. So far so good. The code uses large data structure (around 5GB) and successfully integrated with openresty, as follows:
init_by_lua '
-- FFI module import
ffi = require("ffi")
-- Declaration of the C functions to be imported
ffi.cdef[[
void* ccode_instantiate(const char* xml);
void ccode_release(void* instance);
char* ccode_execute(void* instance,const char* text,int32_t limit,uint32_t range);
void free(void *ptr);
]]
-- Load the module globally
ffi.load("ccode",true)
-- Creation of the global class instance
instance = ffi.C.ccode_instantiate("${CCODE_HOME}/ccode.xml")
';
content_by_lua '
local args = ngx.req.get_uri_args()
local ref = args["ref"] -- ref#
if not ref then
return ngx.exit(ngx.HTTP_BAD_REQUEST)
end
local l = tonumber((args["l"] or "10")) -- limit
local r = tonumber((args["r"] or "1")) -- range
local json = ffi.C.ccode_execute(instance,ref,l,r)
ngx.say(ffi.string(json))
ffi.C.free(json) -- Frees the C string
';
Upon initialization, an XML is read, and external files are read to build the data structure in memory. This all works well, except I made one obvious design mistake apparently: the solution above is single threaded, because the main executable is global, and the workers just call it and have to wait for the current request to complete because requests are blocking. Obviously not what I want.
I think I know the solution, but wanted to confirm before I start refactoring, and I have a a few questions.
1. Can someone confirm that to fix this, I need to separate the data structure from the execution and have my C data structure instantiated globally, then call the executable from the workers that will leverage the global data structure?
2. What is the right way to implement a C++ (with C wrapper) data structure as a global resource (LUA tables are not going to work) to be called by C executables in workers?
3. Is this the best way to do this? Performance is of the essence so I am looking for the fastest performing solution.
4. I considered adding something like boost.asio to my code and leave it as a global resource (as it is now), but seems to me that this would defeat the purpose of leveraging openresty and my C++ code would then be pretty much self sufficient to service requests and could be used standalone, yet would lack the optimizations put in openresty as well as other facilities it provides.
Thanks for your help!