11# frozen_string_literal: true
2+ require "pry"
3+ require "pry-byebug"
24
35require 'faraday'
46require 'faraday/retry'
1618require 'flagsmith/sdk/pooling_manager'
1719require 'flagsmith/sdk/models/flags'
1820require 'flagsmith/sdk/models/segments'
21+ require 'flagsmith/sdk/offline_handlers'
1922
2023require 'flagsmith/engine/core'
2124
@@ -44,7 +47,9 @@ class Client # rubocop:disable Metrics/ClassLength
4447 # Available Configs.
4548 #
4649 # :environment_key, :api_url, :custom_headers, :request_timeout_seconds, :enable_local_evaluation,
47- # :environment_refresh_interval_seconds, :retries, :enable_analytics, :default_flag_handler
50+ # :environment_refresh_interval_seconds, :retries, :enable_analytics, :default_flag_handler,
51+ # :offline_mode, :offline_handler
52+ #
4853 # You can see full description in the Flagsmith::Config
4954
5055 attr_reader :config , :environment
@@ -55,10 +60,24 @@ def initialize(config)
5560 @_mutex = Mutex . new
5661 @config = Flagsmith ::Config . new ( config )
5762
63+ validate_offline_mode!
64+
5865 api_client
5966 analytics_processor
6067 environment_data_polling_manager
6168 engine
69+ load_offline_handler
70+ end
71+
72+ def validate_offline_mode!
73+ if @config . offline_mode? and not @config . offline_handler
74+ raise Flagsmith ::ClientError ,
75+ 'The offline_mode config param requires a matching offline_handler.'
76+ end
77+ if @config . offline_handler and @config . default_flag_handler
78+ raise Flagsmith ::ClientError ,
79+ 'Cannot use offline_handler and default_flag_handler at the same time.'
80+ end
6281 end
6382
6483 def api_client
@@ -79,6 +98,10 @@ def analytics_processor
7998 )
8099 end
81100
101+ def load_offline_handler
102+ @environment = offline_handler . environment if offline_handler
103+ end
104+
82105 def environment_data_polling_manager
83106 return nil unless @config . local_evaluation?
84107
@@ -103,7 +126,9 @@ def environment_from_api
103126 # Get all the default for flags for the current environment.
104127 # @returns Flags object holding all the flags for the current environment.
105128 def get_environment_flags # rubocop:disable Naming/AccessorMethodName
106- return environment_flags_from_document if @config . local_evaluation?
129+ if @config . local_evaluation? or @config . offline_mode
130+ return environment_flags_from_document
131+ end
107132
108133 environment_flags_from_api
109134 end
@@ -154,7 +179,7 @@ def get_value_for_identity(feature_name, user_id = nil, default: nil)
154179 def get_identity_segments ( identifier , traits = { } )
155180 unless environment
156181 raise Flagsmith ::ClientError ,
157- 'Local evaluation required to obtain identity segments.'
182+ 'Local evaluation or offline handler is required to obtain identity segments.'
158183 end
159184
160185 identity_model = build_identity_model ( identifier , traits )
@@ -168,7 +193,8 @@ def environment_flags_from_document
168193 Flagsmith ::Flags ::Collection . from_feature_state_models (
169194 engine . get_environment_feature_states ( environment ) ,
170195 analytics_processor : analytics_processor ,
171- default_flag_handler : default_flag_handler
196+ default_flag_handler : default_flag_handler ,
197+ offline_handler : offline_handler ,
172198 )
173199 end
174200
@@ -178,35 +204,62 @@ def get_identity_flags_from_document(identifier, traits = {})
178204 Flagsmith ::Flags ::Collection . from_feature_state_models (
179205 engine . get_identity_feature_states ( environment , identity_model ) ,
180206 analytics_processor : analytics_processor ,
181- default_flag_handler : default_flag_handler
207+ default_flag_handler : default_flag_handler ,
208+ offline_handler : offline_handler ,
182209 )
183210 end
184211
185212 def environment_flags_from_api
186- rescue_with_default_handler do
187- api_flags = api_client . get ( @config . environment_flags_url ) . body
188- api_flags = api_flags . select { |flag | flag [ :feature_segment ] . nil? }
189- Flagsmith ::Flags ::Collection . from_api (
190- api_flags ,
191- analytics_processor : analytics_processor ,
192- default_flag_handler : default_flag_handler
193- )
213+ if offline_handler
214+ begin
215+ return _environment_flags_from_api
216+ rescue
217+ return environment_flags_from_document
218+ end
219+ else
220+ rescue_with_default_handler do
221+ return _environment_flags_from_api
222+ end
194223 end
195224 end
196225
197- def get_identity_flags_from_api ( identifier , traits = { } )
198- rescue_with_default_handler do
199- data = generate_identities_data ( identifier , traits )
200- json_response = api_client . post ( @config . identities_url , data . to_json ) . body
226+ def _environment_flags_from_api
227+ api_flags = api_client . get ( @config . environment_flags_url ) . body
228+ api_flags = api_flags . select { |flag | flag [ :feature_segment ] . nil? }
229+ Flagsmith ::Flags ::Collection . from_api (
230+ api_flags ,
231+ analytics_processor : analytics_processor ,
232+ default_flag_handler : default_flag_handler ,
233+ offline_handler : offline_handler
234+ )
235+ end
201236
202- Flagsmith ::Flags ::Collection . from_api (
203- json_response [ :flags ] ,
204- analytics_processor : analytics_processor ,
205- default_flag_handler : default_flag_handler
206- )
237+ def get_identity_flags_from_api ( identifier , traits = { } )
238+ if offline_handler
239+ begin
240+ return _get_identity_flags_from_api ( identifier , traits )
241+ rescue
242+ return get_identity_flags_from_document ( identifier , traits )
243+ end
244+ else
245+ rescue_with_default_handler do
246+ return _get_identity_flags_from_api ( identifier , traits )
247+ end
207248 end
208249 end
209250
251+ def _get_identity_flags_from_api ( identifier , traits = { } )
252+ data = generate_identities_data ( identifier , traits )
253+ json_response = api_client . post ( @config . identities_url , data . to_json ) . body
254+
255+ Flagsmith ::Flags ::Collection . from_api (
256+ json_response [ :flags ] ,
257+ analytics_processor : analytics_processor ,
258+ default_flag_handler : default_flag_handler ,
259+ offline_handler : offline_handler
260+ )
261+ end
262+
210263 def rescue_with_default_handler
211264 yield
212265 rescue StandardError
0 commit comments