Class: ConvertSdk::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/convert_sdk/config.rb

Overview

The SDK's configuration surface and wire-translation boundary #1.

Config is the ONE place in the gem where the inbound public naming world (idiomatic snake_case keyword arguments) is translated into the internal / wire naming world (string-keyed camelCase). The only other naming-world conversion site in the entire gem is the outbound payload builder in ApiManager (Story 4.1); any other file converting option names is an architecture violation (the two-worlds rule).

JS-parity defaults

DEFAULTS carries the frozen JS-parity values — batch 10, flush interval 1s, data-refresh 300s, bucketing seed 9999 / max-traffic 10000 / max-hash 2**32. These exact numbers are restated across the PRD, architecture, and research; they are NOT tuning knobs and must not drift. Endpoint URLs are copied verbatim from the reference SDKs' default config.

Fail-fast validation (the SDK's only raising surface)

Construction delegates to ConfigValidator, which raises a stdlib ArgumentError — naming the offending option and the expected type — for any presence/type violation. This is the SDK's ONLY raising surface (Decision 3): there is no custom exception hierarchy, because the SDK degrades gracefully (cached config / sentinels) for every runtime/infra failure, leaving nothing for a hierarchy to hold. Misconfiguration therefore surfaces immediately at boot rather than as silent misbehavior in production. Unknown option keys are rejected for the same reason — a typo fails fast instead of being ignored.

Nil-able timer intervals (Lambda / CLI mode)

flush_interval and data_refresh_interval accept nil, meaning timer-off: the background flush / refresh threads are never started. This is the AWS Lambda and plain-CLI recipe (synchronous flush before exit; no background threads). flush_interval is the canonical flush-timer key throughout the gem (the older event_release_interval alias is retired).

Secret registration (NFR5)

When an sdk_key / sdk_key_secret is present and a LogManager is injected, Config registers those values with the manager's Redactor immediately at construction — so secrets are armed before any log line can carry them. Config is constructible standalone (no log_manager) for unit tests; ConvertSdk.create / Client (Story 2.5) injects the real manager.

Constant Summary collapse

MILLISECONDS_PER_SECOND =

Number of milliseconds per second — the flush_interval second→ms wire translation factor.

1000
MAX_HASH =

The fixed bucketing hash space (2**32). A JS-parity constant, not a configurable option — exposed as a reader for the bucketing engine.

4_294_967_296
DEFAULTS =

The frozen JS-parity defaults for every public option. Verified against javascript-sdk config/default.ts and php-sdk DefaultConfig.php.

{
  # Auth / data — at least one of sdk_key / data is required (validated).
  sdk_key: nil,
  sdk_key_secret: nil,
  data: nil,
  # Platform environment selector; nil leaves it to the platform default.
  environment: nil,
  # Live Convert endpoints (verbatim from the reference default config).
  config_endpoint: "https://cdn-4.convertexperiments.com/api/v1",
  track_endpoint: "https://[project_id].metrics.convertexperiments.com/v1",
  # Bucketing constants — frozen JS-parity numbers, do not tune.
  max_traffic: 10_000,
  hash_seed: 9999,
  # Config-refresh cadence in seconds (JS 300000 ms); nil = timer-off.
  data_refresh_interval: 300,
  # Event delivery — batch size and flush cadence (seconds); nil = timer-off.
  event_batch_size: 10,
  flush_interval: 1,
  # Rule evaluation options.
  keys_case_sensitive: true,
  negation: "!",
  # Logging verbosity (JS default.ts:29 logLevel: LogLevel.DEBUG).
  log_level: LogLevel::DEBUG,
  # Network tracking enable/disable.
  tracking: true,
  # HTTP client timeouts in seconds (consumed by HttpClient, Story 1.5).
  open_timeout: 5,
  read_timeout: 10
}.freeze
KNOWN_KEYS =

The canonical set of accepted option keys (the DEFAULTS keys).

DEFAULTS.keys.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(log_manager: nil, **options) ⇒ Config

Build a validated configuration from snake_case keyword options merged over DEFAULTS. Raises ArgumentError (the SDK's only raising surface) on any presence/type violation or unknown option key.

Parameters:

  • log_manager (LogManager, nil) (defaults to: nil)

    when provided, present secrets (sdk_key / sdk_key_secret) are registered with its Redactor so they are armed before any log line. Optional for standalone construction.

  • options (Hash{Symbol=>Object})

    any subset of the DEFAULTS keys.

Raises:

  • (ArgumentError)

    on unknown keys, missing sdk_key+data, or bad types.



139
140
141
142
143
144
145
# File 'lib/convert_sdk/config.rb', line 139

def initialize(log_manager: nil, **options)
  reject_unknown_keys(options)
  merged = DEFAULTS.merge(options)
  assign(merged)
  ConfigValidator.new(merged).validate!
  register_secrets(log_manager)
end

Instance Attribute Details

#config_endpointString (readonly)

Returns config-fetch base URL (JS api.endpoint.config).

Returns:

  • (String)

    config-fetch base URL (JS api.endpoint.config).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#dataHash? (readonly)

Returns inline config payload (JS data); skips fetch.

Returns:

  • (Hash, nil)

    inline config payload (JS data); skips fetch.



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#data_refresh_intervalNumeric? (readonly)

Returns config-refresh seconds; nil = timer-off (JS dataRefreshInterval, ms).

Returns:

  • (Numeric, nil)

    config-refresh seconds; nil = timer-off (JS dataRefreshInterval, ms).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#environmentString? (readonly)

Returns platform environment (JS environment).

Returns:

  • (String, nil)

    platform environment (JS environment).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#event_batch_sizeInteger (readonly)

Returns event flush batch size (JS events.batch_size).

Returns:

  • (Integer)

    event flush batch size (JS events.batch_size).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#flush_intervalNumeric? (readonly)

Returns flush cadence seconds; nil = timer-off (JS events.release_interval, ms). Canonical flush-timer key.

Returns:

  • (Numeric, nil)

    flush cadence seconds; nil = timer-off (JS events.release_interval, ms). Canonical flush-timer key.



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#hash_seedInteger (readonly)

Returns bucketing hash seed (JS bucketing.hash_seed).

Returns:

  • (Integer)

    bucketing hash seed (JS bucketing.hash_seed).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#keys_case_sensitiveBoolean (readonly)

Returns rule key case sensitivity (JS rules.keys_case_sensitive).

Returns:

  • (Boolean)

    rule key case sensitivity (JS rules.keys_case_sensitive).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#log_levelInteger (readonly)

Returns a LogLevel threshold (JS logger.logLevel).

Returns:

  • (Integer)

    a LogLevel threshold (JS logger.logLevel).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#max_trafficInteger (readonly)

Returns bucketing max traffic (JS bucketing.max_traffic).

Returns:

  • (Integer)

    bucketing max traffic (JS bucketing.max_traffic).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#negationString (readonly)

Returns rule negation token (JS rules.negation, default "!").

Returns:

  • (String)

    rule negation token (JS rules.negation, default "!").



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#open_timeoutNumeric (readonly)

Returns HTTP connect timeout seconds (HttpClient, NFR3).

Returns:

  • (Numeric)

    HTTP connect timeout seconds (HttpClient, NFR3).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#read_timeoutObject (readonly)

Returns the value of attribute read_timeout.



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#sdk_keyString? (readonly)

Returns account/project SDK key (JS sdkKey). Path auth.

Returns:

  • (String, nil)

    account/project SDK key (JS sdkKey). Path auth.



124
125
126
# File 'lib/convert_sdk/config.rb', line 124

def sdk_key
  @sdk_key
end

#sdk_key_secretString? (readonly)

Returns bearer secret (JS sdkKeySecret). Redacted.

Returns:

  • (String, nil)

    bearer secret (JS sdkKeySecret). Redacted.



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#track_endpointString (readonly)

Returns tracking base URL (JS api.endpoint.track).

Returns:

  • (String)

    tracking base URL (JS api.endpoint.track).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#trackingBoolean (readonly)

Returns network tracking enabled (JS network.tracking).

Returns:

  • (Boolean)

    network tracking enabled (JS network.tracking).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

Instance Method Details

#max_hashInteger

Returns the fixed bucketing hash space (2**32).

Returns:

  • (Integer)

    the fixed bucketing hash space (2**32).



148
149
150
# File 'lib/convert_sdk/config.rb', line 148

def max_hash
  MAX_HASH
end

#to_internalHash{String=>Object}

The wire-translation boundary: the internal, string-keyed camelCase representation downstream managers (DataManager / ApiManager) consume. This is the single inbound conversion site. flush_interval seconds are translated to the millisecond wire value here; nil passes through (timer-off).

Returns:

  • (Hash{String=>Object})

    a frozen internal config snapshot.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/convert_sdk/config.rb', line 158

def to_internal
  {
    "sdkKey" => @sdk_key,
    "sdkKeySecret" => @sdk_key_secret,
    "data" => @data,
    "environment" => @environment,
    "configEndpoint" => @config_endpoint,
    "trackEndpoint" => @track_endpoint,
    "maxTraffic" => @max_traffic,
    "hashSeed" => @hash_seed,
    "maxHash" => MAX_HASH,
    "dataRefreshInterval" => @data_refresh_interval,
    "batchSize" => @event_batch_size,
    "releaseInterval" => to_milliseconds(@flush_interval),
    "keysCaseSensitive" => @keys_case_sensitive,
    "negation" => @negation,
    "logLevel" => @log_level,
    "tracking" => @tracking
  }.freeze
end