Module: Shipeasy
- Defined in:
- lib/shipeasy/config.rb,
lib/shipeasy-sdk.rb,
lib/shipeasy/client.rb,
lib/shipeasy/engine.rb,
lib/shipeasy/sdk/see.rb,
lib/shipeasy/sdk/eval.rb,
lib/shipeasy/sdk/anon_id.rb,
lib/shipeasy/sdk/murmur3.rb,
lib/shipeasy/sdk/railtie.rb,
lib/shipeasy/sdk/version.rb,
lib/shipeasy/i18n/railtie.rb,
lib/shipeasy/sdk/telemetry.rb,
lib/shipeasy/sdk/openfeature.rb,
lib/shipeasy/sdk/sticky_store.rb,
lib/shipeasy/i18n/view_helpers.rb,
lib/shipeasy/i18n/label_fetcher.rb,
lib/shipeasy/sdk/rack_middleware.rb
Overview
Single configuration object for the Shipeasy gem.
Covers both subsystems:
- SDK / experimentation (api_key, base_url) — drives Engine
- i18n / string manager (public_key, profile, cdn_base_url, ...) — drives
the Rails view helpers and label fetcher
Usage:
Shipeasy.configure do |c|
c.api_key = ENV["SHIPEASY_SERVER_KEY"]
c.public_key = ENV["SHIPEASY_CLIENT_KEY"]
c.profile = "default"
end
Anything not set falls back to the defaults below. The same Shipeasy.config is read by Engine and the Rails helpers, so there is one place to point environment variables at.
Defined Under Namespace
Modules: I18n, OpenFeature, SDK Classes: Client, Configuration, Engine, Error
Class Method Summary collapse
-
.attributes_transform ⇒ Object
The resolved attributes transform (callable).
- .config ⇒ Object
-
.configure {|config| ... } ⇒ Object
Configure the gem once at boot.
-
.engine ⇒ Object
The single global engine registered by configure, or nil if configure has not run (or ran without an api_key).
-
.flags ⇒ Object
Lazy, fork-safe singleton Engine.
-
.register_engine!(cfg) ⇒ Object
Build + register the one global engine (first-config-wins).
-
.reset_config! ⇒ Object
Reset the config back to defaults — primarily for tests.
Class Method Details
.attributes_transform ⇒ Object
The resolved attributes transform (callable). Default = identity, so a user object that is already the attribute hash is used verbatim.
84 85 86 87 88 89 90 91 92 93 |
# File 'lib/shipeasy/config.rb', line 84 def attributes_transform transform = config.attributes if transform.nil? ->(user) { user } elsif transform.respond_to?(:call) transform else raise Error, "Shipeasy.configure { |c| c.attributes = … } must be a callable (e.g. a lambda)" end end |
.config ⇒ Object
57 58 59 |
# File 'lib/shipeasy/config.rb', line 57 def config @config ||= Configuration.new end |
.configure {|config| ... } ⇒ Object
Configure the gem once at boot. In addition to populating the shared Configuration, this builds and registers the ONE global Shipeasy::Engine (first-config-wins) from the api_key/base_url and kicks off its one-shot fetch (fire-and-forget) so ‘Shipeasy::Client.new(user).get_flag(…)` resolves against real rules with no explicit init call.
Shipeasy.configure do |c|
c.api_key = ENV["SHIPEASY_SERVER_KEY"]
c.attributes = ->(u) { { "user_id" => u.id, "plan" => u.plan } }
end
Shipeasy::Client.new(current_user).get_flag("new_checkout")
Long-running servers that also want the background poll can call ‘Shipeasy.engine.init` after configure.
76 77 78 79 80 |
# File 'lib/shipeasy/config.rb', line 76 def configure yield config register_engine!(config) if config.api_key config end |
.engine ⇒ Object
The single global engine registered by configure, or nil if configure has not run (or ran without an api_key). Shipeasy::Client reads this.
97 98 99 100 101 102 103 104 105 106 |
# File 'lib/shipeasy/config.rb', line 97 def engine pid = Process.pid if @engine && @engine_pid != pid # Post-fork: the parent's poll thread didn't survive. Rebuild lazily # from the stored config in this child process. @engine = nil register_engine!(config) if config.api_key end @engine end |
.flags ⇒ Object
Lazy, fork-safe singleton Engine. The first call from each process spawns a fresh client + poll thread — including post-fork workers under Puma’s preload_app!. Callers can ‘Shipeasy.flags.get_flag(…)` straight from a controller without holding a constant or worrying about `before_worker_boot` hooks.
Initializers stay minimal:
# config/initializers/shipeasy.rb
Shipeasy.configure { |c| c.api_key = ENV["SHIPEASY_SERVER_KEY"] }
The first request that touches ‘Shipeasy.flags.*` triggers init(). For serverless / Lambda where you want a single fetch with no thread, build the engine explicitly: `Shipeasy::Engine.new(…).init_once`.
NOTE: this remains a separate, polling engine from the one configure() registers (Shipeasy.engine). New code should prefer the Shipeasy.configure + Shipeasy::Client.new(user) front door; ‘Shipeasy.flags` is retained for the legacy `Shipeasy.flags.get_flag(name, user)` style.
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/shipeasy/config.rb', line 155 def flags pid = Process.pid if @flags && @flags_pid != pid # Post-fork: parent's poll thread didn't survive. Don't destroy # @flags (its mutex/state is invalid in this child anyway); just # rebuild from scratch. @flags = nil end @flags ||= begin @flags_pid = pid client = Engine.new( api_key: config.api_key, base_url: config.base_url, ) client.init client end end |
.register_engine!(cfg) ⇒ Object
Build + register the one global engine (first-config-wins). Fires the one-shot fetch fire-and-forget. Idempotent within a process.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/shipeasy/config.rb', line 110 def register_engine!(cfg) return @engine if @engine && @engine_pid == Process.pid @engine_pid = Process.pid engine = Engine.new(api_key: cfg.api_key, base_url: cfg.base_url) @engine = engine # Capture +engine+ in the closure (not the @engine ivar, which a concurrent # reset/reconfigure could nil out before the thread runs). Thread.new do engine.init_once rescue => e warn "[shipeasy] configure() one-shot fetch failed: #{e.}" end engine end |
.reset_config! ⇒ Object
Reset the config back to defaults — primarily for tests.
126 127 128 129 130 131 132 133 134 |
# File 'lib/shipeasy/config.rb', line 126 def reset_config! @config = nil @flags_pid = nil @flags&.destroy @flags = nil @engine&.destroy @engine = nil @engine_pid = nil end |