Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/actions/check/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ runs:
test_service_port: 9000
enable_persistence_tests: true
token: ${{ inputs.token }}
version: v3.0.0-alpha.2
version: v3.0.0-alpha.3
28 changes: 10 additions & 18 deletions contract-tests/client_entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,13 @@ def initialize(log, config)
data_system.initializers(initializers)
end

sync_config = data_system_config[:synchronizers]
if sync_config
primary = sync_config[:primary]
secondary = sync_config[:secondary]
sync_configs = data_system_config[:synchronizers]
if sync_configs && !sync_configs.empty?
synchronizer_builders = sync_configs.map { |sync_config| build_synchronizer_builder(sync_config) }.compact
data_system.synchronizers(synchronizer_builders) unless synchronizer_builders.empty?

primary_builder = build_synchronizer_builder(primary)
secondary_builder = build_synchronizer_builder(secondary)

data_system.synchronizers(primary_builder, secondary_builder) if primary_builder

if primary_builder || secondary_builder
fallback_builder = build_fdv1_fallback_builder(primary, secondary)
data_system.fdv1_compatible_synchronizer(fallback_builder)
end
fallback_builder = build_fdv1_fallback_builder(sync_configs)
data_system.fdv1_compatible_synchronizer(fallback_builder)
end

if data_system_config[:payloadFilter]
Expand Down Expand Up @@ -327,17 +320,16 @@ def close
end

#
# Builds an FDv1 fallback polling data source builder using the first available config.
# Builds an FDv1 fallback polling data source builder using the first available polling config.
#
# @param primary [Hash, nil] The primary synchronizer configuration
# @param secondary [Hash, nil] The secondary synchronizer configuration
# @param sync_configs [Array<Hash>] Array of synchronizer configurations
# @return [Object] Returns the configured FDv1 fallback builder
#
private def build_fdv1_fallback_builder(primary, secondary)
private def build_fdv1_fallback_builder(sync_configs)
builder = LaunchDarkly::DataSystem.fdv1_fallback_ds_builder

