Skip to content

Commit

Permalink
feat: priority recompute restructure
Browse files Browse the repository at this point in the history
  • Loading branch information
Pratik Mishra authored and Pratik Mishra committed Nov 13, 2024
1 parent c155bb0 commit abb77bb
Show file tree
Hide file tree
Showing 18 changed files with 217 additions and 34 deletions.
19 changes: 19 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ diesel = { version = "2.1.0", features = [
"chrono",
"uuid",
"postgres_backend",
"numeric",
] }
fred = { version = "9.2.1" }
itertools = { version = "0.10.5" }
Expand Down
3 changes: 3 additions & 0 deletions crates/context_aware_config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ actix-http = "3.3.1"
actix-web = { workspace = true }
anyhow = { workspace = true }
base64 = { workspace = true }
bigdecimal = { version = "0.3.1" , features= ["serde"]}
blake3 = "1.3.3"
cac_client = { path = "../cac_client" }
cfg-if = { workspace = true }
Expand All @@ -20,8 +21,10 @@ diesel = { workspace = true }
fred = { workspace = true, optional = true, features = ["metrics"]}
futures-util = "0.3.28"
itertools = { workspace = true }
jsonlogic = { workspace = true }
jsonschema = { workspace = true }
log = { workspace = true }
num-bigint = "0.4"
serde = { workspace = true }
serde_json = { workspace = true }
service_utils = { path = "../service_utils" }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- This file should undo anything in `up.sql`
ALTER TABLE public.dimensions
drop column position;

ALTER TABLE public.contexts
drop column weightage;

DROP INDEX IF EXISTS idx_contexts_weightage;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- Your SQL goes here
ALTER TABLE public.dimensions
add column position integer DEFAULT 1 NOT NULL;

ALTER TABLE public.contexts
add column weightage numeric(1000,0) DEFAULT 1 NOT NULL;

