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