Skip to content

Commit

Permalink
feat: Use Variant type in model
Browse files Browse the repository at this point in the history
  • Loading branch information
ayushjain17 committed Sep 20, 2024
1 parent 1a54fd2 commit 3502b86
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 82 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ members = [
"examples/experimentation_client_integration_example",
"examples/cac_client_integration_example",
"examples/superposition-demo-app",
"crates/superposition_macros"
"crates/superposition_macros",
"crates/superposition_proc_macros",
]

[[workspace.metadata.leptos]]
Expand Down Expand Up @@ -69,7 +70,7 @@ leptos_actix = { version = "0.6.11" }
thiserror = { version = "1.0.57" }
leptos-use = "0.10.3"
mime = "0.3.17"
aws-sdk-kms = {version = "1.38.0"}
aws-sdk-kms = { version = "1.38.0" }
aws-config = { version = "1.1.7", features = ["behavior-version-latest"] }

[workspace.lints.clippy]
Expand Down
3 changes: 2 additions & 1 deletion cog.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pre_bump_hooks = []

pre_package_bump_hooks = [
"echo 'upgrading {{package}}' to {{version}}",
"cargo set-version --package {{package}} {{version}}"
"cargo set-version --package {{package}} {{version}}",
]

post_package_bump_hooks = []
Expand All @@ -36,3 +36,4 @@ superposition_types = { path = "crates/superposition_types" }
js_client = { path = "clients/js" }
haskell_client = { path = "clients/haskell" }
superposition_macros = { path = "crates/superposition_macros" }
superposition_proc_macros = { path = "crates/superposition_proc_macros" }
1 change: 1 addition & 0 deletions crates/experimentation_platform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ superposition_types = { path = "../superposition_types" }
reqwest = { workspace = true }
anyhow = { workspace = true }
superposition_macros = { path = "../superposition_macros" }
superposition_proc_macros = { path = "../superposition_proc_macros" }
jsonlogic = { workspace = true }

[features]
Expand Down
57 changes: 14 additions & 43 deletions crates/experimentation_platform/src/api/experiments/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ use diesel::{
r2d2::{ConnectionManager, PooledConnection},
ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl,
};

use service_utils::helpers::{construct_request_headers, generate_snowflake_id, request};

use reqwest::{Method, Response, StatusCode};
use serde_json::{json, Map, Value};
use service_utils::helpers::{construct_request_headers, generate_snowflake_id, request};
use service_utils::service::types::{
AppHeader, AppState, CustomHeaders, DbConnection, Tenant,
};
Expand All @@ -31,23 +30,18 @@ use super::{
validate_experiment, validate_override_keys,
},
types::{
AuditQueryFilters, ConcludeExperimentRequest, ContextAction, ContextBulkResponse,
ContextMoveReq, ContextPutReq, ExperimentCreateRequest, ExperimentCreateResponse,
ExperimentResponse, ExperimentsResponse, ListFilters, OverrideKeysUpdateRequest,
RampRequest, Variant,
ApplicableVariantsQuery, AuditQueryFilters, ConcludeExperimentRequest,
ContextAction, ContextBulkResponse, ContextMoveReq, ContextPutReq,
ExperimentCreateRequest, ExperimentCreateResponse, ExperimentResponse,
ExperimentsResponse, ListFilters, OverrideKeysUpdateRequest, RampRequest,
},
};