CREATE INDEX IF NOT EXISTS idx_contexts_weightage ON public.contexts(weightage);
19 changes: 11 additions & 8 deletions crates/context_aware_config/src/api/config/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ use diesel::{
#[cfg(feature = "high-performance-mode")]
use fred::interfaces::KeysInterface;
use itertools::Itertools;
use jsonschema::JSONSchema;
use serde_json::{json, Map, Value};
#[cfg(feature = "high-performance-mode")]
use service_utils::service::types::{AppState, Tenant};
Expand All @@ -42,11 +41,14 @@ use superposition_types::{
};
use uuid::Uuid;

use crate::api::context::{
delete_context_api, hash, put, validate_dimensions_and_calculate_priority, PutReq,
};
use crate::api::dimension::get_all_dimension_schema_map;
use crate::api::dimension::{get_dimension_data, get_dimension_data_map};
use crate::db::models::ConfigVersion;
use crate::{
api::context::{
delete_context_api, hash, put, validate_dimensions_and_calculate_priority, PutReq,
},
helpers::DimensionData,
};
use crate::{
db::schema::{config_versions::dsl as config_versions, event_log::dsl as event_log},
helpers::generate_cac,
Expand Down Expand Up @@ -392,7 +394,7 @@ async fn reduce_config_key(
mut og_contexts: Vec<Context>,
mut og_overrides: HashMap<String, Overrides>,
check_key: &str,
dimension_schema_map: &HashMap<String, (JSONSchema, i32)>,
dimension_schema_map: &HashMap<String, DimensionData>,
default_config: Map<String, Value>,
is_approve: bool,
) -> superposition::Result<Config> {
Expand Down Expand Up @@ -527,7 +529,8 @@ async fn reduce_config(
.and_then(|value| value.to_str().ok().and_then(|s| s.parse::<bool>().ok()))
.unwrap_or(false);

let dimensions_schema_map = get_all_dimension_schema_map(&mut conn)?;
let dimensions_vec = get_dimension_data(&mut conn)?;
let dimensions_data_map = get_dimension_data_map(&dimensions_vec)?;
let mut config = generate_cac(&mut conn)?;
let default_config = (config.default_configs).clone();
for (key, _) in default_config {
Expand All @@ -541,7 +544,7 @@ async fn reduce_config(
contexts.clone(),
overrides.clone(),
key.as_str(),
&dimensions_schema_map,
&dimensions_data_map,
default_config.clone(),
is_approve,
)
Expand Down
45 changes: 29 additions & 16 deletions crates/context_aware_config/src/api/context/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use crate::{
ContextAction, ContextBulkResponse, ContextFilterSortBy, ContextFilters,
DimensionCondition, MoveReq, PriorityRecomputeResponse, PutReq, PutResp,
},
dimension::get_all_dimension_schema_map,
dimension::{get_dimension_data, get_dimension_data_map},
},
db::{
models::Context,
Expand All @@ -54,7 +54,8 @@ use crate::{
},
},
helpers::{
add_config_version, calculate_context_priority, validate_context_jsonschema,
add_config_version, calculate_context_priority, calculate_context_weightage,
validate_context_jsonschema, DimensionData,
},
};

Expand Down Expand Up @@ -84,7 +85,7 @@ type DBConnection = PooledConnection<ConnectionManager<PgConnection>>;
pub fn validate_dimensions_and_calculate_priority(
object_key: &str,
cond: &Value,
dimension_schema_map: &HashMap<String, (JSONSchema, i32)>,
dimension_schema_map: &HashMap<String, DimensionData>,
) -> superposition::Result<i32> {
let get_priority = |key: &String, val: &Value| -> superposition::Result<i32> {
if key == "var" {
Expand All @@ -93,7 +94,7 @@ pub fn validate_dimensions_and_calculate_priority(
.ok_or(bad_argument!("Dimension name should be of `String` type"))?;
dimension_schema_map
.get(dimension_name)
.map(|(_, priority)| priority)
.map(|dimension_val| &dimension_val.priority)
.ok_or(bad_argument!(
"No matching dimension ({}) found",
dimension_name
Expand Down Expand Up @@ -129,17 +130,17 @@ pub fn validate_dimensions_and_calculate_priority(

if let (Some(dimension_value), Some(dimension_condition)) = (val, condition) {
let expected_dimension_name = dimension_condition.var;
let (dimension_value_schema, _) = dimension_schema_map
let dimension_data = dimension_schema_map
.get(&expected_dimension_name)
.ok_or(bad_argument!(
"No matching `dimension` {} in dimension table",
expected_dimension_name
))?;
"No matching `dimension` {} in dimension table",
expected_dimension_name
))?;

validate_context_jsonschema(
object_key,
&dimension_value,
dimension_value_schema,
&dimension_data.schema,
)?;
}
arr.iter().try_fold(0, |acc, item| {
Expand Down Expand Up @@ -218,14 +219,16 @@ fn create_ctx_from_put_req(
validate_condition_with_functions(conn, &ctx_condition)?;
validate_override_with_functions(conn, &r_override)?;

let dimension_schema_map = get_all_dimension_schema_map(conn)?;

let dimension_data = get_dimension_data(conn)?;
let dimension_data_map = get_dimension_data_map(&dimension_data)?;
let priority = validate_dimensions_and_calculate_priority(
"context",
&condition_val,
&dimension_schema_map,
&dimension_data_map,
)?;

let weightage = calculate_context_weightage(&condition_val, &dimension_data_map)
.map_err(|_| unexpected_error!("Something Went Wrong"))?;
if priority == 0 {
return Err(bad_argument!("No dimension found in context"));
}
Expand All @@ -242,6 +245,7 @@ fn create_ctx_from_put_req(
created_by: user.get_email(),
last_modified_at: Utc::now().naive_utc(),
last_modified_by: user.get_email(),
weightage,
})
}

Expand Down Expand Up @@ -321,6 +325,7 @@ fn get_put_resp(ctx: Context) -> PutResp {
context_id: ctx.id,
override_id: ctx.override_id,
priority: ctx.priority,
weightage: ctx.weightage,
}
}

Expand Down Expand Up @@ -448,12 +453,18 @@ fn r#move(
let ctx_condition = req.context.to_owned().into_inner();
let ctx_condition_value = Value::Object(ctx_condition.clone().into());
let new_ctx_id = hash(&ctx_condition_value);
let dimension_schema_map = get_all_dimension_schema_map(conn)?;

let dimension_data = get_dimension_data(conn)?;
let dimension_data_map = get_dimension_data_map(&dimension_data)?;
let priority = validate_dimensions_and_calculate_priority(
"context",
&ctx_condition_value,
&dimension_schema_map,
&dimension_data_map,
)?;
let weightage =
calculate_context_weightage(&ctx_condition_value, &dimension_data_map)
.map_err(|_| unexpected_error!("Something Went Wrong"))?;

validate_condition_with_mandatory_dimensions(
&req.context.into_inner(),
&tenant_config.mandatory_dimensions,
Expand Down Expand Up @@ -488,6 +499,7 @@ fn r#move(
override_: ctx.override_,
last_modified_at: Utc::now().naive_utc(),
last_modified_by: user.get_email(),
weightage,
};

let handle_unique_violation =
Expand Down Expand Up @@ -861,7 +873,8 @@ async fn priority_recompute(
unexpected_error!("Something went wrong")
})?;

let dimension_schema_map = get_all_dimension_schema_map(&mut conn)?;
let dimension_data = get_dimension_data(&mut conn)?;
let dimension_data_map = get_dimension_data_map(&dimension_data)?;
let mut response: Vec<PriorityRecomputeResponse> = vec![];
let tags = parse_config_tags(custom_headers.config_tags)?;

Expand All @@ -872,7 +885,7 @@ async fn priority_recompute(
let new_priority = calculate_context_priority(
"context",
&Value::Object(context.value.clone().into()),
&dimension_schema_map,
&dimension_data_map,
)
.map_err(|err| {
log::error!("failed to calculate context priority: {}", err);
Expand Down
2 changes: 2 additions & 0 deletions crates/context_aware_config/src/api/context/types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use bigdecimal::BigDecimal;
use serde::{Deserialize, Serialize};
use superposition_types::{Cac, Condition, Overrides};

Expand All @@ -24,6 +25,7 @@ pub struct PutResp {
pub context_id: String,
pub override_id: String,
pub priority: i32,
pub weightage: BigDecimal,
}

#[derive(Deserialize)]
Expand Down
2 changes: 1 addition & 1 deletion crates/context_aware_config/src/api/dimension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ mod handlers;
mod types;
mod utils;
pub use handlers::endpoints;
pub use utils::get_all_dimension_schema_map;
pub use utils::{get_dimension_data, get_dimension_data_map};
1 change: 1 addition & 0 deletions crates/context_aware_config/src/api/dimension/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ async fn create(
let new_dimension = Dimension {
dimension: create_req.dimension.into(),
priority: create_req.priority.into(),
position: create_req.position.into(),
schema: schema_value,
created_by: user.get_email(),
created_at: Utc::now(),
Expand Down
33 changes: 33 additions & 0 deletions crates/context_aware_config/src/api/dimension/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::db::models::Dimension;
pub struct CreateReq {
pub dimension: DimensionName,
pub priority: Priority,
pub position: Position,
pub schema: Value,
#[serde(default, deserialize_with = "deserialize_option")]
pub function_name: Option<Value>,
Expand All @@ -35,6 +36,36 @@ impl TryFrom<i32> for Priority {
}
}

#[derive(Debug, Deserialize, AsRef, Deref, DerefMut, Into)]
#[serde(try_from = "Option<i32>")]
pub struct Position(i32);
impl Position {
fn validate_data(position_val: Option<i32>) -> Result<Self, String> {
if let Some(val) = position_val {
if val <= 0 {
return Err("Position should be greater than 0".to_string());
} else {
Ok(Self(val))
}
} else {
Ok(Position::default())
}
}
}

impl TryFrom<Option<i32>> for Position {
type Error = String;
fn try_from(value: Option<i32>) -> Result<Self, Self::Error> {
Ok(Self::validate_data(value)?)
}
}

impl Default for Position {
fn default() -> Self {
Position(1)
}
}

#[derive(Debug, Deserialize, AsRef, Deref, DerefMut, Into)]
#[serde(try_from = "String")]
pub struct DimensionName(String);
Expand Down Expand Up @@ -66,6 +97,7 @@ where
pub struct DimensionWithMandatory {
pub dimension: String,
pub priority: i32,
pub position: i32,
pub created_at: DateTime<Utc>,
pub created_by: String,
pub schema: Value,
Expand All @@ -80,6 +112,7 @@ impl DimensionWithMandatory {
DimensionWithMandatory {
dimension: value.dimension,
priority: value.priority,
position: value.position,
created_at: value.created_at,
created_by: value.created_by,
schema: value.schema,
Expand Down
Loading

0 comments on commit abb77bb

Please sign in to comment.