Skip to content

Latest commit

 

History

History
294 lines (230 loc) · 12.9 KB

client-experimentation.md

File metadata and controls

294 lines (230 loc) · 12.9 KB

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
Param type description Example value
tenant String specifies the tenants configs and contexts that will be loaded into the client at polling_interval from hostname mjos
polling_interval Duration specifies the time cac client waits before checking with the server for updates Duration::from_secs(5)
hostname String The URL of the superposition server https://superposition.example.com

Get Client

Get a client

Function definition
pub async fn get_client(
        tenant: String
    ) -> Result<Arc<Client>, String>
Params
Param type description Example value
tenant String specifies the tenant used during create_client mjos

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
Param type description Example value
context Value The context under which you want to resolve configs {"os": "android", "merchant": "juspay"}
toss i8 an integer that assigns your request to a variant 4

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
Param type description Example value
context Value The 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
Param type description Example value
Tenant String specifies the tenants configs and contexts that will be loaded into the client at polling_interval from hostname mjos
Interval Integer specifies the time cac client waits before checking with the server for updates Duration::from_secs(5)
Hostname String The URL of the superposition server https://superposition.example.com

Get Client

Get a client

Function definition
getExpClient :: Tenant -> IO (Either Error (ForeignPtr ExpClient))
Params
Param type description Example value
tenant String specifies the tenant used during create_client mjos

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
Param type description Example value
context String The context under which you want to resolve configs {"os": "android", "merchant": "juspay"}
toss Integer an integer that assigns your request to a variant 4

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
Param type description Example value
context Value The 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