Class: LaunchDarkly::LDClient

Inherits:
Object
  • Object
show all
Defined in:
lib/ldclient-rb/ldclient.rb

Overview

A client for the LaunchDarkly API. Client instances are thread-safe. Users should create a single client instance for the lifetime of the application.

Instance Method Summary collapse

Constructor Details

#initialize(api_key, config = Config.default) ⇒ LDClient

Creates a new client instance that connects to LaunchDarkly. A custom configuration parameter can also supplied to specify advanced options, but for most use cases, the default configuration is appropriate.

Parameters:

  • api_key (String)

    the API key for your LaunchDarkly account

  • config (Config) (defaults to: Config.default)

    an optional client configuration object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/ldclient-rb/ldclient.rb', line 31

def initialize(api_key, config = Config.default)
  @queue = Queue.new
  @api_key = api_key
  @config = config
  @client = Faraday.new do |builder|
    builder.use :http_cache, store: @config.store

    builder.adapter :net_http_persistent
  end
  @offline = false

  if @config.stream?
    @stream_processor = StreamProcessor.new(api_key, config)
  end

  @worker = create_worker()
end

Instance Method Details

#feature_keysObject

Returns the key of every feature



216
217
218
# File 'lib/ldclient-rb/ldclient.rb', line 216

def feature_keys
  get_features.map {|feature| feature[:key]}
end

#flushObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/ldclient-rb/ldclient.rb', line 49

def flush()
  events = []
  num_events = @queue.length()
  begin
    num_events.times do 
      events << @queue.pop(true)
    end
  rescue
  end

  if !events.empty?()
    res = log_timings("Flush events") {
      next @client.post (@config.base_uri + "/api/events/bulk") do |req|
        req.headers['Authorization'] = 'api_key ' + @api_key
        req.headers['User-Agent'] = 'RubyClient/' + LaunchDarkly::VERSION
        req.headers['Content-Type'] = 'application/json'
        req.body = events.to_json
        req.options.timeout = @config.read_timeout          
        req.options.open_timeout = @config.connect_timeout               
      end
    }
    if res.status != 200
      @config.logger.error("[LDClient] Unexpected status code while processing events: #{res.status}")
    end
  end      
end

#get_featuresObject

Returns all features



223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/ldclient-rb/ldclient.rb', line 223

def get_features
  res = @client.get (@config.base_uri + '/api/features') do |req|
    req.headers['Authorization'] = 'api_key ' + @api_key
    req.headers['User-Agent'] = 'RubyClient/' + LaunchDarkly::VERSION
    req.options.timeout = @config.read_timeout
    req.options.open_timeout = @config.connect_timeout
  end

  if res.status == 200 then
    return JSON.parse(res.body, symbolize_names: true)[:items]
  else
    @config.logger.error("[LDClient] Unexpected status code #{res.status}")
  end
end

#get_flag?(key, user, default = false) ⇒ Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/ldclient-rb/ldclient.rb', line 91

def get_flag?(key, user, default=false)
  toggle?(key, user, default)
end

#identify(user) ⇒ Object

Registers the user

Parameters:

  • The (Hash)

    user to register



185
186
187
# File 'lib/ldclient-rb/ldclient.rb', line 185

def identify(user)
  add_event({:kind => 'identify', :key => user[:key], :user => user})
end

#is_offline?Boolean

Returns:

  • (Boolean)


197
198
199
# File 'lib/ldclient-rb/ldclient.rb', line 197

def is_offline?()
  return @offline
end

#set_offlineObject



189
190
191
# File 'lib/ldclient-rb/ldclient.rb', line 189

def set_offline()
  @offline = true
end

#set_onlineObject



193
194
195
# File 'lib/ldclient-rb/ldclient.rb', line 193

def set_online()
  @offline = false
end

#toggle?(key, user, default = false) ⇒ Boolean

Calculates the value of a feature flag for a given user. At a minimum, the user hash should contain a :key .

For authenticated users, the :key should be the unique identifier for your user. For anonymous users, the :key should be a session identifier or cookie. In either case, the only requirement is that the key is unique to a user.

You can also pass IP addresses and country codes in the user hash.

Countries should be sent as ISO 3166-1 alpha-2 codes.

The user hash can contain arbitrary custom attributes stored in a :custom sub-hash:

Attribute values in the custom hash can be integers, booleans, strings, or lists of integers, booleans, or strings.

Examples:

Basic user hash

{:key => "[email protected]"}

More complete user hash

{:key => "[email protected]", :ip => "127.0.0.1", :country => "US"}

A user hash with custom attributes

{:key => "[email protected]", :custom => {:customer_rank => 1000, :groups => ["google", "microsoft"]}} 

Parameters:

  • key (String)

    the unique feature key for the feature flag, as shown on the LaunchDarkly dashboard

  • user (Hash)

    a hash containing parameters for the end user requesting the flag

  • default=false (Boolean)

    the default value of the flag

Returns:

  • (Boolean)

    whether or not the flag should be enabled, or the default value if the flag is disabled on the LaunchDarkly control panel



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ldclient-rb/ldclient.rb', line 125

def toggle?(key, user, default=false)
  begin
    if @offline
      return default
    end

    unless user
      @config.logger.error("[LDClient] Must specify user")
      return default
    end

    if @config.stream? and not @stream_processor.started?
      @stream_processor.start
    end

    if @config.stream? and @stream_processor.initialized?
      feature = get_flag_stream(key)
      if @config.debug_stream?
        polled = get_flag_int(key)
        diff = HashDiff.diff(feature, polled)
        if not diff.empty?
          @config.logger.error("Streamed flag differs from polled flag " + diff.to_s)
        end
      end
    else
      feature = get_flag_int(key)
    end
    value = evaluate(feature, user)
    value.nil? ? default : value

    add_event({:kind => 'feature', :key => key, :user => user, :value => value})
    LDNewRelic.annotate_transaction(key, value)
    return value
  rescue StandardError => error
    @config.logger.error("[LDClient] Unhandled exception in toggle: (#{error.class.name}) #{error.to_s}\n\t#{error.backtrace.join("\n\t")}")
    default
  end
end

#track(event_name, user, data) ⇒ void

This method returns an undefined value.

Tracks that a user performed an event

Parameters:

  • event_name (String)

    The name of the event

  • user (Hash)

    The user that performed the event. This should be the same user hash used in calls to #toggle?

  • data (Hash)

    A hash containing any additional data associated with the event



209
210
211
# File 'lib/ldclient-rb/ldclient.rb', line 209

def track(event_name, user, data)
  add_event({:kind => 'custom', :key => event_name, :user => user, :data => data })
end