Skip to content

Commit b66b93a

Browse files
committed
feat: adding lua cac and experimentation client wrapper
1 parent 710c69d commit b66b93a

File tree

2 files changed

+214
-0
lines changed

2 files changed

+214
-0
lines changed

clients/lua/cacclient/client.lua

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
local ffi = require("ffi")
2+
local platform = string.lower(jit.os)
3+
4+
local file_name = "libcac_client.dylib"
5+
-- if platform == "osx" then
6+
-- file_name = "libcac_client.dylib"
7+
-- elseif platform == "linux" then
8+
-- file_name = "libcac_client.so"
9+
-- elseif platform == "windows" then
10+
-- file_name = "libcac_client.dll"
11+
-- else
12+
-- error("Unsupported platform: " .. platform)
13+
-- end
14+
15+
local lib_path = "/Users/namit.goel/Desktop/repos/namit_superposition/superposition/clients/lua/libcac_client.dylib"
16+
17+
ffi.cdef[[
18+
int cac_new_client(const char* tenant_name, int polling_frequency, const char* cac_host_name);
19+
const char* cac_get_client(const char* tenant_name);
20+
void cac_start_polling_update(const char* tenant_name);
21+
void cac_free_client(const char* client_ptr);
22+
const char* cac_last_error_message();
23+
int cac_last_error_length();
24+
const char* cac_get_config(const char* client_ptr, const char* filter_query, const char* filter_prefix);
25+
void cac_free_string(const char* string);
26+
const char* cac_get_last_modified(const char* client_ptr);
27+
const char* cac_get_resolved_config(const char* client_ptr, const char* query, const char* filter_keys, const char* merge_strategy);
28+
const char* cac_get_default_config(const char* client_ptr, const char* filter_keys);
29+
]]
30+
31+
local rust_lib = ffi.load(lib_path)
32+
33+
local CacClient = {}
34+
CacClient.__index = CacClient
35+
36+
function CacClient:new(tenant_name, polling_frequency, cac_host_name)
37+
assert(tenant_name and #tenant_name > 0, "tenantName cannot be null or empty")
38+
assert(cac_host_name and #cac_host_name > 0, "cacHostName cannot be null or empty")
39+
40+
local self = setmetatable({}, CacClient)
41+
self.tenant = tenant_name
42+
self.polling_frequency = polling_frequency
43+
self.cac_host_name = cac_host_name
44+
return self
45+
end
46+
47+
function CacClient:get_cac_last_error_message()
48+
return ffi.string(rust_lib.cac_last_error_message())
49+
end
50+
51+
function CacClient:get_cac_last_error_length()
52+
return rust_lib.cac_last_error_length()
53+
end
54+
55+
function CacClient:get_cac_client()
56+
return ffi.string(rust_lib.cac_get_client(self.tenant))
57+
end
58+
59+
function CacClient:create_new_cac_client()
60+
local resp = rust_lib.cac_new_client(self.tenant, self.polling_frequency, self.cac_host_name)
61+
if resp == 1 then
62+
local error_message = self:get_cac_last_error_message()
63+
print("Some Error Occur while creating new client ", error_message)
64+
end
65+
return resp
66+
end
67+
68+
function CacClient:start_cac_polling_update()
69+
-- LuaJIT does not have built-in threading support.
70+
-- You need to use a library like luaproc or lua-llthreads for threading.
71+
-- For simplicity, we'll run it directly (not actually threaded)
72+
rust_lib.cac_start_polling_update(self.tenant)
73+
end
74+
75+
function CacClient:get_cac_config(filter_query, filter_prefix)
76+
local client_ptr = self:get_cac_client()
77+
return ffi.string(rust_lib.cac_get_config(client_ptr, filter_query, filter_prefix))
78+
end
79+
80+
function CacClient:free_cac_client(client_ptr)
81+
rust_lib.cac_free_client(client_ptr)
82+
end
83+
84+
function CacClient:free_cac_string(string)
85+
rust_lib.cac_free_string(string)
86+
end
87+
88+
function CacClient:get_last_modified()
89+
return ffi.string(rust_lib.cac_get_last_modified(self:get_cac_client()))
90+
end
91+
92+
function CacClient:get_resolved_config(query, filter_keys, merge_strategy)
93+
return ffi.string(rust_lib.cac_get_resolved_config(self:get_cac_client(), query, filter_keys, merge_strategy))
94+
end
95+
96+
function CacClient:get_default_config(filter_keys)
97+
return ffi.string(rust_lib.cac_get_default_config(self:get_cac_client(), filter_keys))
98+
end
99+
100+
-- Example usage:
101+
local tenant_name = "dev"
102+
local polling_frequency = 1
103+
local cac_host_name = "http://localhost:8080"
104+
105+
local client = CacClient:new(tenant_name, polling_frequency, cac_host_name)
106+
local response = client:create_new_cac_client()
107+
print(client:get_cac_config("{}", ""))

clients/lua/expclient/client.lua

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
local ffi = require("ffi")
2+
local platform = string.lower(jit.os)
3+
4+
local file_name
5+
if platform == "osx" then
6+
file_name = "libexperimentation_client.dylib"
7+
elseif platform == "linux" then
8+
file_name = "libexperimentation_client.so"
9+
elseif platform == "windows" then
10+
file_name = "libexperimentation_client.dll"
11+
else
12+
error("Unsupported platform: " .. platform)
13+
end
14+
15+
local lib_path = "/Users/namit.goel/Desktop/repos/namit_superposition/superposition/clients/lua/expclient/libexperimentation_client.dylib"
16+
17+
ffi.cdef[[
18+
int expt_new_client(const char* tenant_name, int polling_frequency, const char* cac_host_name);
19+
void expt_start_polling_update(const char* tenant_name);
20+
const char* expt_get_client(const char* tenant_name);
21+
const char* expt_get_applicable_variant(const char* client_ptr, const char* context, int toss);
22+
const char* expt_get_satisfied_experiments(const char* client_ptr, const char* context, const char* filter_prefix);
23+
const char* expt_get_filtered_satisfied_experiments(const char* client_ptr, const char* context, const char* filter_prefix);
24+
const char* expt_get_running_experiments(const char* client_ptr);
25+
void expt_free_string(const char* string);
26+
const char* expt_last_error_message();
27+
int expt_last_error_length();
28+
void expt_free_client(const char* client_ptr);
29+
]]
30+
31+
local rust_lib = ffi.load(lib_path)
32+
33+
local ExperimentationClient = {}
34+
ExperimentationClient.__index = ExperimentationClient
35+
36+
function ExperimentationClient:new(tenant_name, polling_frequency, cac_host_name)
37+
assert(tenant_name and #tenant_name > 0, "tenantName cannot be null or empty")
38+
assert(cac_host_name and #cac_host_name > 0, "cacHostName cannot be null or empty")
39+
40+
local self = setmetatable({}, ExperimentationClient)
41+
self.tenant = tenant_name
42+
self.polling_frequency = polling_frequency
43+
self.cac_host_name = cac_host_name
44+
return self
45+
end
46+
47+
function ExperimentationClient:get_experimentation_last_error_message()
48+
return ffi.string(rust_lib.expt_last_error_message())
49+
end
50+
51+
function ExperimentationClient:create_new_experimentation_client()
52+
local resp_code = rust_lib.expt_new_client(self.tenant, self.polling_frequency, self.cac_host_name)
53+
if resp_code == 1 then
54+
local error_message = self:get_experimentation_last_error_message()
55+
print("Some error occurred while creating new experimentation client:", error_message)
56+
error("Client Creation Error")
57+
end
58+
return resp_code
59+
end
60+
61+
function ExperimentationClient:get_experimentation_client()
62+
return ffi.string(rust_lib.expt_get_client(self.tenant))
63+
end
64+
65+
function ExperimentationClient:get_running_experiments()
66+
return ffi.string(rust_lib.expt_get_running_experiments(self:get_experimentation_client()))
67+
end
68+
69+
function ExperimentationClient:free_string(string)
70+
rust_lib.expt_free_string(string)
71+
end
72+
73+
function ExperimentationClient:start_experimentation_polling_update()
74+
-- LuaJIT does not have built-in threading support.
75+
-- You need to use a library like luaproc or lua-llthreads for threading.
76+
-- For simplicity, we'll run it directly (not actually threaded)
77+
rust_lib.expt_start_polling_update(self.tenant)
78+
end
79+
80+
function ExperimentationClient:get_experimentation_last_error_length()
81+
return rust_lib.expt_last_error_length()
82+
end
83+
84+
function ExperimentationClient:free_experimentation_client()
85+
rust_lib.expt_free_client(self:get_experimentation_client())
86+
end
87+
88+
function ExperimentationClient:get_filtered_satisfied_experiments(context, filter_prefix)
89+
return ffi.string(rust_lib.expt_get_filtered_satisfied_experiments(self:get_experimentation_client(), context, filter_prefix))
90+
end
91+
92+
function ExperimentationClient:get_applicable_variant(context, toss)
93+
return ffi.string(rust_lib.expt_get_applicable_variant(self:get_experimentation_client(), context, toss))
94+
end
95+
96+
function ExperimentationClient:get_satisfied_experiments(context, filter_prefix)
97+
return ffi.string(rust_lib.expt_get_satisfied_experiments(self:get_experimentation_client(), context, filter_prefix))
98+
end
99+
100+
-- Example usage:
101+
local tenant_name = "dev"
102+
local polling_frequency = 1
103+
local cac_host_name = "http://localhost:8080"
104+
105+
local client = ExperimentationClient:new(tenant_name, polling_frequency, cac_host_name)
106+
local response = client:create_new_experimentation_client()
107+
print(response)

0 commit comments

Comments
 (0)