Skip to content

Commit

Permalink
feat(flags): adding support for GeoIP and person property overrides t…
Browse files Browse the repository at this point in the history
…o rust flag service (#24536)

Co-authored-by: Phani Raj <[email protected]>
  • Loading branch information
dmarticus and Phanatic authored Aug 27, 2024
1 parent 54b2bc4 commit 8dde90a
Show file tree
Hide file tree
Showing 16 changed files with 1,563 additions and 458 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ jobs:
DATABASE_URL: 'postgres://posthog:posthog@localhost:5432/posthog'
run: cd ../ && python manage.py setup_test_environment --only-postgres

- name: Download MaxMind Database
if: needs.changes.outputs.rust == 'true'
run: |
mkdir -p ../share
curl -L "https://mmdbcdn.posthog.net/" --http1.1 | brotli --decompress --output=../share/GeoLite2-City.mmdb
- name: Run cargo test
if: needs.changes.outputs.rust == 'true'
run: |
Expand Down
11 changes: 11 additions & 0 deletions rust/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 rust/feature-flags/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ thiserror = { workspace = true }
serde-pickle = { version = "1.1.1"}
sha1 = "0.10.6"
regex = "1.10.4"
maxminddb = "0.17"
sqlx = { workspace = true }
uuid = { workspace = true }

Expand Down
20 changes: 20 additions & 0 deletions rust/feature-flags/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use envconfig::Envconfig;
use once_cell::sync::Lazy;
use std::net::SocketAddr;
use std::path::{Path, PathBuf};
use std::str::FromStr;

// TODO rewrite this to follow the AppConfig pattern in other files
#[derive(Envconfig, Clone, Debug)]
pub struct Config {
#[envconfig(default = "127.0.0.1:3001")]
Expand All @@ -25,6 +27,9 @@ pub struct Config {

#[envconfig(default = "1")]
pub acquire_timeout_secs: u64,

#[envconfig(from = "MAXMIND_DB_PATH", default = "")]
pub maxmind_db_path: String,
}

impl Config {
Expand All @@ -38,6 +43,21 @@ impl Config {
max_concurrent_jobs: 1024,
max_pg_connections: 100,
acquire_timeout_secs: 1,
maxmind_db_path: "".to_string(),
}
}

pub fn get_maxmind_db_path(&self) -> PathBuf {
if self.maxmind_db_path.is_empty() {
Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.parent()
.unwrap()
.join("share")
.join("GeoLite2-City.mmdb")
} else {
PathBuf::from(&self.maxmind_db_path)
}
}
}
Expand Down
41 changes: 32 additions & 9 deletions rust/feature-flags/src/flag_definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ impl FeatureFlagList {
team_id: i32,
flags: &FeatureFlagList,
) -> Result<(), FlagError> {
let payload = serde_json::to_string(flags).map_err(|e| {
let payload = serde_json::to_string(&flags.flags).map_err(|e| {
tracing::error!("Failed to serialize flags: {}", e);
FlagError::DataParsingError
})?;
Expand Down Expand Up @@ -1392,23 +1392,46 @@ mod tests {
}

// Fetch flags from both sources
let redis_flags = FeatureFlagList::from_redis(redis_client, team.id)
let mut redis_flags = FeatureFlagList::from_redis(redis_client, team.id)
.await
.expect("Failed to fetch flags from Redis");
let pg_flags = FeatureFlagList::from_pg(pg_client, team.id)
let mut pg_flags = FeatureFlagList::from_pg(pg_client, team.id)
.await
.expect("Failed to fetch flags from Postgres");

// Sort flags by key to ensure consistent order
redis_flags.flags.sort_by(|a, b| a.key.cmp(&b.key));
pg_flags.flags.sort_by(|a, b| a.key.cmp(&b.key));

// Compare results
assert_eq!(redis_flags.flags.len(), pg_flags.flags.len());
assert_eq!(
redis_flags.flags.len(),
pg_flags.flags.len(),
"Number of flags mismatch"
);

for (redis_flag, pg_flag) in redis_flags.flags.iter().zip(pg_flags.flags.iter()) {
assert_eq!(redis_flag.key, pg_flag.key);
assert_eq!(redis_flag.name, pg_flag.name);
assert_eq!(redis_flag.active, pg_flag.active);
assert_eq!(redis_flag.deleted, pg_flag.deleted);
assert_eq!(redis_flag.key, pg_flag.key, "Flag key mismatch");
assert_eq!(
redis_flag.name, pg_flag.name,
"Flag name mismatch for key: {}",
redis_flag.key
);
assert_eq!(
redis_flag.active, pg_flag.active,
"Flag active status mismatch for key: {}",
redis_flag.key
);
assert_eq!(
redis_flag.deleted, pg_flag.deleted,
"Flag deleted status mismatch for key: {}",
redis_flag.key
);
assert_eq!(
redis_flag.filters.groups[0].rollout_percentage,
pg_flag.filters.groups[0].rollout_percentage
pg_flag.filters.groups[0].rollout_percentage,
"Flag rollout percentage mismatch for key: {}",
redis_flag.key
);
}
}
Expand Down
Loading

0 comments on commit 8dde90a

Please sign in to comment.