use crate::{
api::experiments::types::ApplicableVariantsQuery,
db::{
models::{EventLog, Experiment, ExperimentStatusType},
schema::{event_log::dsl as event_log, experiments::dsl as experiments},
},
use crate::db::{
models::{EventLog, Experiment, ExperimentStatusType, Variant, Variants},
schema::{event_log::dsl as event_log, experiments::dsl as experiments},
};

use serde_json::{json, Map, Value};

pub fn endpoints(scope: Scope) -> Scope {
scope
.service(get_audit_logs)
Expand Down Expand Up @@ -275,7 +269,7 @@ async fn create(
traffic_percentage: 0,
status: ExperimentStatusType::CREATED,
context: Value::Object(req.context.clone().into_inner().into()),
variants: serde_json::to_value(variants).unwrap(),
variants: Variants::new(variants),
last_modified_by: user.get_email(),
chosen_variant: None,
};
Expand Down Expand Up @@ -348,17 +342,9 @@ pub async fn conclude(
})?;

let mut operations: Vec<ContextAction> = vec![];
let experiment_variants: Vec<Variant> = serde_json::from_value(experiment.variants)
.map_err(|err| {
log::error!(
"failed parse eixisting experiment variant while concluding with error: {}",
err
);
unexpected_error!("Something went wrong, failed to conclude experiment")
})?;

let mut is_valid_winner_variant = false;
for variant in experiment_variants {
for variant in experiment.variants.into_inner() {
let context_id = variant.context_id.ok_or_else(|| {
log::error!("context id not available for variant {:?}", variant.id);
unexpected_error!("Something went wrong, failed to conclude experiment")
Expand Down Expand Up @@ -472,10 +458,7 @@ async fn get_applicable_variants(
for exp in experiments {
if let Some(v) = decide_variant(
exp.traffic_percentage as u8,
serde_json::from_value(exp.variants).map_err(|e| {
log::error!("Unable to parse variants from DB {e}");
unexpected_error!("Something went wrong.")
})?,
exp.variants.into_inner(),
query_data.toss,
)
.map_err(|e| {
Expand Down Expand Up @@ -594,15 +577,7 @@ async fn ramp(

let old_traffic_percentage = experiment.traffic_percentage as u8;
let new_traffic_percentage = req.traffic_percentage as u8;
let experiment_variants: Vec<Variant> = serde_json::from_value(experiment.variants)
.map_err(|e| {
log::error!(
"failed to parse existing experiment variants while ramping {}",
e
);
unexpected_error!("Something went wrong, failed to ramp traffic percentage")
})?;
let variants_count = experiment_variants.len() as u8;
let variants_count = experiment.variants.into_inner().len() as u8;
let max = 100 / variants_count;

if matches!(experiment.status, ExperimentStatusType::CONCLUDED) {
Expand Down Expand Up @@ -666,11 +641,7 @@ async fn update_overrides(
));
}

let experiment_variants: Vec<Variant> = serde_json::from_value(experiment.variants)
.map_err(|err| {
log::error!("failed to parse exisiting variants with error {}", err);
unexpected_error!("Something went wrong, failed to update experiment")
})?;
let experiment_variants: Vec<Variant> = experiment.variants.into_inner();

let id_to_existing_variant: HashMap<String, &Variant> = HashMap::from_iter(
experiment_variants
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use super::types::{Variant, VariantType};
use crate::db::models::{Experiment, ExperimentStatusType};
use diesel::pg::PgConnection;
use diesel::{BoolExpressionMethods, ExpressionMethods, QueryDsl, RunQueryDsl};
use serde_json::{Map, Value};
Expand All @@ -9,6 +7,8 @@ use std::collections::HashSet;
use superposition_macros::{bad_argument, unexpected_error};
use superposition_types::{result as superposition, Condition, Exp, Overrides};

use crate::db::models::{Experiment, ExperimentStatusType, Variant, VariantType};

pub fn check_variant_types(variants: &Vec<Variant>) -> superposition::Result<()> {
let mut experimental_variant_cnt = 0;
let mut control_variant_cnt = 0;
Expand Down
21 changes: 3 additions & 18 deletions crates/experimentation_platform/src/api/experiments/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,7 @@ use serde_json::{Map, Value};
use service_utils::helpers::deserialize_stringified_list;
use superposition_types::{Condition, Exp, Overrides};

use crate::db::models::{self, ExperimentStatusType};

#[derive(Deserialize, Serialize, Clone, PartialEq, Debug)]
pub enum VariantType {
CONTROL,
EXPERIMENTAL,
}

#[derive(Deserialize, Serialize, Clone)]
pub struct Variant {
pub id: String,
pub variant_type: VariantType,
pub context_id: Option<String>,
pub override_id: Option<String>,
pub overrides: Exp<Overrides>,
}
use crate::db::models::{self, ExperimentStatusType, Variant};

/********** Experiment Create Req Types ************/

Expand Down Expand Up @@ -62,7 +47,7 @@ pub struct ExperimentResponse {
pub traffic_percentage: i32,

pub context: Value,
pub variants: Value,
pub variants: Vec<Variant>,
pub last_modified_by: String,
pub chosen_variant: Option<String>,
}
Expand All @@ -81,7 +66,7 @@ impl From<models::Experiment> for ExperimentResponse {
traffic_percentage: experiment.traffic_percentage,

context: experiment.context,
variants: experiment.variants,
variants: experiment.variants.into_inner(),
last_modified_by: experiment.last_modified_by,
chosen_variant: experiment.chosen_variant,
}
Expand Down
40 changes: 38 additions & 2 deletions crates/experimentation_platform/src/db/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ use crate::db::schema::*;
use chrono::{DateTime, NaiveDateTime, Utc};

use diesel::{
query_builder::QueryId, Insertable, Queryable, QueryableByName, Selectable,
deserialize::FromSqlRow, expression::AsExpression, query_builder::QueryId,
sql_types::Json, Insertable, Queryable, QueryableByName, Selectable,
};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use superposition_proc_macros::{JsonFromSql, JsonToSql};
use superposition_types::{Exp, Overrides};

#[derive(
Debug,
Expand All @@ -25,6 +28,39 @@ pub enum ExperimentStatusType {
INPROGRESS,
}

#[derive(Deserialize, Serialize, Clone, PartialEq, Debug)]
pub enum VariantType {
CONTROL,
EXPERIMENTAL,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Variant {
pub id: String,
pub variant_type: VariantType,
#[serde(skip_serializing_if = "Option::is_none")]
pub context_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub override_id: Option<String>,
pub overrides: Exp<Overrides>,
}

#[derive(
Debug, Clone, Serialize, Deserialize, AsExpression, FromSqlRow, JsonFromSql, JsonToSql,
)]
#[diesel(sql_type = Json)]
pub struct Variants(Vec<Variant>);

impl Variants {
pub fn new(data: Vec<Variant>) -> Self {
Self(data)
}

pub fn into_inner(self) -> Vec<Variant> {
self.0
}
}

#[derive(QueryableByName, Queryable, Selectable, Insertable, Serialize, Clone, Debug)]
#[diesel(check_for_backend(diesel::pg::Pg))]
#[diesel(primary_key(id))]
Expand All @@ -40,7 +76,7 @@ pub struct Experiment {
pub traffic_percentage: i32,

pub context: Value,
pub variants: Value,
pub variants: Variants,
pub last_modified_by: String,
pub chosen_variant: Option<String>,
}
Expand Down
Loading

0 comments on commit 3502b86

Please sign in to comment.