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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@

# rspec failure tracking
.rspec_status
vendor/bundle
32 changes: 27 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ object = client.fetch_object_value(flag_key: 'object_value', default_value: JSON
| ❌ | [Logging](#logging) | Integrate with popular logging packages. |
| ✅ | [Domains](#domains) | Logically bind clients with providers. |
| ❌ | [Eventing](#eventing) | React to state changes in the provider or flag management system. |
| ⚠️ | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
| | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
| ❌ | [Transaction Context Propagation](#transaction-context-propagation) | Set a specific [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context) for a transaction (e.g. an HTTP request or a thread) |
| ⚠️ | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. |

Expand Down Expand Up @@ -206,19 +206,41 @@ Please refer to the documentation of the provider you're using to see what event

### Shutdown

Coming Soon! [Issue available](https://github.com/open-feature/ruby-sdk/issues/149) to be worked on.

<!-- TODO The OpenFeature API provides a close function to perform a cleanup of all registered providers.
The OpenFeature API provides a shutdown function to perform a cleanup of all registered providers.
This should only be called when your application is in the process of shutting down.

```ruby
# Configure providers
OpenFeature::SDK.configure do |config|
config.set_provider(OpenFeature::SDK::Provider::InMemoryProvider.new(
{
"v2_enabled" => true,
}
))
end

# During application shutdown
OpenFeature::SDK.shutdown
```

When you call `OpenFeature::SDK.shutdown`, it will:

1. Call the `shutdown` method on all registered providers that support it
2. Clear all registered providers from the configuration
3. Reset the SDK to its initial state

After shutdown, no providers will be available and the SDK will need to be reconfigured if you want to continue using it.

To implement shutdown in your custom provider:

```ruby
class MyProvider
def shutdown
# Perform any shutdown/reclamation steps with flag management system here
# Return value is ignored
end
end
``` -->
```

### Transaction Context Propagation

Expand Down
2 changes: 1 addition & 1 deletion lib/open_feature/sdk/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class API
include Singleton # Satisfies Flag Evaluation API Requirement 1.1.1
extend Forwardable

def_delegators :configuration, :provider, :set_provider, :hooks, :evaluation_context
def_delegators :configuration, :provider, :set_provider, :hooks, :evaluation_context, :shutdown

def configuration
@configuration ||= Configuration.new
Expand Down
10 changes: 10 additions & 0 deletions lib/open_feature/sdk/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ def set_provider(provider, domain: nil)
@providers = new_providers
end
end

# Shutdown all registered providers and clear the configuration
def shutdown
@provider_mutex.synchronize do
@providers.each_value do |provider|
provider.shutdown if provider.respond_to?(:shutdown)
end
@providers.clear
end
end
end
end
end
39 changes: 39 additions & 0 deletions spec/open_feature/sdk/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,43 @@
end
end
end

describe "#shutdown" do
context "when providers have shutdown methods" do
let(:provider1) { OpenFeature::SDK::Provider::InMemoryProvider.new }
let(:provider2) { OpenFeature::SDK::Provider::InMemoryProvider.new }

it "calls shutdown on all providers and clears them" do
configuration.set_provider(provider1)
configuration.set_provider(provider2, domain: "testing")

expect(provider1).to receive(:shutdown)
expect(provider2).to receive(:shutdown)

configuration.shutdown

# Verify providers are cleared
expect(configuration.provider).to be_nil
expect(configuration.provider(domain: "testing")).to be_nil
end
end

context "when providers do not have shutdown methods" do
it "does not raise errors for providers without shutdown and clears them" do
provider_without_shutdown = OpenFeature::SDK::Provider::NoOpProvider.new
configuration.set_provider(provider_without_shutdown)

expect { configuration.shutdown }.not_to raise_error

# Verify providers are cleared
expect(configuration.provider).to be_nil
end
end

context "when no providers are set" do
it "does not raise errors" do
expect { configuration.shutdown }.not_to raise_error
end
end
end
end
29 changes: 29 additions & 0 deletions spec/specification/flag_evaluation_api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,35 @@
end.not_to raise_error
end
end

context "Shutdown functionality" do
specify "The API must provide a shutdown function to gracefully clean up all providers" do
provider1 = OpenFeature::SDK::Provider::InMemoryProvider.new
provider2 = OpenFeature::SDK::Provider::InMemoryProvider.new

OpenFeature::SDK.set_provider(provider1)
OpenFeature::SDK.set_provider(provider2, domain: "testing")

expect(provider1).to receive(:shutdown)
expect(provider2).to receive(:shutdown)

expect { OpenFeature::SDK.shutdown }.not_to raise_error

# Verify providers are cleared after shutdown
expect(OpenFeature::SDK.provider).to be_nil
expect(OpenFeature::SDK.provider(domain: "testing")).to be_nil
end

specify "Shutdown does not raise errors when providers don't have shutdown methods" do
provider_without_shutdown = OpenFeature::SDK::Provider::NoOpProvider.new
OpenFeature::SDK.set_provider(provider_without_shutdown)

expect { OpenFeature::SDK.shutdown }.not_to raise_error

# Verify providers are cleared after shutdown
expect(OpenFeature::SDK.provider).to be_nil
end
end
end

context "1.2 - Client Usage" do
Expand Down
Loading