use std::sync::Arc;
use std::time::Duration;
use serde_json::Value;
use tokio::runtime::Runtime;
use crate::client::DEFAULT_POLL_INTERVAL;
use crate::{
BulkEvaluation, ConfigError, Error, EvaluationContext, FlagEvaluation, FlagValue,
FluxGateClientBuilder, SnapshotStatus,
};
#[derive(Clone, Debug)]
pub struct FluxGateClient {
inner: crate::FluxGateClient,
runtime: Arc<Runtime>,
}
impl FluxGateClient {
pub fn new(base_url: &str, sdk_key: &str) -> Result<Self, ConfigError> {
crate::FluxGateClient::builder(base_url, sdk_key).build_blocking()
}
pub fn builder(
base_url: impl Into<String>,
sdk_key: impl Into<String>,
) -> FluxGateClientBuilder {
crate::FluxGateClient::builder(base_url, sdk_key)
}
pub(crate) fn from_parts(inner: crate::FluxGateClient) -> Result<Self, ConfigError> {
let runtime = tokio::runtime::Builder::new_multi_thread()
.worker_threads(1)
.thread_name("fluxgate")
.enable_all()
.build()
.map_err(ConfigError::Runtime)?;
Ok(Self {
inner,
runtime: Arc::new(runtime),
})
}
pub fn evaluate<T: FlagValue>(
&self,
key: &str,
default_value: T,
context: &EvaluationContext,
) -> FlagEvaluation<T> {
self.runtime
.block_on(self.inner.evaluate(key, default_value, context))
}
pub fn get_bool(&self, key: &str, default_value: bool, context: &EvaluationContext) -> bool {
self.evaluate(key, default_value, context).value
}
pub fn get_string(
&self,
key: &str,
default_value: &str,
context: &EvaluationContext,
) -> String {
self.evaluate(key, default_value.to_owned(), context).value
}
pub fn get_i64(&self, key: &str, default_value: i64, context: &EvaluationContext) -> i64 {
self.evaluate(key, default_value, context).value
}
pub fn get_f64(&self, key: &str, default_value: f64, context: &EvaluationContext) -> f64 {
self.evaluate(key, default_value, context).value
}
pub fn get_value(&self, key: &str, default_value: Value, context: &EvaluationContext) -> Value {
self.evaluate(key, default_value, context).value
}
pub fn is_enabled(&self, key: &str, context: &EvaluationContext) -> bool {
self.get_bool(key, false, context)
}
pub fn evaluate_all(
&self,
context: &EvaluationContext,
version: Option<&str>,
) -> Result<BulkEvaluation, Error> {
self.runtime
.block_on(self.inner.evaluate_all(context, version))
}
pub fn watch(&self, context: EvaluationContext) -> FlagSnapshot {
self.watch_with_interval(context, DEFAULT_POLL_INTERVAL)
}
pub fn watch_with_interval(
&self,
context: EvaluationContext,
poll_interval: Duration,
) -> FlagSnapshot {
let _guard = self.runtime.enter();
FlagSnapshot {
inner: self.inner.watch_with_interval(context, poll_interval),
runtime: Arc::clone(&self.runtime),
}
}
pub fn is_healthy(&self) -> bool {
self.runtime.block_on(self.inner.is_healthy())
}
pub fn clear_cache(&self) {
self.inner.clear_cache();
}
}
#[derive(Clone, Debug)]
pub struct FlagSnapshot {
inner: crate::FlagSnapshot,
runtime: Arc<Runtime>,
}
impl FlagSnapshot {
pub fn wait_ready(&self) {
self.runtime.block_on(self.inner.ready());
}
pub fn set_context(&self, context: EvaluationContext) {
self.runtime.block_on(self.inner.set_context(context));
}
pub fn refresh(&self) {
self.runtime.block_on(self.inner.refresh());
}
pub fn status(&self) -> SnapshotStatus {
self.inner.status()
}
pub fn error(&self) -> Option<Error> {
self.inner.error()
}
pub fn context(&self) -> EvaluationContext {
self.inner.context()
}
pub fn revision(&self) -> u64 {
self.inner.revision()
}
pub fn evaluate<T: FlagValue>(&self, key: &str, default_value: T) -> FlagEvaluation<T> {
self.inner.evaluate(key, default_value)
}
pub fn get_bool(&self, key: &str, default_value: bool) -> bool {
self.inner.get_bool(key, default_value)
}
pub fn get_string(&self, key: &str, default_value: &str) -> String {
self.inner.get_string(key, default_value)
}
pub fn get_i64(&self, key: &str, default_value: i64) -> i64 {
self.inner.get_i64(key, default_value)
}
pub fn get_f64(&self, key: &str, default_value: f64) -> f64 {
self.inner.get_f64(key, default_value)
}
pub fn get_value(&self, key: &str, default_value: Value) -> Value {
self.inner.get_value(key, default_value)
}
pub fn is_enabled(&self, key: &str) -> bool {
self.inner.is_enabled(key)
}
pub fn keys(&self) -> Vec<String> {
self.inner.keys()
}
pub fn close(&self) {
self.inner.close();
}
}