launchdarkly-server-sdk 6.4.0 → 7.0.1
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/lib/ldclient-rb/config.rb +102 -56
- data/lib/ldclient-rb/context.rb +487 -0
- data/lib/ldclient-rb/evaluation_detail.rb +20 -20
- data/lib/ldclient-rb/events.rb +77 -132
- data/lib/ldclient-rb/flags_state.rb +4 -4
- data/lib/ldclient-rb/impl/big_segments.rb +17 -17
- data/lib/ldclient-rb/impl/context.rb +96 -0
- data/lib/ldclient-rb/impl/context_filter.rb +145 -0
- data/lib/ldclient-rb/impl/diagnostic_events.rb +9 -10
- data/lib/ldclient-rb/impl/evaluator.rb +379 -131
- data/lib/ldclient-rb/impl/evaluator_bucketing.rb +40 -41
- data/lib/ldclient-rb/impl/evaluator_helpers.rb +31 -34
- data/lib/ldclient-rb/impl/evaluator_operators.rb +26 -55
- data/lib/ldclient-rb/impl/event_sender.rb +6 -6
- data/lib/ldclient-rb/impl/event_summarizer.rb +12 -7
- data/lib/ldclient-rb/impl/event_types.rb +18 -30
- data/lib/ldclient-rb/impl/integrations/consul_impl.rb +7 -7
- data/lib/ldclient-rb/impl/integrations/dynamodb_impl.rb +29 -29
- data/lib/ldclient-rb/impl/integrations/file_data_source.rb +8 -8
- data/lib/ldclient-rb/impl/integrations/redis_impl.rb +92 -12
- data/lib/ldclient-rb/impl/model/clause.rb +45 -0
- data/lib/ldclient-rb/impl/model/feature_flag.rb +232 -0
- data/lib/ldclient-rb/impl/model/preprocessed_data.rb +8 -121
- data/lib/ldclient-rb/impl/model/segment.rb +132 -0
- data/lib/ldclient-rb/impl/model/serialization.rb +52 -12
- data/lib/ldclient-rb/impl/repeating_task.rb +1 -1
- data/lib/ldclient-rb/impl/store_data_set_sorter.rb +2 -2
- data/lib/ldclient-rb/impl/unbounded_pool.rb +1 -1
- data/lib/ldclient-rb/impl/util.rb +2 -2
- data/lib/ldclient-rb/in_memory_store.rb +2 -2
- data/lib/ldclient-rb/integrations/consul.rb +1 -1
- data/lib/ldclient-rb/integrations/dynamodb.rb +1 -1
- data/lib/ldclient-rb/integrations/file_data.rb +3 -3
- data/lib/ldclient-rb/integrations/redis.rb +4 -4
- data/lib/ldclient-rb/integrations/test_data/flag_builder.rb +218 -62
- data/lib/ldclient-rb/integrations/test_data.rb +16 -12
- data/lib/ldclient-rb/integrations/util/store_wrapper.rb +9 -9
- data/lib/ldclient-rb/interfaces.rb +14 -14
- data/lib/ldclient-rb/ldclient.rb +94 -144
- data/lib/ldclient-rb/memoized_value.rb +1 -1
- data/lib/ldclient-rb/non_blocking_thread_pool.rb +1 -1
- data/lib/ldclient-rb/polling.rb +2 -2
- data/lib/ldclient-rb/reference.rb +274 -0
- data/lib/ldclient-rb/requestor.rb +5 -5
- data/lib/ldclient-rb/stream.rb +7 -8
- data/lib/ldclient-rb/util.rb +4 -19
- data/lib/ldclient-rb/version.rb +1 -1
- data/lib/ldclient-rb.rb +2 -3
- metadata +34 -17
- data/lib/ldclient-rb/file_data_source.rb +0 -23
- data/lib/ldclient-rb/newrelic.rb +0 -17
- data/lib/ldclient-rb/redis_store.rb +0 -88
- data/lib/ldclient-rb/user_filter.rb +0 -52
@@ -1,88 +0,0 @@
|
|
1
|
-
require "ldclient-rb/interfaces"
|
2
|
-
require "ldclient-rb/impl/integrations/redis_impl"
|
3
|
-
|
4
|
-
module LaunchDarkly
|
5
|
-
#
|
6
|
-
# An implementation of the LaunchDarkly client's feature store that uses a Redis
|
7
|
-
# instance. This object holds feature flags and related data received from the
|
8
|
-
# streaming API. Feature data can also be further cached in memory to reduce overhead
|
9
|
-
# of calls to Redis.
|
10
|
-
#
|
11
|
-
# To use this class, you must first have the `redis` and `connection-pool` gems
|
12
|
-
# installed. Then, create an instance and store it in the `feature_store` property
|
13
|
-
# of your client configuration.
|
14
|
-
#
|
15
|
-
# @deprecated Use the factory method in {LaunchDarkly::Integrations::Redis} instead. This specific
|
16
|
-
# implementation class may be changed or removed in the future.
|
17
|
-
#
|
18
|
-
class RedisFeatureStore
|
19
|
-
include LaunchDarkly::Interfaces::FeatureStore
|
20
|
-
|
21
|
-
# Note that this class is now just a facade around CachingStoreWrapper, which is in turn delegating
|
22
|
-
# to RedisFeatureStoreCore where the actual database logic is. This class was retained for historical
|
23
|
-
# reasons, so that existing code can still call RedisFeatureStore.new. In the future, we will migrate
|
24
|
-
# away from exposing these concrete classes and use factory methods instead.
|
25
|
-
|
26
|
-
#
|
27
|
-
# Constructor for a RedisFeatureStore instance.
|
28
|
-
#
|
29
|
-
# @param opts [Hash] the configuration options
|
30
|
-
# @option opts [String] :redis_url URL of the Redis instance (shortcut for omitting redis_opts)
|
31
|
-
# @option opts [Hash] :redis_opts options to pass to the Redis constructor (if you want to specify more than just redis_url)
|
32
|
-
# @option opts [String] :prefix namespace prefix to add to all hash keys used by LaunchDarkly
|
33
|
-
# @option opts [Logger] :logger a `Logger` instance; defaults to `Config.default_logger`
|
34
|
-
# @option opts [Integer] :max_connections size of the Redis connection pool
|
35
|
-
# @option opts [Integer] :expiration expiration time for the in-memory cache, in seconds; 0 for no local caching
|
36
|
-
# @option opts [Integer] :capacity maximum number of feature flags (or related objects) to cache locally
|
37
|
-
# @option opts [Object] :pool custom connection pool, if desired
|
38
|
-
# @option opts [Boolean] :pool_shutdown_on_close whether calling `close` should shutdown the custom connection pool.
|
39
|
-
#
|
40
|
-
def initialize(opts = {})
|
41
|
-
core = LaunchDarkly::Impl::Integrations::Redis::RedisFeatureStoreCore.new(opts)
|
42
|
-
@wrapper = LaunchDarkly::Integrations::Util::CachingStoreWrapper.new(core, opts)
|
43
|
-
end
|
44
|
-
|
45
|
-
#
|
46
|
-
# Default value for the `redis_url` constructor parameter; points to an instance of Redis
|
47
|
-
# running at `localhost` with its default port.
|
48
|
-
#
|
49
|
-
def self.default_redis_url
|
50
|
-
LaunchDarkly::Integrations::Redis::default_redis_url
|
51
|
-
end
|
52
|
-
|
53
|
-
#
|
54
|
-
# Default value for the `prefix` constructor parameter.
|
55
|
-
#
|
56
|
-
def self.default_prefix
|
57
|
-
LaunchDarkly::Integrations::Redis::default_prefix
|
58
|
-
end
|
59
|
-
|
60
|
-
def get(kind, key)
|
61
|
-
@wrapper.get(kind, key)
|
62
|
-
end
|
63
|
-
|
64
|
-
def all(kind)
|
65
|
-
@wrapper.all(kind)
|
66
|
-
end
|
67
|
-
|
68
|
-
def delete(kind, key, version)
|
69
|
-
@wrapper.delete(kind, key, version)
|
70
|
-
end
|
71
|
-
|
72
|
-
def init(all_data)
|
73
|
-
@wrapper.init(all_data)
|
74
|
-
end
|
75
|
-
|
76
|
-
def upsert(kind, item)
|
77
|
-
@wrapper.upsert(kind, item)
|
78
|
-
end
|
79
|
-
|
80
|
-
def initialized?
|
81
|
-
@wrapper.initialized?
|
82
|
-
end
|
83
|
-
|
84
|
-
def stop
|
85
|
-
@wrapper.stop
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require "json"
|
2
|
-
require "set"
|
3
|
-
|
4
|
-
module LaunchDarkly
|
5
|
-
# @private
|
6
|
-
class UserFilter
|
7
|
-
def initialize(config)
|
8
|
-
@all_attributes_private = config.all_attributes_private
|
9
|
-
@private_attribute_names = Set.new(config.private_attribute_names.map(&:to_sym))
|
10
|
-
end
|
11
|
-
|
12
|
-
def transform_user_props(user_props)
|
13
|
-
return nil if user_props.nil?
|
14
|
-
|
15
|
-
user_private_attrs = Set.new((user_props[:privateAttributeNames] || []).map(&:to_sym))
|
16
|
-
|
17
|
-
filtered_user_props, removed = filter_values(user_props, user_private_attrs, ALLOWED_TOP_LEVEL_KEYS, IGNORED_TOP_LEVEL_KEYS)
|
18
|
-
custom = user_props[:custom]
|
19
|
-
if !custom.nil?
|
20
|
-
filtered_user_props[:custom], removed_custom = filter_values(custom, user_private_attrs)
|
21
|
-
removed.merge(removed_custom)
|
22
|
-
end
|
23
|
-
|
24
|
-
unless removed.empty?
|
25
|
-
# note, :privateAttributeNames is what the developer sets; :privateAttrs is what we send to the server
|
26
|
-
filtered_user_props[:privateAttrs] = removed.to_a.sort.map { |s| s.to_s }
|
27
|
-
end
|
28
|
-
return filtered_user_props
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
ALLOWED_TOP_LEVEL_KEYS = Set.new([:key, :secondary, :ip, :country, :email,
|
34
|
-
:firstName, :lastName, :avatar, :name, :anonymous, :custom])
|
35
|
-
IGNORED_TOP_LEVEL_KEYS = Set.new([:custom, :key, :anonymous])
|
36
|
-
|
37
|
-
def filter_values(props, user_private_attrs, allowed_keys = [], keys_to_leave_as_is = [])
|
38
|
-
is_valid_key = lambda { |key| allowed_keys.empty? || allowed_keys.include?(key) }
|
39
|
-
removed_keys = Set.new(props.keys.select { |key|
|
40
|
-
# Note that if is_valid_key returns false, we don't explicitly *remove* the key (which would place
|
41
|
-
# it in the privateAttrs list) - we just silently drop it when we calculate filtered_hash.
|
42
|
-
is_valid_key.call(key) && !keys_to_leave_as_is.include?(key) && private_attr?(key, user_private_attrs)
|
43
|
-
})
|
44
|
-
filtered_hash = props.select { |key, value| !removed_keys.include?(key) && is_valid_key.call(key) }
|
45
|
-
[filtered_hash, removed_keys]
|
46
|
-
end
|
47
|
-
|
48
|
-
def private_attr?(name, user_private_attrs)
|
49
|
-
@all_attributes_private || @private_attribute_names.include?(name) || user_private_attrs.include?(name)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|