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
5 changes: 5 additions & 0 deletions lib/open_feature/sdk/client_metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ module OpenFeature
module SDK
ClientMetadata = Struct.new(:domain, keyword_init: true) do
alias_method :name, :domain

def initialize(domain: nil)
super(domain: domain&.dup&.freeze)
freeze
end
end
end
end
2 changes: 1 addition & 1 deletion lib/open_feature/sdk/provider/no_op_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module Provider
# * <tt>fetch_object_value</tt> - Retrieve feature flag object value
#
class NoOpProvider
REASON_NO_OP = "No-op"
REASON_NO_OP = Reason::DEFAULT
NAME = "No-op Provider"

attr_reader :metadata
Expand Down
4 changes: 2 additions & 2 deletions lib/open_feature/sdk/provider_initialization_error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class ProviderInitializationError < StandardError
# @param message [String] the error message
# @param provider [Object] the provider that failed to initialize
# @param original_error [Exception] the original error that caused the failure
# @param error_code [String] the OpenFeature error code (defaults to PROVIDER_FATAL)
def initialize(message, provider: nil, original_error: nil, error_code: Provider::ErrorCode::PROVIDER_FATAL)
# @param error_code [String] the OpenFeature error code (defaults to GENERAL)
def initialize(message, provider: nil, original_error: nil, error_code: Provider::ErrorCode::GENERAL)
super(message)
@provider = provider
@original_error = original_error
Expand Down
14 changes: 7 additions & 7 deletions lib/open_feature/sdk/provider_state_registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ module SDK
# Tracks provider states
class ProviderStateRegistry
def initialize
@states = {}
@states = {}.compare_by_identity
@mutex = Mutex.new
end

def set_initial_state(provider, state = ProviderState::NOT_READY)
return unless provider

@mutex.synchronize do
@states[provider.object_id] = {state: state, details: {}}
@states[provider] = {state: state, details: {}}
end
end

Expand All @@ -29,7 +29,7 @@ def update_state_from_event(provider, event_type, event_details = nil)
# Only update state if the event should cause a state change
if new_state
@mutex.synchronize do
@states[provider.object_id] = {state: new_state, details: event_details || {}}
@states[provider] = {state: new_state, details: event_details || {}}
end
new_state
else
Expand All @@ -42,7 +42,7 @@ def get_state(provider)
return ProviderState::NOT_READY unless provider

@mutex.synchronize do
entry = @states[provider.object_id]
entry = @states[provider]
entry ? entry[:state] : ProviderState::NOT_READY
end
end
Expand All @@ -51,7 +51,7 @@ def get_details(provider)
return {} unless provider

@mutex.synchronize do
entry = @states[provider.object_id]
entry = @states[provider]
entry ? entry[:details] : {}
end
end
Expand All @@ -60,15 +60,15 @@ def remove_provider(provider)
return unless provider

@mutex.synchronize do
@states.delete(provider.object_id)
@states.delete(provider)
end
end

def tracked?(provider)
return false unless provider

@mutex.synchronize do
@states.key?(provider.object_id)
@states.key?(provider)
end
end

Expand Down
5 changes: 5 additions & 0 deletions spec/open_feature/sdk/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
expect(client).to respond_to(:metadata)
expect(client.metadata.domain).to eq(domain)
end

it "client metadata is frozen (req 4.2.2.1 — hook context client_metadata must be immutable)" do
expect(client.metadata).to be_frozen
expect(client.metadata.domain).to be_frozen
end
end

context "Flag evaluation" do
Expand Down
7 changes: 5 additions & 2 deletions spec/open_feature/sdk/hooks/logging_hook_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,15 @@
end

it "uses error_code from exception when available" do
error_with_code = OpenFeature::SDK::ProviderInitializationError.new("init failed")
error_with_code = OpenFeature::SDK::ProviderInitializationError.new(
"init failed",
error_code: "CUSTOM_ERROR_CODE"
)
hook = described_class.new(logger: logger)

expect(logger).to receive(:error) do |&block|
message = block.call
expect(message).to include("error_code=PROVIDER_FATAL")
expect(message).to include("error_code=CUSTOM_ERROR_CODE")
end

hook.error(hook_context: hook_context, exception: error_with_code, hints: hints)
Expand Down
8 changes: 4 additions & 4 deletions spec/open_feature/sdk/provider_initialization_error_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
expect(error).to be_a(StandardError)
end

it "sets the error code to PROVIDER_FATAL by default" do
expect(error.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::PROVIDER_FATAL)
it "sets the error code to GENERAL by default" do
expect(error.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::GENERAL)
end
end

Expand All @@ -49,8 +49,8 @@
expect(error.original_error).to be_nil
end

it "sets the error code to PROVIDER_FATAL by default" do
expect(error.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::PROVIDER_FATAL)
it "sets the error code to GENERAL by default" do
expect(error.error_code).to eq(OpenFeature::SDK::Provider::ErrorCode::GENERAL)
end
end

Expand Down
4 changes: 2 additions & 2 deletions spec/open_feature/sdk/provider_state_registry_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

RSpec.describe OpenFeature::SDK::ProviderStateRegistry do
let(:registry) { described_class.new }
let(:provider) { double("Provider", object_id: 12_345) }
let(:provider2) { double("Provider2", object_id: 67_890) }
let(:provider) { double("Provider") }
let(:provider2) { double("Provider2") }

describe "#set_initial_state" do
it "sets NOT_READY as default state" do
Expand Down
Loading