Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions launchdarkly-server-sdk/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use tokio::sync::{broadcast, Semaphore};
use super::config::Config;
use super::data_source_builders::BuildError as DataSourceError;
use super::data_system::{DataSystem, FDv1DataSystem};
use super::data_system_builders::BuildError as DataSystemError;
use super::evaluation::{FlagDetail, FlagDetailConfig};
use super::stores::store::DataStore;
use super::stores::store_builders::BuildError as DataStoreError;
Expand Down Expand Up @@ -65,6 +66,12 @@ impl From<DataSourceError> for BuildError {
}
}

impl From<DataSystemError> for BuildError {
fn from(error: DataSystemError) -> Self {
Self::InvalidConfig(error.to_string())
}
}

impl From<DataStoreError> for BuildError {
fn from(error: DataStoreError) -> Self {
Self::InvalidConfig(error.to_string())
Expand Down Expand Up @@ -184,13 +191,24 @@ impl Client {
let event_processor =
event_processor_builder.build(&endpoints, config.sdk_key(), tags.clone())?;

let mut data_source_builder = config.data_source_builder().to_owned();
data_source_builder.set_instance_id(instance_id);
let data_source = data_source_builder.build(&endpoints, config.sdk_key(), tags.clone())?;
let data_system: Arc<dyn DataSystem> = Arc::new(FDv1DataSystem::new(
data_source,
config.data_store_builder(),
)?);
let data_system: Arc<dyn DataSystem> = match config.data_system_builder() {
Some(data_system_builder) => data_system_builder.build(
&endpoints,
config.sdk_key(),
tags.as_deref(),
&instance_id,
)?,
None => {
let mut data_source_builder = config.data_source_builder().to_owned();
data_source_builder.set_instance_id(instance_id);
let data_source =
data_source_builder.build(&endpoints, config.sdk_key(), tags.clone())?;
Arc::new(FDv1DataSystem::new(
data_source,
config.data_store_builder(),
)?)
}
};
let data_store = data_system.store();

let events_default = EventsScope {
Expand Down
39 changes: 39 additions & 0 deletions launchdarkly-server-sdk/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use thiserror::Error;

use crate::data_source_builders::{DataSourceFactory, NullDataSourceBuilder};
use crate::data_system_builders::{DataSystemBuilder, DataSystemFactory};

#[cfg(any(
feature = "hyper-rustls-native-roots",
Expand Down Expand Up @@ -136,6 +137,7 @@ pub struct Config {
service_endpoints_builder: ServiceEndpointsBuilder,
data_store_builder: Box<dyn DataStoreFactory>,
data_source_builder: Box<dyn DataSourceFactory>,
data_system_builder: Option<Box<dyn DataSystemFactory>>,
event_processor_builder: Box<dyn EventProcessorFactory>,
application_tag: Option<String>,
instance_id: String,
Expand Down Expand Up @@ -164,6 +166,11 @@ impl Config {
self.data_source_builder.borrow()
}

/// Returns the DataSystemFactory, if an FDv2 data system was configured.
pub(crate) fn data_system_builder(&self) -> Option<&dyn DataSystemFactory> {
self.data_system_builder.as_deref()
}

/// Returns the EventProcessorFactory
pub fn event_processor_builder(&self) -> &dyn EventProcessorFactory {
self.event_processor_builder.borrow()
Expand Down Expand Up @@ -212,6 +219,7 @@ pub struct ConfigBuilder {
service_endpoints_builder: Option<ServiceEndpointsBuilder>,
data_store_builder: Option<Box<dyn DataStoreFactory>>,
data_source_builder: Option<Box<dyn DataSourceFactory>>,
data_system_builder: Option<Box<dyn DataSystemFactory>>,
event_processor_builder: Option<Box<dyn EventProcessorFactory>>,
application_info: Option<ApplicationInfo>,
offline: bool,
Expand All @@ -226,6 +234,7 @@ impl ConfigBuilder {
service_endpoints_builder: None,
data_store_builder: None,
data_source_builder: None,
data_system_builder: None,
event_processor_builder: None,
offline: false,
daemon_mode: false,
Expand Down Expand Up @@ -258,6 +267,16 @@ impl ConfigBuilder {
self
}

/// Set the data system to use for this client.
///
/// When set, the data system supersedes the [data_source](ConfigBuilder::data_source).
/// If offline mode is enabled, it will be ignored.
pub fn data_system(mut self, builder: &DataSystemBuilder) -> Self {
let factory: Box<dyn DataSystemFactory> = Box::new(builder.clone());
self.data_system_builder = Some(factory);
self
}

/// Set the event processor to use for this client.
/// For usage see [EventProcessorBuilder](crate::EventProcessorBuilder).
///
Expand Down Expand Up @@ -307,8 +326,27 @@ impl ConfigBuilder {
Some(_data_store_builder) => self.data_store_builder.unwrap(),
};

// The data system is optional; when set it supersedes the data source.
// Like the data source, it is ignored in offline or daemon mode.
let data_system_builder = match self.data_system_builder {
Some(_) if self.offline => {
warn!("Custom data system builders will be ignored when in offline mode");
None
}
Some(_) if self.daemon_mode => {
warn!("Custom data system builders will be ignored when in daemon mode");
None
}
other => other,
};

let data_source_builder_result: Result<Box<dyn DataSourceFactory>, BuildError> =
match self.data_source_builder {
None if data_system_builder.is_some() => Ok(Box::new(NullDataSourceBuilder::new())),
Some(_) if data_system_builder.is_some() => {
warn!("Custom data source builders will be ignored when a data system is configured");
Ok(Box::new(NullDataSourceBuilder::new()))
}
None if self.offline => Ok(Box::new(NullDataSourceBuilder::new())),
Some(_) if self.offline => {
warn!("Custom data source builders will be ignored when in offline mode");
Expand Down Expand Up @@ -401,6 +439,7 @@ impl ConfigBuilder {
service_endpoints_builder,
data_store_builder,
data_source_builder,
data_system_builder,
event_processor_builder,
application_tag,
instance_id,
Expand Down
Loading
Loading