# Use the first available polling config for the fallback base_uri
polling_config = primary&.dig(:polling) || secondary&.dig(:polling)
polling_config = sync_configs.lazy.map { |c| c[:polling] }.detect { |p| p }
if polling_config
builder.base_uri(polling_config[:baseUri]) if polling_config[:baseUri]
builder.poll_interval(polling_config[:pollIntervalMs] / 1_000.0) if polling_config[:pollIntervalMs]
Expand Down
20 changes: 7 additions & 13 deletions lib/ldclient-rb/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -703,34 +703,28 @@ def initialize(store:, context_cache_size: nil, context_cache_time: nil, status_
class DataSystemConfig
#
# @param initializers [Array<#build(String, Config)>, nil] The (optional) array of builders
# @param primary_synchronizer [#build(String, Config), nil] The (optional) builder for primary synchronizer
# @param secondary_synchronizer [#build(String, Config), nil] The (optional) builder for secondary synchronizer
# @param synchronizers [Array<#build(String, Config)>, nil] The (optional) array of synchronizer builders
# @param data_store_mode [Symbol] The (optional) data store mode
# @param data_store [LaunchDarkly::Interfaces::FeatureStore, nil] The (optional) data store
# @param fdv1_fallback_synchronizer [#build(String, Config), nil]
# The (optional) builder for FDv1-compatible fallback synchronizer
#
def initialize(initializers: nil, primary_synchronizer: nil, secondary_synchronizer: nil,
def initialize(initializers: nil, synchronizers: nil,
data_store_mode: LaunchDarkly::Interfaces::DataSystem::DataStoreMode::READ_ONLY, data_store: nil, fdv1_fallback_synchronizer: nil)
@initializers = initializers
@primary_synchronizer = primary_synchronizer
@secondary_synchronizer = secondary_synchronizer
@synchronizers = synchronizers
@data_store_mode = data_store_mode
@data_store = data_store
@fdv1_fallback_synchronizer = fdv1_fallback_synchronizer
end

# The initializers for the data system. Each builder responds to build(sdk_key, config) and returns an Initializer.
# The initializer builders for the data system. Each builder responds to build(sdk_key, config) and returns an Initializer.
# @return [Array<#build(String, Config)>, nil]
attr_reader :initializers

# The primary synchronizer builder. Responds to build(sdk_key, config) and returns a Synchronizer.
# @return [#build(String, Config), nil]
attr_reader :primary_synchronizer

# The secondary synchronizer builder. Responds to build(sdk_key, config) and returns a Synchronizer.
# @return [#build(String, Config), nil]
attr_reader :secondary_synchronizer
# The synchronizer builders for the data system. Each builder responds to build(sdk_key, config) and returns a Synchronizer.
# @return [Array<#build(String, Config)>, nil]
attr_reader :synchronizers

# The data store mode.
# @return [Symbol]
Expand Down
26 changes: 9 additions & 17 deletions lib/ldclient-rb/data_system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ module DataSystem
class ConfigBuilder
def initialize
@initializers = nil
@primary_synchronizer = nil
@secondary_synchronizer = nil
@synchronizers = nil
@fdv1_fallback_synchronizer = nil
@data_store_mode = LaunchDarkly::Interfaces::DataSystem::DataStoreMode::READ_ONLY
@data_store = nil
Expand All @@ -40,13 +39,12 @@ def initializers(initializers)
#
# Sets the synchronizers for the data system.
#
# @param primary [#build(String, Config)] Builder that responds to build(sdk_key, config) and returns the primary Synchronizer
# @param secondary [#build(String, Config), nil] Builder that responds to build(sdk_key, config) and returns the secondary Synchronizer
# @param synchronizers [Array<#build(String, Config)>]
# Array of builders that respond to build(sdk_key, config) and return a Synchronizer
# @return [ConfigBuilder] self for chaining
#
def synchronizers(primary, secondary = nil)
@primary_synchronizer = primary
@secondary_synchronizer = secondary
def synchronizers(synchronizers)
@synchronizers = synchronizers
self
end

Expand Down Expand Up @@ -79,17 +77,11 @@ def data_store(data_store, store_mode)
# Builds the data system configuration.
#
# @return [DataSystemConfig]
# @raise [ArgumentError] if configuration is invalid
#
def build
if @secondary_synchronizer && @primary_synchronizer.nil?
raise ArgumentError, "Primary synchronizer must be set if secondary is set"
end

DataSystemConfig.new(
initializers: @initializers,
primary_synchronizer: @primary_synchronizer,
secondary_synchronizer: @secondary_synchronizer,
synchronizers: @synchronizers,
data_store_mode: @data_store_mode,
data_store: @data_store,
fdv1_fallback_synchronizer: @fdv1_fallback_synchronizer
Expand Down Expand Up @@ -151,7 +143,7 @@ def self.default

builder = ConfigBuilder.new
builder.initializers([polling_builder])
builder.synchronizers(streaming_builder, polling_builder)
builder.synchronizers([streaming_builder, polling_builder])
builder.fdv1_compatible_synchronizer(fallback)

builder
Expand All @@ -169,7 +161,7 @@ def self.streaming
fallback = fdv1_fallback_ds_builder

builder = ConfigBuilder.new
builder.synchronizers(streaming_builder)
builder.synchronizers([streaming_builder])
builder.fdv1_compatible_synchronizer(fallback)

builder
Expand All @@ -187,7 +179,7 @@ def self.polling
fallback = fdv1_fallback_ds_builder

builder = ConfigBuilder.new
builder.synchronizers(polling_builder)
builder.synchronizers([polling_builder])
builder.fdv1_compatible_synchronizer(fallback)

builder
Expand Down
5 changes: 5 additions & 0 deletions lib/ldclient-rb/impl/data_source/status_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ def update_status(new_state, new_error)
new_state = LaunchDarkly::Interfaces::DataSource::Status::INITIALIZING
end

# Special handling: You can't go back to INITIALIZING after being anything else
if new_state == LaunchDarkly::Interfaces::DataSource::Status::INITIALIZING && !old_status.state.nil?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kinyoklion want to make sure you agree with Jason and I on this one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think that is right.

I think this is my expectation for state.

stateDiagram-v2
    [*] --> INITIALIZING
    INITIALIZING --> VALID
    INITIALIZING --> OFF
    VALID --> INTERRUPTED
    VALID --> OFF
    INTERRUPTED --> VALID
    INTERRUPTED --> OFF
    OFF --> [*]
    
Loading

new_state = old_status.state
end

# No change if state is the same and no error
return if new_state == old_status.state && new_error.nil?

Expand Down
6 changes: 0 additions & 6 deletions lib/ldclient-rb/impl/data_store/status_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@ module DataStore
#
# StatusProviderV2 is the FDv2-specific implementation of {LaunchDarkly::Interfaces::DataStore::StatusProvider}.
#
# This type is not stable, and not subject to any backwards
# compatibility guarantees or semantic versioning. It is not suitable for production usage.
#
# Do not use it.
# You have been warned.
#
class StatusProviderV2
include LaunchDarkly::Interfaces::DataStore::StatusProvider

Expand Down
Loading