Skip to main content

Experimentation Client Integration

This provides SDK to interact with experimentation-platform

Rust​

The rust client have a client factory that helps you work with multiple clients connected to different tenants

Client Factory Methods Reference​

Create Client​

Create a client in the factory. You can chose to use the result to check for errors faced by the Client Factory while creating your client, it is not mandatory to consume the Ok value.

Function definition​
pub async fn create_client(
tenant: String,
polling_interval: Duration,
hostname: String,
) -> Result<Arc<Client>, String>
Params​
ParamtypedescriptionExample value
tenantStringspecifies the tenants configs and contexts that will be loaded into the client at polling_interval from hostnamemjos
polling_intervalDurationspecifies the time cac client waits before checking with the server for updatesDuration::from_secs(5)
hostnameStringThe URL of the superposition serverhttps://superposition.example.com

Get Client​

Get a client

Function definition​
pub async fn get_client(
tenant: String
) -> Result<Arc<Client>, String>
Params​
ParamtypedescriptionExample value
tenantStringspecifies the tenant used during create_clientmjos

Example Implementation​

Below is the rust implementation to instantiate Experimentation client .

use superpostion_client as sp;

let tenants: Vec<String> = ["dev", "test"];
//You can create a clientFactory
for tenant in tenants {
rt::spawn(
sp::CLIENT_FACTORY
.create_client(tenant.to_string(),
poll_frequency,//How frequently you want to update config in secs
hostname.to_string()// superposition hostname
)
.await
.expect(format!("{}: Failed to acquire experimentation_client", tenant).as_str())
.clone()
.run_polling_updates(),
);
};
//You can extract an individual tenant's client from clientFactory
let tenant = "dev".to_owned();
let sp_client = sp::CLIENT_FACTORY
.get_client(tenant.clone())
.await
.map_err(|e| {
log::error!("{}: {}", tenant, e);
ErrorType::IgnoreError(format!("{}: Failed to get experimentation_client", tenant))
})?;


Experiment Client Methods Reference​

Run polling for updates from Superposition Service​

the Experimentation client polls for updates from the superposition service and loads any changes done on the server. This means that experiments changed in superposition are reflected on the client in the duration of polling_interval. run_polling_updates() should be run in a separate thread, as it does not terminate.

Function definition​
pub async fn run_polling_updates()

Get an applicable variant​

When experiments are running, you can get different variants of the experiment based on the toss value you provide. Superposition decides which bucket your request falls into based on this value, and returns an ID called the variantId. You can then include this in your CAC client request.

The toss can be a random number between -1 to 100. You can log the variantId so that your metrics can help you decide on a variant

Function Definition​
pub async fn get_applicable_variant(context: &Value, toss: i8) -> Vec<String>
Params​
ParamtypedescriptionExample value
contextValueThe context under which you want to resolve configs{"os": "android", "merchant": "juspay"}
tossi8an integer that assigns your request to a variant4

Get satisfied experiments​

Rather than just getting the variant ID, you can get the whole experiment(s) that are satisfying your context - rather than just the final result.

Function Definition​
pub async fn get_satisfied_experiments(context: &Value) -> Experiments
Params​
ParamtypedescriptionExample value
contextValueThe context under which you want to resolve configs{"os": "android", "merchant": "juspay"}

Get all running experiments​

Get all running experiments, why would you want to do this? We don't know. But you can.

Function Definition​
pub async fn get_running_experiments() -> Experiments

Haskell​

Experiment Client Methods Reference​

Create Client​

Create a client in the factory. You can chose to use the result to check for errors faced by the Client Factory while creating your client.

Function definition​
createExpClient:: Tenant -> Integer -> String -> IO (Either Error ())
Params​
ParamtypedescriptionExample value
TenantStringspecifies the tenants configs and contexts that will be loaded into the client at polling_interval from hostnamemjos
IntervalIntegerspecifies the time cac client waits before checking with the server for updatesDuration::from_secs(5)
HostnameStringThe URL of the superposition serverhttps://superposition.example.com

Get Client​

Get a client

Function definition​
getExpClient :: Tenant -> IO (Either Error (ForeignPtr ExpClient))
Params​
ParamtypedescriptionExample value
tenantStringspecifies the tenant used during create_clientmjos

Run polling for updates from Superposition Service​

the Experimentation client polls for updates from the superposition service and loads any changes done on the server. This means that experiments changed in superposition are reflected on the client in the duration of Interval. expStartPolling should be run in a separate thread, as it does not terminate.

Function definition​
expStartPolling :: Tenant -> IO ()

Get an applicable variant​

When experiments are running, you can get different variants of the experiment based on the toss value you provide. Superposition decides which bucket your request falls into based on this value, and returns an ID called the variantId. You can then include this in your CAC client request.

The toss can be a random number between -1 to 100. You can log the variantId so that your metrics can help you decide on a variant

Function Definition​
getApplicableVariants :: ForeignPtr ExpClient -> String -> Integer -> IO (Either Error String)
Params​
ParamtypedescriptionExample value
contextStringThe context under which you want to resolve configs{"os": "android", "merchant": "juspay"}
tossIntegeran integer that assigns your request to a variant4

Get satisfied experiments​

Rather than just getting the variant ID, you can get the whole experiment(s) that are satisfying your context - rather than just the final result.

Function Definition​
getSatisfiedExperiments :: ForeignPtr ExpClient -> String -> IO (Either Error Value)
Params​
ParamtypedescriptionExample value
contextValueThe context under which you want to resolve configs{"os": "android", "merchant": "juspay"}

Get all running experiments​

Get all running experiments, why would you want to do this? We don't know. But you can.

Function Definition​
getRunningExperiments :: ForeignPtr ExpClient -> IO (Either Error Value)

Sample Integration​

{-# LANGUAGE LambdaCase #-}
module Main (main) where

import Client (createExpClient, expStartPolling,
getApplicableVariants, getExpClient,
getRunningExperiments,
getSatisfiedExperiments)
import Control.Concurrent
import Prelude

main :: IO ()
main = do
createExpClient "dev" 10 "http://localhost:8080" >>= \case
Left err -> putStrLn err
Right _ -> pure ()
threadId <- forkIO (expStartPolling "dev")
print threadId
getExpClient "dev" >>= \case
Left err -> putStrLn err
Right client -> loop client
pure ()
where
loop client = do
runningExperiments <- getRunningExperiments client
satisfiedExperiments <- getSatisfiedExperiments client "{\"os\": \"android\", \"client\": \"1mg\"}"
variants <- getApplicableVariants client "{\"os\": \"android\", \"client\": \"1mg\"}" 9
print "Running experiments"
print runningExperiments
print "experiments that satisfy context"
print satisfiedExperiments
print "variant ID applied"
print variants
-- threadDelay 10000000
loop client