flagsmith 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/.rubocop.yml +4 -1
- data/.rubocop_todo.yml +0 -1
- data/.ruby-version +1 -0
- data/Gemfile.lock +35 -6
- data/LICENCE +4 -5
- data/README.md +8 -64
- data/Rakefile +5 -1
- data/example/.env.development +5 -0
- data/example/.env.test +4 -0
- data/example/.gitignore +5 -0
- data/example/.hanamirc +3 -0
- data/example/.rspec +2 -0
- data/example/Gemfile +25 -0
- data/example/Gemfile.lock +269 -0
- data/example/README.md +29 -0
- data/example/Rakefile +9 -0
- data/example/apps/web/application.rb +162 -0
- data/example/apps/web/config/routes.rb +1 -0
- data/example/apps/web/controllers/.gitkeep +0 -0
- data/example/apps/web/controllers/home/index.rb +32 -0
- data/example/apps/web/templates/application.html.slim +7 -0
- data/example/apps/web/templates/home/index.html.slim +10 -0
- data/example/apps/web/views/application_layout.rb +7 -0
- data/example/apps/web/views/home/index.rb +29 -0
- data/example/config/boot.rb +2 -0
- data/example/config/environment.rb +17 -0
- data/example/config/initializers/.gitkeep +0 -0
- data/example/config/initializers/flagsmith.rb +9 -0
- data/example/config/puma.rb +15 -0
- data/example/config.ru +3 -0
- data/example/spec/example/entities/.gitkeep +0 -0
- data/example/spec/example/mailers/.gitkeep +0 -0
- data/example/spec/example/repositories/.gitkeep +0 -0
- data/example/spec/features_helper.rb +12 -0
- data/example/spec/spec_helper.rb +103 -0
- data/example/spec/support/.gitkeep +0 -0
- data/example/spec/support/capybara.rb +8 -0
- data/example/spec/web/controllers/.gitkeep +0 -0
- data/example/spec/web/controllers/home/index_spec.rb +9 -0
- data/example/spec/web/features/.gitkeep +0 -0
- data/example/spec/web/views/application_layout_spec.rb +10 -0
- data/example/spec/web/views/home/index_spec.rb +10 -0
- data/lib/flagsmith/engine/core.rb +88 -0
- data/lib/flagsmith/engine/environments/models.rb +61 -0
- data/lib/flagsmith/engine/features/models.rb +173 -0
- data/lib/flagsmith/engine/identities/models.rb +115 -0
- data/lib/flagsmith/engine/organisations/models.rb +28 -0
- data/lib/flagsmith/engine/projects/models.rb +31 -0
- data/lib/flagsmith/engine/segments/constants.rb +41 -0
- data/lib/flagsmith/engine/segments/evaluator.rb +68 -0
- data/lib/flagsmith/engine/segments/models.rb +121 -0
- data/lib/flagsmith/engine/utils/hash_func.rb +34 -0
- data/lib/flagsmith/hash_slice.rb +12 -0
- data/lib/flagsmith/sdk/analytics_processor.rb +39 -0
- data/lib/flagsmith/sdk/api_client.rb +47 -0
- data/lib/flagsmith/sdk/config.rb +91 -0
- data/lib/flagsmith/sdk/errors.rb +9 -0
- data/lib/flagsmith/sdk/instance_methods.rb +137 -0
- data/lib/flagsmith/sdk/intervals.rb +24 -0
- data/lib/flagsmith/sdk/models/flag.rb +62 -0
- data/lib/flagsmith/sdk/models/flags/collection.rb +105 -0
- data/lib/flagsmith/sdk/pooling_manager.rb +31 -0
- data/lib/flagsmith/version.rb +5 -0
- data/lib/flagsmith.rb +79 -101
- metadata +104 -6
- data/.gitignore +0 -57
- data/flagsmith.gemspec +0 -22
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module Flagsmith
|
6
|
+
# Ruby client for flagsmith.com
|
7
|
+
class ApiClient
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
HTTP_METHODS_ALLOW_LIST = %i[get post].freeze
|
11
|
+
|
12
|
+
delegate HTTP_METHODS_ALLOW_LIST => :@conn
|
13
|
+
|
14
|
+
def initialize(config)
|
15
|
+
@conn = Faraday.new(url: config.api_url) do |f|
|
16
|
+
build_headers(f, config)
|
17
|
+
f.response :json, parser_options: { symbolize_names: true }
|
18
|
+
f.adapter Faraday.default_adapter
|
19
|
+
|
20
|
+
f.options.timeout = config.request_timeout_seconds
|
21
|
+
configure_logger(f, config)
|
22
|
+
configure_retries(f, config)
|
23
|
+
end
|
24
|
+
|
25
|
+
freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def build_headers(faraday, config)
|
31
|
+
faraday.headers['Accept'] = 'application/json'
|
32
|
+
faraday.headers['Content-Type'] = 'application/json'
|
33
|
+
faraday.headers['X-Environment-Key'] = config.environment_key
|
34
|
+
faraday.headers.merge(config.custom_headers)
|
35
|
+
end
|
36
|
+
|
37
|
+
def configure_logger(faraday, config)
|
38
|
+
faraday.response :logger, config.logger
|
39
|
+
end
|
40
|
+
|
41
|
+
def configure_retries(faraday, config)
|
42
|
+
return unless config.retries
|
43
|
+
|
44
|
+
faraday.request :retry, { max: config.retries }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flagsmith
|
4
|
+
# Config options shared around Engine
|
5
|
+
class Config
|
6
|
+
DEFAULT_API_URL = 'https://edge.api.flagsmith.com/api/v1/'
|
7
|
+
OPTIONS = %i[
|
8
|
+
environment_key api_url custom_headers request_timeout_seconds enable_local_evaluation
|
9
|
+
environment_refresh_interval_seconds retries enable_analytics default_flag_handler logger
|
10
|
+
].freeze
|
11
|
+
|
12
|
+
# Available Configs
|
13
|
+
#
|
14
|
+
# == Options:
|
15
|
+
#
|
16
|
+
# +environment_key+ - The environment key obtained from Flagsmith
|
17
|
+
# interface
|
18
|
+
# +api_url+ - Override the URL of the Flagsmith API to communicate with
|
19
|
+
# +customer_headers+ - Additional headers to add to requests made
|
20
|
+
# to the Flagsmith API
|
21
|
+
# +request_timeout_seconds+ - Number of seconds to wait for a request to
|
22
|
+
# complete before terminating the request
|
23
|
+
# Defaults to 10 seconds
|
24
|
+
# +enable_local_evaluation+ - Enables local evaluation of flags
|
25
|
+
# +environment_refresh_interval_seconds+ - If using local evaluation,
|
26
|
+
# specify the interval period between
|
27
|
+
# refreshes of local environment data
|
28
|
+
# +retries+ - a faraday retry option to use
|
29
|
+
# on all http requests to the Flagsmith API
|
30
|
+
# +enable_analytics+ - if enabled, sends additional requests to the Flagsmith
|
31
|
+
# API to power flag analytics charts
|
32
|
+
# +default_flag_handler+ - ruby block which will be used in the case where
|
33
|
+
# flags cannot be retrieved from the API or
|
34
|
+
# a non existent feature is requested.
|
35
|
+
# The searched feature#name will be passed to the block as an argument.
|
36
|
+
# +logger+ - Pass your logger, default is Logger.new($stdout)
|
37
|
+
#
|
38
|
+
attr_reader(*OPTIONS)
|
39
|
+
|
40
|
+
def initialize(options)
|
41
|
+
build_config(options)
|
42
|
+
|
43
|
+
freeze
|
44
|
+
end
|
45
|
+
|
46
|
+
def local_evaluation?
|
47
|
+
@enable_local_evaluation
|
48
|
+
end
|
49
|
+
|
50
|
+
def enable_analytics?
|
51
|
+
@enable_analytics
|
52
|
+
end
|
53
|
+
|
54
|
+
def environment_flags_url
|
55
|
+
'flags/'
|
56
|
+
end
|
57
|
+
|
58
|
+
def identities_url
|
59
|
+
'identities/'
|
60
|
+
end
|
61
|
+
|
62
|
+
def environment_url
|
63
|
+
'environment-document/'
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
69
|
+
def build_config(options)
|
70
|
+
opts = options.is_a?(String) ? { environment_key: options } : options
|
71
|
+
|
72
|
+
@environment_key = opts.fetch(:environment_key, Flagsmith::Config.environment_key)
|
73
|
+
@api_url = opts.fetch(:api_url, Flagsmith::Config::DEFAULT_API_URL)
|
74
|
+
@custom_headers = opts.fetch(:custom_headers, {})
|
75
|
+
@request_timeout_seconds = opts.fetch(:request_timeout_seconds, 10)
|
76
|
+
@retries = opts[:retries]
|
77
|
+
@enable_local_evaluation = opts.fetch(:enable_local_evaluation, false)
|
78
|
+
@environment_refresh_interval_seconds = opts.fetch(:environment_refresh_interval_seconds, 60)
|
79
|
+
@enable_analytics = opts.fetch(:enable_analytics, false)
|
80
|
+
@default_flag_handler = opts[:default_flag_handler]
|
81
|
+
@logger = options.fetch(:logger, Logger.new($stdout).tap { |l| l.level = :debug })
|
82
|
+
end
|
83
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
84
|
+
|
85
|
+
class << self
|
86
|
+
def environment_key
|
87
|
+
ENV['FLAGSMITH_ENVIRONMENT_KEY']
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flagsmith
|
4
|
+
module SDK
|
5
|
+
# Available Flagsmith Functions
|
6
|
+
module InstanceMethods
|
7
|
+
# Get all the default for flags for the current environment.
|
8
|
+
# @returns Flags object holding all the flags for the current environment.
|
9
|
+
def get_environment_flags # rubocop:disable Naming/AccessorMethodName
|
10
|
+
return environment_flags_from_document if @config.local_evaluation?
|
11
|
+
|
12
|
+
environment_flags_from_api
|
13
|
+
end
|
14
|
+
|
15
|
+
# Get all the flags for the current environment for a given identity. Will also
|
16
|
+
# upsert all traits to the Flagsmith API for future evaluations. Providing a
|
17
|
+
# trait with a value of None will remove the trait from the identity if it exists.
|
18
|
+
#
|
19
|
+
# identifier a unique identifier for the identity in the current
|
20
|
+
# environment, e.g. email address, username, uuid
|
21
|
+
# traits { key => value } is a dictionary of traits to add / update on the identity in
|
22
|
+
# Flagsmith, e.g. { "num_orders": 10 }
|
23
|
+
# returns Flags object holding all the flags for the given identity.
|
24
|
+
def get_identity_flags(identifier, **traits)
|
25
|
+
return get_identity_flags_from_document(identifier, traits) if environment
|
26
|
+
|
27
|
+
get_identity_flags_from_api(identifier, traits)
|
28
|
+
end
|
29
|
+
|
30
|
+
def feature_enabled?(feature_name, default: false)
|
31
|
+
flag = get_environment_flags[feature_name]
|
32
|
+
return default if flag.nil?
|
33
|
+
|
34
|
+
flag.enabled?
|
35
|
+
end
|
36
|
+
|
37
|
+
def feature_enabled_for_identity?(feature_name, user_id, default: false)
|
38
|
+
flag = get_identity_flags(user_id)[feature_name]
|
39
|
+
return default if flag.nil?
|
40
|
+
|
41
|
+
flag.enabled?
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_value(feature_name, default: nil)
|
45
|
+
flag = get_environment_flags[feature_name]
|
46
|
+
return default if flag.nil?
|
47
|
+
|
48
|
+
flag.value
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_value_for_identity(feature_name, user_id = nil, default: nil)
|
52
|
+
flag = get_identity_flags(user_id)[feature_name]
|
53
|
+
return default if flag.nil?
|
54
|
+
|
55
|
+
flag.value
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def environment_flags_from_document
|
61
|
+
Flagsmith::Flags::Collection.from_feature_state_models(
|
62
|
+
get_environment_feature_states(environment),
|
63
|
+
analytics_processor: analytics_processor,
|
64
|
+
default_flag_handler: default_flag_handler
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_identity_flags_from_document(identifier, traits = {})
|
69
|
+
identity_model = build_identity_model(identifier, traits)
|
70
|
+
|
71
|
+
Flagsmith::Flags::Collection.from_feature_state_models(
|
72
|
+
get_identity_feature_states(environment, identity_model),
|
73
|
+
analytics_processor: analytics_processor,
|
74
|
+
default_flag_handler: default_flag_handler
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def environment_flags_from_api
|
79
|
+
rescue_with_default_handler do
|
80
|
+
api_flags = api_client.get(@config.environment_flags_url).body
|
81
|
+
api_flags = api_flags.select { |flag| flag[:feature_segment].nil? }
|
82
|
+
Flagsmith::Flags::Collection.from_api(
|
83
|
+
api_flags,
|
84
|
+
analytics_processor: analytics_processor,
|
85
|
+
default_flag_handler: default_flag_handler
|
86
|
+
)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_identity_flags_from_api(identifier, traits = {})
|
91
|
+
rescue_with_default_handler do
|
92
|
+
data = generate_identities_data(identifier, traits)
|
93
|
+
json_response = api_client.post(@config.identities_url, data.to_json).body
|
94
|
+
|
95
|
+
Flagsmith::Flags::Collection.from_api(
|
96
|
+
json_response[:flags],
|
97
|
+
analytics_processor: analytics_processor,
|
98
|
+
default_flag_handler: default_flag_handler
|
99
|
+
)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def rescue_with_default_handler
|
104
|
+
yield
|
105
|
+
rescue StandardError
|
106
|
+
if default_flag_handler
|
107
|
+
return Flagsmith::Flags::Collection.new(
|
108
|
+
{},
|
109
|
+
default_flag_handler: default_flag_handler
|
110
|
+
)
|
111
|
+
end
|
112
|
+
raise
|
113
|
+
end
|
114
|
+
|
115
|
+
def build_identity_model(identifier, traits = {})
|
116
|
+
unless environment
|
117
|
+
raise Flagsmith::ClientError,
|
118
|
+
'Unable to build identity model when no local environment present.'
|
119
|
+
end
|
120
|
+
|
121
|
+
trait_models = traits.map do |key, value|
|
122
|
+
Flagsmith::Engine::Identities::Trait.new(trait_key: key, trait_value: value)
|
123
|
+
end
|
124
|
+
Flagsmith::Engine::Identity.new(
|
125
|
+
identity_traits: trait_models, environment_api_key: environment_key, identifier: identifier
|
126
|
+
)
|
127
|
+
end
|
128
|
+
|
129
|
+
def generate_identities_data(identifier, traits = {})
|
130
|
+
{
|
131
|
+
identifier: identifier,
|
132
|
+
traits: traits.map { |key, value| { trait_key: key, trait_value: value } }
|
133
|
+
}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flagsmith
|
4
|
+
module SDK
|
5
|
+
# Util functions
|
6
|
+
module Intervals
|
7
|
+
# @return [Thread] return loop thread reference
|
8
|
+
# rubocop:disable Naming/AccessorMethodName
|
9
|
+
def set_interval(delay)
|
10
|
+
Thread.new do
|
11
|
+
loop do
|
12
|
+
sleep delay
|
13
|
+
yield if block_given?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
# rubocop:enable Naming/AccessorMethodName
|
18
|
+
|
19
|
+
def clear_interval(thread)
|
20
|
+
thread.kill
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flagsmith
|
4
|
+
# Flag object
|
5
|
+
class Flag
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
attr_reader :enabled, :value, :default, :feature_name, :feature_id
|
9
|
+
|
10
|
+
def initialize(feature_name:, enabled:, value:, feature_id:, default: false)
|
11
|
+
@feature_name = feature_name
|
12
|
+
@feature_id = feature_id
|
13
|
+
@enabled = enabled
|
14
|
+
@value = value
|
15
|
+
@default = default
|
16
|
+
end
|
17
|
+
|
18
|
+
def enabled?
|
19
|
+
@enabled
|
20
|
+
end
|
21
|
+
|
22
|
+
alias is_default default
|
23
|
+
|
24
|
+
def <=>(other)
|
25
|
+
feature_name <=> other.feature_name
|
26
|
+
end
|
27
|
+
|
28
|
+
def [](key)
|
29
|
+
to_h[key]
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_h
|
33
|
+
{
|
34
|
+
feature_id: feature_id,
|
35
|
+
feature_name: feature_name,
|
36
|
+
value: value,
|
37
|
+
enabled: enabled,
|
38
|
+
default: default
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
class << self
|
43
|
+
def from_feature_state_model(feature_state_model, identity_id)
|
44
|
+
new(
|
45
|
+
enabled: feature_state_model.enabled,
|
46
|
+
value: feature_state_model.get_value(identity_id),
|
47
|
+
feature_name: feature_state_model.feature.name,
|
48
|
+
feature_id: feature_state_model.feature.id
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def from_api(json_flag_data)
|
53
|
+
new(
|
54
|
+
enabled: json_flag_data[:enabled],
|
55
|
+
value: json_flag_data[:feature_state_value] || json_flag_data[:value],
|
56
|
+
feature_name: json_flag_data.dig(:feature, :name),
|
57
|
+
feature_id: json_flag_data.dig(:feature, :id)
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Flagsmith
|
4
|
+
module Flags
|
5
|
+
class NotFound < StandardError; end
|
6
|
+
|
7
|
+
# Flag Collection
|
8
|
+
class Collection
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
attr_reader :flags, :default_flag_handler, :analytics_processor
|
12
|
+
|
13
|
+
def initialize(flags = {}, analytics_processor: nil, default_flag_handler: nil)
|
14
|
+
@flags = flags
|
15
|
+
@default_flag_handler = default_flag_handler
|
16
|
+
@analytics_processor = analytics_processor
|
17
|
+
end
|
18
|
+
|
19
|
+
def each(&block)
|
20
|
+
flags.each { |item| block&.call(item) || item }
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_a
|
24
|
+
@flags.values || []
|
25
|
+
end
|
26
|
+
alias all_flags to_a
|
27
|
+
|
28
|
+
# Check whether a given feature is enabled.
|
29
|
+
# :param feature_name: the name of the feature to check if enabled.
|
30
|
+
# :return: Boolean representing the enabled state of a given feature.
|
31
|
+
# :raises FlagsmithClientError: if feature doesn't exist
|
32
|
+
def feature_enabled?(feature_name)
|
33
|
+
get_flag(feature_name).enabled?
|
34
|
+
end
|
35
|
+
alias is_feature_enabled feature_enabled?
|
36
|
+
|
37
|
+
# Get the value of a particular feature.
|
38
|
+
# :param feature_name: the name of the feature to retrieve the value of.
|
39
|
+
# :return: the value of the given feature.
|
40
|
+
# :raises FlagsmithClientError: if feature doesn't exist
|
41
|
+
def feature_value(feature_name)
|
42
|
+
get_flag(feature_name).value
|
43
|
+
end
|
44
|
+
alias get_feature_value feature_value
|
45
|
+
|
46
|
+
# Get a specific flag given the feature name.
|
47
|
+
# :param feature_name: the name of the feature to retrieve the flag for.
|
48
|
+
# :return: BaseFlag object.
|
49
|
+
# :raises FlagsmithClientError: if feature doesn't exist
|
50
|
+
def get_flag(feature_name)
|
51
|
+
key = Flagsmith::Flags::Collection.normalize_key(feature_name)
|
52
|
+
flag = flags.fetch(key)
|
53
|
+
@analytics_processor.track_feature(flag.feature_id) if @analytics_processor && flag.feature_id
|
54
|
+
flag
|
55
|
+
rescue KeyError
|
56
|
+
return @default_flag_handler.call(feature_name) if @default_flag_handler
|
57
|
+
|
58
|
+
raise Flagsmith::Flags::NotFound,
|
59
|
+
"Feature does not exist: #{key}, implement default_flag_handler to handle this case."
|
60
|
+
end
|
61
|
+
|
62
|
+
def [](key)
|
63
|
+
key.is_a?(Integer) ? to_a[key] : get_flag(key)
|
64
|
+
end
|
65
|
+
|
66
|
+
def length
|
67
|
+
to_a.length
|
68
|
+
end
|
69
|
+
|
70
|
+
def inspect
|
71
|
+
"<##{self.class}:#{object_id.to_s(8)} flags=#{@flags}>"
|
72
|
+
end
|
73
|
+
|
74
|
+
class << self
|
75
|
+
def from_api(json_data, **args)
|
76
|
+
to_flag_object = lambda { |json_flag, acc|
|
77
|
+
acc[normalize_key(json_flag.dig(:feature, :name))] =
|
78
|
+
Flagsmith::Flag.from_api(json_flag)
|
79
|
+
}
|
80
|
+
|
81
|
+
new(
|
82
|
+
json_data.each_with_object({}, &to_flag_object),
|
83
|
+
**args
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
def from_feature_state_models(feature_states, identity_id: nil, **args)
|
88
|
+
to_flag_object = lambda { |feature_state, acc|
|
89
|
+
acc[normalize_key(feature_state.feature.name)] =
|
90
|
+
Flagsmith::Flag.from_feature_state_model(feature_state, identity_id)
|
91
|
+
}
|
92
|
+
|
93
|
+
new(
|
94
|
+
feature_states.each_with_object({}, &to_flag_object),
|
95
|
+
**args
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
def normalize_key(key)
|
100
|
+
key.to_s.downcase
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'intervals'
|
4
|
+
|
5
|
+
module Flagsmith
|
6
|
+
# Manager to asynchronously fetch the environment
|
7
|
+
class EnvironmentDataPollingManager
|
8
|
+
include Flagsmith::SDK::Intervals
|
9
|
+
|
10
|
+
def initialize(main, refresh_interval_seconds)
|
11
|
+
@main = main
|
12
|
+
@refresh_interval_seconds = refresh_interval_seconds
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
update_environment = lambda {
|
17
|
+
stop
|
18
|
+
@interval = set_interval(@refresh_interval_seconds) { @main.update_environment }
|
19
|
+
}
|
20
|
+
|
21
|
+
# TODO: this call should be awaited for getIdentityFlags/getEnvironmentFlags when enableLocalEvaluation is true
|
22
|
+
update_environment.call
|
23
|
+
end
|
24
|
+
|
25
|
+
def stop
|
26
|
+
return unless @interval
|
27
|
+
|
28
|
+
clear_interval(@interval)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|