#![allow(deprecated)]
use posthog_rs::ClientOptionsBuilder;
use serde_json::json;
use std::collections::HashMap;
use std::time::{Duration, Instant};
#[cfg(feature = "async-client")]
#[tokio::main]
async fn main() {
let api_key = match std::env::var("POSTHOG_API_TOKEN") {
Ok(key) => key,
Err(_) => {
eprintln!("Error: POSTHOG_API_TOKEN environment variable not set");
eprintln!("Please set it to your PostHog project API token");
eprintln!("\nExample: export POSTHOG_API_TOKEN=phc_...");
std::process::exit(1);
}
};
let personal_key = match std::env::var("POSTHOG_PERSONAL_API_TOKEN") {
Ok(key) => key,
Err(_) => {
eprintln!("Error: POSTHOG_PERSONAL_API_TOKEN environment variable not set");
eprintln!("Please set it to your PostHog personal API token");
eprintln!("\nTo create a personal API key:");
eprintln!("1. Go to https://app.posthog.com/me/settings");
eprintln!("2. Click 'Create personal API key'");
eprintln!("3. Export it: export POSTHOG_PERSONAL_API_TOKEN=phx_...");
std::process::exit(1);
}
};
println!("=== Local Evaluation Performance Demo ===\n");
let local_client = {
let options = ClientOptionsBuilder::default()
.api_key(api_key.clone())
.personal_api_key(personal_key)
.enable_local_evaluation(true)
.poll_interval_seconds(30) .build()
.unwrap();
posthog_rs::client(options).await
};
let api_client = {
let options = ClientOptionsBuilder::default()
.api_key(api_key)
.build()
.unwrap();
posthog_rs::client(options).await
};
println!("Fetching flag definitions for local evaluation...");
tokio::time::sleep(Duration::from_secs(2)).await;
let user_id = "perf-test-user";
let mut properties = HashMap::new();
properties.insert("plan".to_string(), json!("enterprise"));
properties.insert("country".to_string(), json!("US"));
println!("\n=== Performance Comparison ===");
println!("\n1. API Evaluation (10 requests):");
let start = Instant::now();
for i in 0..10 {
let _ = api_client
.get_feature_flag(
"using-feature-flags".to_string(),
format!("{}-{}", user_id, i),
None,
Some(properties.clone()),
None,
)
.await;
}
let api_duration = start.elapsed();
println!(
" Time: {:?} total, {:?} per request",
api_duration,
api_duration / 10
);
println!("\n2. Local Evaluation (10 requests):");
let start = Instant::now();
for i in 0..10 {
let _ = local_client
.get_feature_flag(
"using-feature-flags".to_string(),
format!("{}-{}", user_id, i),
None,
Some(properties.clone()),
None,
)
.await;
}
let local_duration = start.elapsed();
println!(
" Time: {:?} total, {:?} per request",
local_duration,
local_duration / 10
);
let speedup = api_duration.as_micros() as f64 / local_duration.as_micros().max(1) as f64;
println!("\nLocal evaluation is {:.1}x faster!", speedup);
println!("\n=== Batch Evaluation Demo ===");
let start = Instant::now();
match local_client
.get_feature_flags(user_id.to_string(), None, Some(properties), None)
.await
{
Ok((flags, _)) => {
let duration = start.elapsed();
println!("Evaluated {} flags in {:?}", flags.len(), duration);
println!("\nSample flags:");
for (key, value) in flags.iter().take(5) {
println!(" {}: {:?}", key, value);
}
}
Err(e) => println!("Error: {}", e),
}
println!("\nLocal evaluation continues polling for updates in the background");
println!(" Updates will be fetched every 30 seconds automatically");
}
#[cfg(not(feature = "async-client"))]
fn main() {
println!("This example requires the async-client feature.");
println!("Run with: cargo run --example local_evaluation --features async-client");
}