Class: FeatBit::Client
- Inherits:
-
Object
- Object
- FeatBit::Client
- Defined in:
- lib/featbit/client.rb
Instance Attribute Summary collapse
-
#data_store ⇒ Object
readonly
Returns the value of attribute data_store.
-
#event_processor ⇒ Object
readonly
Returns the value of attribute event_processor.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#status_provider ⇒ Object
readonly
Returns the value of attribute status_provider.
Instance Method Summary collapse
- #add_flag_change_listener(callable = nil, &block) ⇒ Object
- #bool_variation(flag_key, user, default_value = false) ⇒ Object
- #close ⇒ Object (also: #stop)
- #flush ⇒ Object
-
#initialize(options = Options.new) ⇒ Client
constructor
A new instance of Client.
- #initialized? ⇒ Boolean
- #json_variation(flag_key, user, default_value = {}) ⇒ Object
- #number_variation(flag_key, user, default_value = 0) ⇒ Object
- #remove_flag_change_listener(id) ⇒ Object
- #string_variation(flag_key, user, default_value = "") ⇒ Object
- #track(user, event_name, numeric_value = 1.0) ⇒ Object
- #variation(flag_key, user, default_value) ⇒ Object
- #variation_detail(flag_key, user, default_value) ⇒ Object
Constructor Details
#initialize(options = Options.new) ⇒ Client
Returns a new instance of Client.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/featbit/client.rb', line 9 def initialize( = Options.new) @options = .is_a?(Options) ? : Options.new(offline: true) @data_store = @options.data_store || InMemoryDataStore.new initial_status = @options.offline ? Status::OFFLINE : Status::STARTING @status_provider = StatusProvider.new(initial_status, logger: @options.logger) @listeners = {} @listener_id = 0 @listener_mutex = Mutex.new @lifecycle_mutex = Mutex.new @closed = false @close_result = nil load_bootstrap(@options.bootstrap) if @options.bootstrap @event_processor = build_event_processor @evaluator = Evaluator.new( flag_getter: ->(key) { @data_store.flag(key) }, segment_getter: ->(id) { @data_store.segment(id) }, logger: @options.logger ) start_synchronizer unless @options.offline @status_provider.update(Status::READY) if @options.offline && @data_store.initialized? @status_provider.wait_until_ready(@options.start_wait) if !@options.offline && @options.start_wait.positive? rescue StandardError => e safe_log(:error, "FeatBit client initialization failed: #{e.}") @status_provider ||= StatusProvider.new(Status::FAILED) @status_provider.update(Status::FAILED, message: e.) @event_processor ||= NullEventProcessor.new end |
Instance Attribute Details
#data_store ⇒ Object (readonly)
Returns the value of attribute data_store.
7 8 9 |
# File 'lib/featbit/client.rb', line 7 def data_store @data_store end |
#event_processor ⇒ Object (readonly)
Returns the value of attribute event_processor.
7 8 9 |
# File 'lib/featbit/client.rb', line 7 def event_processor @event_processor end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
7 8 9 |
# File 'lib/featbit/client.rb', line 7 def @options end |
#status_provider ⇒ Object (readonly)
Returns the value of attribute status_provider.
7 8 9 |
# File 'lib/featbit/client.rb', line 7 def status_provider @status_provider end |
Instance Method Details
#add_flag_change_listener(callable = nil, &block) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/featbit/client.rb', line 105 def add_flag_change_listener(callable = nil, &block) listener = callable || block return nil unless listener.respond_to?(:call) @listener_mutex.synchronize do @listener_id += 1 @listeners[@listener_id] = listener @listener_id end rescue StandardError nil end |
#bool_variation(flag_key, user, default_value = false) ⇒ Object
63 64 65 |
# File 'lib/featbit/client.rb', line 63 def bool_variation(flag_key, user, default_value = false) typed_variation(flag_key, user, default_value, [TrueClass, FalseClass]) end |
#close ⇒ Object Also known as: stop
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/featbit/client.rb', line 124 def close @lifecycle_mutex.synchronize do return @close_result unless @close_result.nil? return true if @closed @closed = true end results = [safe_close(@synchronizer), safe_close(@event_processor)] results << safe_status_update(Status::CLOSED) @lifecycle_mutex.synchronize { @close_result = results.all? } rescue StandardError => e safe_log(:warn, "FeatBit client close failed: #{e.}") false end |
#flush ⇒ Object
99 100 101 102 103 |
# File 'lib/featbit/client.rb', line 99 def flush @event_processor.flush rescue StandardError false end |
#initialized? ⇒ Boolean
38 39 40 41 42 |
# File 'lib/featbit/client.rb', line 38 def initialized? @data_store.initialized? rescue StandardError false end |
#json_variation(flag_key, user, default_value = {}) ⇒ Object
75 76 77 |
# File 'lib/featbit/client.rb', line 75 def json_variation(flag_key, user, default_value = {}) typed_variation(flag_key, user, default_value, [Hash, Array]) end |
#number_variation(flag_key, user, default_value = 0) ⇒ Object
71 72 73 |
# File 'lib/featbit/client.rb', line 71 def number_variation(flag_key, user, default_value = 0) typed_variation(flag_key, user, default_value, [Numeric]) end |
#remove_flag_change_listener(id) ⇒ Object
118 119 120 121 122 |
# File 'lib/featbit/client.rb', line 118 def remove_flag_change_listener(id) @listener_mutex.synchronize { !@listeners.delete(id).nil? } rescue StandardError false end |
#string_variation(flag_key, user, default_value = "") ⇒ Object
67 68 69 |
# File 'lib/featbit/client.rb', line 67 def string_variation(flag_key, user, default_value = "") typed_variation(flag_key, user, default_value, [String]) end |
#track(user, event_name, numeric_value = 1.0) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/featbit/client.rb', line 79 def track(user, event_name, numeric_value = 1.0) normalized_user = normalize_user(user) return false unless normalized_user.valid? && !event_name.to_s.empty? @event_processor.enqueue( user: normalized_user.to_h, metrics: [{ eventName: event_name.to_s, numericValue: numeric_value.to_f, route: "index/metric", type: "CustomEvent", appType: "ruby-server-side", timestamp: }] ) rescue StandardError => e safe_log(:warn, "FeatBit track failed: #{e.}") false end |
#variation(flag_key, user, default_value) ⇒ Object
44 45 46 47 48 49 |
# File 'lib/featbit/client.rb', line 44 def variation(flag_key, user, default_value) variation_detail(flag_key, user, default_value).value rescue StandardError => e safe_log(:error, "FeatBit variation failed: #{e.}") default_value end |
#variation_detail(flag_key, user, default_value) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/featbit/client.rb', line 51 def variation_detail(flag_key, user, default_value) return safe_detail(flag_key, default_value, :client_not_ready) if @closed || !evaluable? normalized_user = normalize_user(user) detail = @evaluator.evaluate(flag_key, normalized_user, default_value) enqueue_evaluation(detail, normalized_user) if detail.success? detail rescue StandardError => e safe_log(:error, "FeatBit variation detail failed: #{e.}") safe_detail(flag_key, default_value, :error, e.) end |