-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: adddig ruby client for cac and experimentation system
- Loading branch information
1 parent
73b5dbc
commit 5b144fe
Showing
2 changed files
with
222 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
require 'ffi' | ||
require 'os' | ||
|
||
module MergeStrategy | ||
REPLACE = "REPLACE" | ||
MERGE = "MERGE" | ||
end | ||
|
||
module CACLib | ||
extend FFI::Library | ||
|
||
extension = "dylib" | ||
if OS.windows? | ||
extension = "dll" | ||
elsif OS.mac? | ||
extension = "dylib" | ||
else | ||
extension = "so" | ||
end | ||
libpath = File.expand_path(File.join(__dir__, "/../../../target/debug/libcac_client.#{extension}")) | ||
ffi_lib libpath | ||
|
||
class ArcClient < FFI::Struct | ||
layout :dummy, :int | ||
end | ||
|
||
# Attach C functions | ||
attach_function :cac_last_error_length, [], :int | ||
attach_function :cac_last_error_message, [], :string | ||
attach_function :cac_free_string, [:pointer], :void | ||
attach_function :cac_new_client, [:string, :ulong, :string], :int | ||
attach_function :cac_start_polling_update, [:string], :void | ||
attach_function :cac_free_client, [ArcClient.by_ref], :void | ||
attach_function :cac_get_client, [:string], ArcClient.by_ref | ||
attach_function :cac_get_last_modified, [ArcClient.by_ref], :string | ||
attach_function :cac_get_config, [ArcClient.by_ref, :string, :string], :string | ||
attach_function :cac_get_resolved_config, [ArcClient.by_ref, :string, :string, :string], :string | ||
attach_function :cac_get_default_config, [ArcClient.by_ref, :string], :string | ||
end | ||
|
||
class CACClient | ||
def initialize(tenant, update_frequency, hostname) | ||
result = CACLib.cac_new_client(tenant, update_frequency, hostname) | ||
raise "Failed to create client: #{last_error_message}" if result != 0 | ||
@client = CACLib.cac_get_client(tenant) | ||
raise "Failed to get client: #{last_error_message}" if @client.null? | ||
@tenant = tenant | ||
end | ||
|
||
def start_polling_update | ||
CACLib.cac_start_polling_update(@tenant) | ||
end | ||
|
||
def get_last_modified | ||
result = CACLib.cac_get_last_modified(@client) | ||
raise "Failed to get last modified time: #{last_error_message}" if result.nil? | ||
result | ||
end | ||
|
||
def get_config(filter_query, filter_prefix) | ||
result = CACLib.cac_get_config(@client, filter_query, filter_prefix) | ||
puts "Filter query : #{result}" | ||
raise "Failed to get config: #{last_error_message}" if result.nil? | ||
result | ||
ensure | ||
# CACLib.cac_free_string(result) if result // No need to free as its handled internally | ||
end | ||
|
||
def get_resolved_config(query, filter_keys, merge_strategy) | ||
result = CACLib.cac_get_resolved_config(@client, query, filter_keys, merge_strategy) | ||
raise "Failed to get resolved config: #{last_error_message}" if result.nil? | ||
result | ||
end | ||
|
||
def get_default_config(filter_keys) | ||
result = CACLib.cac_get_default_config(@client, filter_keys) | ||
raise "Failed to get default config: #{last_error_message}" if result.nil? | ||
result | ||
end | ||
|
||
def last_error_message | ||
CACLib.cac_last_error_message | ||
end | ||
|
||
def close | ||
CACLib.cac_free_client(@client) unless @client.null? | ||
end | ||
end | ||
|
||
# Example usage | ||
begin | ||
client = CACClient.new("dev", 60000, "http://localhost:8080") | ||
puts "Starting the client" | ||
|
||
client.start_polling_update | ||
|
||
puts "Last Modified: #{client.get_last_modified}" | ||
|
||
config = client.get_config('{"country": "India"}', 'country') | ||
puts "Config: #{config}" | ||
|
||
resolved_config = client.get_resolved_config('{"country": "India"}', | ||
"country_image_url,hyperpay_version", MergeStrategy::REPLACE) | ||
puts "Resolved Config: #{resolved_config}" | ||
|
||
default_config = client.get_default_config("your_filter_keys") | ||
puts "Default Config: #{default_config}" | ||
rescue StandardError => e | ||
puts "Error: #{e.message}" | ||
ensure | ||
client.close if client | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
require 'ffi' | ||
require 'os' | ||
require 'thread' | ||
|
||
module ExpClientLib | ||
extend FFI::Library | ||
extension = if OS.windows? | ||
"dll" | ||
elsif OS.mac? | ||
"dylib" | ||
else | ||
"so" | ||
end | ||
libpath = File.expand_path(File.join(__dir__, "/../../../target/debug/libexperimentation_client.#{extension}")) | ||
ffi_lib libpath | ||
|
||
attach_function :expt_new_client, [:string, :int, :string], :int | ||
attach_function :expt_start_polling_update, [:string], :void | ||
attach_function :expt_get_client, [:string], :string | ||
attach_function :expt_get_applicable_variant, [:string, :string, :int], :string | ||
attach_function :expt_get_satisfied_experiments, [:string, :string, :string], :string | ||
attach_function :expt_get_filtered_satisfied_experiments, [:string, :string, :string], :string | ||
attach_function :expt_get_running_experiments, [:string], :string | ||
attach_function :expt_free_string, [:string], :void | ||
attach_function :expt_last_error_message, [], :string | ||
attach_function :expt_last_error_length, [], :int | ||
attach_function :expt_free_client, [:string], :void | ||
|
||
class ExperimentationClient | ||
def initialize(tenant_name, polling_frequency, cac_host_name) | ||
@tenant = tenant_name | ||
@polling_frequency = polling_frequency | ||
@cac_host_name = cac_host_name | ||
@polling_thread = nil | ||
end | ||
|
||
def get_experimentation_last_error_message | ||
ExpClientLib.expt_last_error_message | ||
end | ||
|
||
def create_new_experimentation_client | ||
resp_code = ExpClientLib.expt_new_client(@tenant, @polling_frequency, @cac_host_name) | ||
if resp_code == 1 | ||
error_message = get_experimentation_last_error_message | ||
puts "Some Error Occurred while creating new experimentation client: #{error_message}" | ||
raise "Client Creation Error" | ||
end | ||
resp_code | ||
end | ||
|
||
def get_experimentation_client | ||
ExpClientLib.expt_get_client(@tenant) | ||
end | ||
|
||
def get_running_experiments | ||
client_ptr = get_experimentation_client | ||
ExpClientLib.expt_get_running_experiments(client_ptr) | ||
end | ||
|
||
def free_string(str) | ||
ExpClientLib.expt_free_string(str) | ||
end | ||
|
||
def start_experimentation_polling_update | ||
@polling_thread = Thread.new do | ||
ExpClientLib.expt_start_polling_update(@tenant) | ||
end | ||
end | ||
|
||
def get_experimentation_last_error_length | ||
ExpClientLib.expt_last_error_length | ||
end | ||
|
||
def free_experimentation_client | ||
ExpClientLib.expt_free_client(get_experimentation_client) | ||
end | ||
|
||
def get_filtered_satisfied_experiments(context, filter_prefix) | ||
ExpClientLib.expt_get_filtered_satisfied_experiments( | ||
get_experimentation_client, context, filter_prefix | ||
) | ||
end | ||
|
||
def get_applicable_variant(context, toss) | ||
ExpClientLib.expt_get_applicable_variant( | ||
get_experimentation_client, context, toss | ||
) | ||
end | ||
|
||
def get_satisfied_experiments(context, filter_prefix) | ||
ExpClientLib.expt_get_satisfied_experiments( | ||
get_experimentation_client, context, filter_prefix | ||
) | ||
end | ||
end | ||
end | ||
|
||
# Example usage | ||
begin | ||
client = ExpClientLib::ExperimentationClient.new('dev', 10, 'http://localhost:8080') | ||
client.create_new_experimentation_client | ||
puts "Running experiments :: #{client.get_running_experiments}" | ||
client.start_experimentation_polling_update | ||
puts "After starting the polling" | ||
puts "Running get_filtered_satisfied_experiments :: #{client.get_filtered_satisfied_experiments("juspay", "key1")}" | ||
rescue StandardError => e | ||
puts "Error: #{e.message}" | ||
ensure | ||
client.close if client | ||
end |