Skip to content

Commit

Permalink
feat: adding lua cac and experimentation client wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
namitgoel committed Aug 1, 2024
1 parent 710c69d commit b66b93a
Show file tree
Hide file tree
Showing 2 changed files with 214 additions and 0 deletions.
107 changes: 107 additions & 0 deletions clients/lua/cacclient/client.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
local ffi = require("ffi")
local platform = string.lower(jit.os)

local file_name = "libcac_client.dylib"
-- if platform == "osx" then
-- file_name = "libcac_client.dylib"
-- elseif platform == "linux" then
-- file_name = "libcac_client.so"
-- elseif platform == "windows" then
-- file_name = "libcac_client.dll"
-- else
-- error("Unsupported platform: " .. platform)
-- end

local lib_path = "/Users/namit.goel/Desktop/repos/namit_superposition/superposition/clients/lua/libcac_client.dylib"

ffi.cdef[[
int cac_new_client(const char* tenant_name, int polling_frequency, const char* cac_host_name);
const char* cac_get_client(const char* tenant_name);
void cac_start_polling_update(const char* tenant_name);
void cac_free_client(const char* client_ptr);
const char* cac_last_error_message();
int cac_last_error_length();
const char* cac_get_config(const char* client_ptr, const char* filter_query, const char* filter_prefix);
void cac_free_string(const char* string);
const char* cac_get_last_modified(const char* client_ptr);
const char* cac_get_resolved_config(const char* client_ptr, const char* query, const char* filter_keys, const char* merge_strategy);
const char* cac_get_default_config(const char* client_ptr, const char* filter_keys);
]]

local rust_lib = ffi.load(lib_path)

local CacClient = {}
CacClient.__index = CacClient

