Class: Toggly::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/toggly/client.rb

Overview

Main client for interacting with Toggly feature flags.

Examples:

Basic usage

client = Toggly::Client.new(
  app_key: "your-app-key",
  environment: "Production"
)

if client.enabled?("my-feature")
  # Feature is enabled
end

With configuration object

config = Toggly::Config.new(
  app_key: "your-app-key",
  environment: "Production",
  refresh_interval: 60
)
client = Toggly::Client.new(config)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_or_options = {}) ⇒ Client

Create a new client

Parameters:

  • config_or_options (Config, Hash) (defaults to: {})

    Configuration object or options hash



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/toggly/client.rb', line 36

def initialize(config_or_options = {})
  @config = config_or_options.is_a?(Config) ? config_or_options : Config.new(**config_or_options)
  @config.validate!

  @definitions = {}
  @mutex = Mutex.new
  @ready = false
  @closed = false

  @engine = EvaluationEngine.new(logger: @config.logger)
  @provider = DefinitionsProvider.new(
    config: @config,
    logger: @config.logger,
    on_definitions_updated: -> { refresh }
  )

  @refresh_thread = nil

  initialize_definitions
  Toggly.register_entity_contexts_at_startup(@config) unless @config.disable_entity_context_registration
  start_background_refresh unless @config.disable_background_refresh
end

Instance Attribute Details

#configConfig (readonly)

Returns Client configuration.

Returns:

  • (Config)

    Client configuration



25
26
27
# File 'lib/toggly/client.rb', line 25

def config
  @config
end

#definitionsHash<String, FeatureDefinition> (readonly)

Returns Current definitions.

Returns:



28
29
30
# File 'lib/toggly/client.rb', line 28

def definitions
  @definitions
end

#readyBoolean (readonly)

Returns Whether the client is ready.

Returns:

  • (Boolean)

    Whether the client is ready



31
32
33
# File 'lib/toggly/client.rb', line 31

def ready
  @ready
end

Instance Method Details

#closeObject

Close the client and stop background refresh



153
154
155
156
157
158
# File 'lib/toggly/client.rb', line 153

def close
  @closed = true
  @provider.stop_websocket
  @refresh_thread&.kill
  @refresh_thread = nil
end

#closed?Boolean

Check if client is closed

Returns:

  • (Boolean)


163
164
165
# File 'lib/toggly/client.rb', line 163

def closed?
  @closed
end

#disabled?(feature_key, context: nil, default: nil) ⇒ Boolean

Check if a feature is disabled

Parameters:

  • feature_key (String, Symbol)

    The feature key

  • context (Context, nil) (defaults to: nil)

    Optional evaluation context

  • default (Boolean) (defaults to: nil)

    Default value if feature not found

Returns:

  • (Boolean)


88
89
90
# File 'lib/toggly/client.rb', line 88

def disabled?(feature_key, context: nil, default: nil)
  !enabled?(feature_key, context: context, default: default.nil? ? nil : !default)
end

#enabled?(feature_key, context: nil, default: nil) ⇒ Boolean

Check if a feature is enabled

Parameters:

  • feature_key (String, Symbol)

    The feature key

  • context (Context, nil) (defaults to: nil)

    Optional evaluation context

  • default (Boolean) (defaults to: nil)

    Default value if feature not found

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/toggly/client.rb', line 65

def enabled?(feature_key, context: nil, default: nil)
  key = feature_key.to_s

  definition = @mutex.synchronize { @definitions[key] }

  # Check defaults if not found
  if definition.nil?
    return default unless default.nil?
    return @config.defaults[key] if @config.defaults.key?(key)
    return @config.enable_undefined_in_dev if development?

    return false
  end

  @engine.evaluate(definition, context)
end

#evaluate(feature_key, context: nil) ⇒ EvaluationResult

Get detailed evaluation result

Parameters:

  • feature_key (String, Symbol)

    The feature key

  • context (Context, nil) (defaults to: nil)

    Optional evaluation context

Returns:



97
98
99
100
101
102
# File 'lib/toggly/client.rb', line 97

def evaluate(feature_key, context: nil)
  key = feature_key.to_s
  definition = @mutex.synchronize { @definitions[key] }

  @engine.evaluate_with_details(definition, context)
end

#feature(feature_key) ⇒ FeatureDefinition?

Get a feature definition

Parameters:

  • feature_key (String, Symbol)

    The feature key

Returns:



108
109
110
# File 'lib/toggly/client.rb', line 108

def feature(feature_key)
  @mutex.synchronize { @definitions[feature_key.to_s] }
end

#feature_keysArray<String>

Get all feature keys

Returns:

  • (Array<String>)


115
116
117
# File 'lib/toggly/client.rb', line 115

def feature_keys
  @mutex.synchronize { @definitions.keys }
end

#featuresArray<FeatureDefinition>

Get all features

Returns:



122
123
124
# File 'lib/toggly/client.rb', line 122

def features
  @mutex.synchronize { @definitions.values }
end

#refresh(force: false) ⇒ Boolean

Manually refresh definitions

Parameters:

  • force (Boolean) (defaults to: false)

    Force refresh even if not modified

Returns:

  • (Boolean)

    Whether definitions were updated



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/toggly/client.rb', line 130

def refresh(force: false)
  return false if @config.offline_mode?

  new_definitions = @provider.fetch(force: force)

  if new_definitions
    @mutex.synchronize do
      @definitions = new_definitions
      @ready = true
    end

    save_snapshot
    log_info("Definitions refreshed (#{new_definitions.size} features)")
    true
  else
    false
  end
rescue StandardError => e
  log_error("Failed to refresh definitions: #{e.message}")
  false
end

#wait_for_ready(timeout: 5) ⇒ Boolean

Wait for client to be ready

Parameters:

  • timeout (Numeric) (defaults to: 5)

    Maximum wait time in seconds

Returns:

  • (Boolean)

    Whether client became ready



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/toggly/client.rb', line 171

def wait_for_ready(timeout: 5)
  start_time = Time.now

  until @ready
    return false if (Time.now - start_time) > timeout

    sleep(0.01)
  end

  true
end