Ruby SDK
The Ruby SDK provides a thread-safe client for evaluating feature flags in Ruby applications.
Installation
Add to your Gemfile:
gem "featuresignals"
Or install directly:
gem install featuresignals
Requirements: Ruby 3.1+
Quick Start
require "featuresignals"
options = FeatureSignals::ClientOptions.new(env_key: "production")
client = FeatureSignals::Client.new("fs_srv_your_api_key", options)
client.wait_for_ready
user = FeatureSignals::EvalContext.new(key: "user-123", attributes: { "plan" => "pro" })
enabled = client.bool_variation("new-feature", user, false)
puts "Feature enabled: #{enabled}"
Configuration
options = FeatureSignals::ClientOptions.new(
env_key: "production",
base_url: "http://localhost:8080",
polling_interval: 15,
streaming: true,
sse_retry: 3,
timeout: 10,
)
| Option | Type | Default | Description |
|---|---|---|---|
env_key | String | (required) | Environment slug |
base_url | String | https://api.featuresignals.com | API server URL |
polling_interval | Numeric | 30 | Polling frequency in seconds |
streaming | Boolean | false | Enable SSE streaming |
sse_retry | Numeric | 5 | SSE reconnect delay in seconds |
timeout | Numeric | 10 | HTTP timeout in seconds |
Variation Methods
enabled = client.bool_variation("flag-key", ctx, false)
value = client.string_variation("banner-text", ctx, "default")
limit = client.number_variation("rate-limit", ctx, 100.0)
config = client.json_variation("config", ctx, { "v" => 1 })
Evaluation Context
user = FeatureSignals::EvalContext.new(key: "user-42")
# with_attribute returns a new copy (immutable)
rich_user = user
.with_attribute("plan", "enterprise")
.with_attribute("country", "US")
Lifecycle
# Wait for initial flags
client.wait_for_ready(timeout: 10)
# Check readiness
if client.ready?
# ...
end
# Get all flags
flags = client.all_flags
# Shutdown
client.close
Callbacks
client = FeatureSignals::Client.new("key", options,
on_ready: -> { puts "Flags loaded" },
on_error: ->(err) { warn "Error: #{err}" },
on_update: ->(flags) { puts "Updated: #{flags.size} flags" },
)
Rails Integration
Create an initializer at config/initializers/feature_signals.rb:
Rails.application.config.to_prepare do
options = FeatureSignals::ClientOptions.new(
env_key: Rails.env.production? ? "production" : "development",
base_url: ENV.fetch("FEATURESIGNALS_URL", "http://localhost:8080"),
streaming: true,
)
FEATURE_FLAGS = FeatureSignals::Client.new(
ENV.fetch("FEATURESIGNALS_API_KEY"), options
)
end
at_exit { FEATURE_FLAGS&.close }
Use in controllers:
class CheckoutController < ApplicationController
def show
user = FeatureSignals::EvalContext.new(
key: current_user.id.to_s,
attributes: { "plan" => current_user.plan }
)
if FEATURE_FLAGS.bool_variation("new-checkout", user, false)
render :new_checkout
else
render :checkout
end
end
end
Sinatra
require "sinatra"
require "featuresignals"
flags = FeatureSignals::Client.new("fs_srv_xxx",
FeatureSignals::ClientOptions.new(env_key: "production"))
get "/feature" do
ctx = FeatureSignals::EvalContext.new(key: params[:user_id] || "anonymous")
{ enabled: flags.bool_variation("my-flag", ctx, false) }.to_json
end
OpenFeature
provider = FeatureSignals::OpenFeature::Provider.new("fs_srv_xxx", options)
result = provider.resolve_boolean_evaluation("new-feature", false)
puts "#{result.value} (#{result.reason})"
provider.shutdown
Thread Safety
- All variation methods are thread-safe (backed by
Mutex) EvalContext#with_attributereturns a new objectcloseis idempotent