function CacClient:new(tenant_name, polling_frequency, cac_host_name)
assert(tenant_name and #tenant_name > 0, "tenantName cannot be null or empty")
assert(cac_host_name and #cac_host_name > 0, "cacHostName cannot be null or empty")

local self = setmetatable({}, CacClient)
self.tenant = tenant_name
self.polling_frequency = polling_frequency
self.cac_host_name = cac_host_name
return self
end

function CacClient:get_cac_last_error_message()
return ffi.string(rust_lib.cac_last_error_message())
end

function CacClient:get_cac_last_error_length()
return rust_lib.cac_last_error_length()
end

function CacClient:get_cac_client()
return ffi.string(rust_lib.cac_get_client(self.tenant))
end

function CacClient:create_new_cac_client()
local resp = rust_lib.cac_new_client(self.tenant, self.polling_frequency, self.cac_host_name)
if resp == 1 then
local error_message = self:get_cac_last_error_message()
print("Some Error Occur while creating new client ", error_message)
end
return resp
end

function CacClient:start_cac_polling_update()
-- LuaJIT does not have built-in threading support.
-- You need to use a library like luaproc or lua-llthreads for threading.
-- For simplicity, we'll run it directly (not actually threaded)
rust_lib.cac_start_polling_update(self.tenant)
end

function CacClient:get_cac_config(filter_query, filter_prefix)
local client_ptr = self:get_cac_client()
return ffi.string(rust_lib.cac_get_config(client_ptr, filter_query, filter_prefix))
end

function CacClient:free_cac_client(client_ptr)
rust_lib.cac_free_client(client_ptr)
end

function CacClient:free_cac_string(string)
rust_lib.cac_free_string(string)
end

function CacClient:get_last_modified()
return ffi.string(rust_lib.cac_get_last_modified(self:get_cac_client()))
end

function CacClient:get_resolved_config(query, filter_keys, merge_strategy)
return ffi.string(rust_lib.cac_get_resolved_config(self:get_cac_client(), query, filter_keys, merge_strategy))
end

function CacClient:get_default_config(filter_keys)
return ffi.string(rust_lib.cac_get_default_config(self:get_cac_client(), filter_keys))
end

-- Example usage:
local tenant_name = "dev"
local polling_frequency = 1
local cac_host_name = "http://localhost:8080"

local client = CacClient:new(tenant_name, polling_frequency, cac_host_name)
local response = client:create_new_cac_client()
print(client:get_cac_config("{}", ""))
107 changes: 107 additions & 0 deletions clients/lua/expclient/client.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
local ffi = require("ffi")
local platform = string.lower(jit.os)

local file_name
if platform == "osx" then
file_name = "libexperimentation_client.dylib"
elseif platform == "linux" then
file_name = "libexperimentation_client.so"
elseif platform == "windows" then
file_name = "libexperimentation_client.dll"
else
error("Unsupported platform: " .. platform)
end

local lib_path = "/Users/namit.goel/Desktop/repos/namit_superposition/superposition/clients/lua/expclient/libexperimentation_client.dylib"

ffi.cdef[[
int expt_new_client(const char* tenant_name, int polling_frequency, const char* cac_host_name);
void expt_start_polling_update(const char* tenant_name);
const char* expt_get_client(const char* tenant_name);
const char* expt_get_applicable_variant(const char* client_ptr, const char* context, int toss);
const char* expt_get_satisfied_experiments(const char* client_ptr, const char* context, const char* filter_prefix);
const char* expt_get_filtered_satisfied_experiments(const char* client_ptr, const char* context, const char* filter_prefix);
const char* expt_get_running_experiments(const char* client_ptr);
void expt_free_string(const char* string);
const char* expt_last_error_message();
int expt_last_error_length();
void expt_free_client(const char* client_ptr);
]]

local rust_lib = ffi.load(lib_path)

local ExperimentationClient = {}
ExperimentationClient.__index = ExperimentationClient

function ExperimentationClient:new(tenant_name, polling_frequency, cac_host_name)
assert(tenant_name and #tenant_name > 0, "tenantName cannot be null or empty")
assert(cac_host_name and #cac_host_name > 0, "cacHostName cannot be null or empty")

local self = setmetatable({}, ExperimentationClient)
self.tenant = tenant_name
self.polling_frequency = polling_frequency
self.cac_host_name = cac_host_name
return self
end

function ExperimentationClient:get_experimentation_last_error_message()
return ffi.string(rust_lib.expt_last_error_message())
end

function ExperimentationClient:create_new_experimentation_client()
local resp_code = rust_lib.expt_new_client(self.tenant, self.polling_frequency, self.cac_host_name)
if resp_code == 1 then
local error_message = self:get_experimentation_last_error_message()
print("Some error occurred while creating new experimentation client:", error_message)
error("Client Creation Error")
end
return resp_code
end

function ExperimentationClient:get_experimentation_client()
return ffi.string(rust_lib.expt_get_client(self.tenant))
end

function ExperimentationClient:get_running_experiments()
return ffi.string(rust_lib.expt_get_running_experiments(self:get_experimentation_client()))
end

function ExperimentationClient:free_string(string)
rust_lib.expt_free_string(string)
end

function ExperimentationClient:start_experimentation_polling_update()
-- LuaJIT does not have built-in threading support.
-- You need to use a library like luaproc or lua-llthreads for threading.
-- For simplicity, we'll run it directly (not actually threaded)
rust_lib.expt_start_polling_update(self.tenant)
end

function ExperimentationClient:get_experimentation_last_error_length()
return rust_lib.expt_last_error_length()
end

function ExperimentationClient:free_experimentation_client()
rust_lib.expt_free_client(self:get_experimentation_client())
end

function ExperimentationClient:get_filtered_satisfied_experiments(context, filter_prefix)
return ffi.string(rust_lib.expt_get_filtered_satisfied_experiments(self:get_experimentation_client(), context, filter_prefix))
end

function ExperimentationClient:get_applicable_variant(context, toss)
return ffi.string(rust_lib.expt_get_applicable_variant(self:get_experimentation_client(), context, toss))
end

function ExperimentationClient:get_satisfied_experiments(context, filter_prefix)
return ffi.string(rust_lib.expt_get_satisfied_experiments(self:get_experimentation_client(), context, filter_prefix))
end

-- Example usage:
local tenant_name = "dev"
local polling_frequency = 1
local cac_host_name = "http://localhost:8080"

local client = ExperimentationClient:new(tenant_name, polling_frequency, cac_host_name)
local response = client:create_new_experimentation_client()
print(response)

0 comments on commit b66b93a

Please sign in to comment.