launchdarkly-server-sdk 8.7.1 → 8.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1692535bf245c0627c6e08cb87f168b11d7518d895bf9faacb2858da227f9d70
4
- data.tar.gz: fa60f044217ac286dd817b325ea87c431ce0399decc5ee84741638959b1a5697
3
+ metadata.gz: 508b6894ca8b1448c28d0358429561282e11b08569750eb2bc6200fa25b7a9ea
4
+ data.tar.gz: 335c7acd3d8903907489b88488976fdbe399f3f60e7a8ee4a1b99f525a42b2a0
5
5
  SHA512:
6
- metadata.gz: 92fc2011f8a0a8ca594863155081e60abfdeec0be8d50a1ebf051ed0a7a97406eac7560a12cf9a5c2beed7de71b58ff0dc720569b67f65f2f582fb2f7b1528c0
7
- data.tar.gz: e6a8b529997e0df8dfdf2a1b82c716211661bbeece2b50777146b5c6fdb7c8d97f69d23057ad6586b0730c9717fcb15b07a9808213da21ad7f9fbc91595c91f9
6
+ metadata.gz: 1656cd73d98bbfabf94b0efb14a07254c8018eee30e204fa0eca1ab531f8b314cb044404a023e6e51c04c967e46d2cecab8db880785540cd072c72e220152cad
7
+ data.tar.gz: 59fa0d6dff4c5ae6f366dca1da7831370c7838145bd4f21883ef74deb1897ebe76f26a8851b75beccace2d242bb0531d374a3cd047ff45638b1a445d2dd56b8d
@@ -38,6 +38,7 @@ module LaunchDarkly
38
38
  meta[:version] = flag_state[:version]
39
39
  end
40
40
 
41
+ meta[:prerequisites] = flag_state[:prerequisites] unless flag_state[:prerequisites].nil? || flag_state[:prerequisites].empty?
41
42
  meta[:variation] = flag_state[:variation] unless flag_state[:variation].nil?
42
43
  meta[:trackEvents] = true if flag_state[:trackEvents]
43
44
  meta[:trackReason] = true if flag_state[:trackReason]
@@ -4,6 +4,56 @@ require "ldclient-rb/interfaces"
4
4
  module LaunchDarkly
5
5
  module Impl
6
6
  module DataStore
7
+
8
+ class DataKind
9
+ FEATURES = "features".freeze
10
+ SEGMENTS = "segments".freeze
11
+
12
+ FEATURE_PREREQ_FN = lambda { |flag| (flag[:prerequisites] || []).map { |p| p[:key] } }.freeze
13
+
14
+ attr_reader :namespace
15
+ attr_reader :priority
16
+
17
+ #
18
+ # @param namespace [String]
19
+ # @param priority [Integer]
20
+ #
21
+ def initialize(namespace:, priority:)
22
+ @namespace = namespace
23
+ @priority = priority
24
+ end
25
+
26
+ #
27
+ # Maintain the same behavior when these data kinds were standard ruby hashes.
28
+ #
29
+ # @param key [Symbol]
30
+ # @return [Object]
31
+ #
32
+ def [](key)
33
+ return priority if key == :priority
34
+ return namespace if key == :namespace
35
+ return get_dependency_keys_fn() if key == :get_dependency_keys
36
+ nil
37
+ end
38
+
39
+ #
40
+ # Retrieve the dependency keys for a particular data kind. Right now, this is only defined for flags.
41
+ #
42
+ def get_dependency_keys_fn()
43
+ return nil unless @namespace == FEATURES
44
+
45
+ FEATURE_PREREQ_FN
46
+ end
47
+
48
+ def eql?(other)
49
+ namespace == other.namespace && priority == other.priority
50
+ end
51
+
52
+ def hash
53
+ [namespace, priority].hash
54
+ end
55
+ end
56
+
7
57
  class StatusProvider
8
58
  include LaunchDarkly::Interfaces::DataStore::StatusProvider
9
59
 
@@ -32,8 +32,16 @@ module LaunchDarkly
32
32
  def initialize(original_flag)
33
33
  @prereq_stack = EvaluatorStack.new(original_flag.key)
34
34
  @segment_stack = EvaluatorStack.new(nil)
35
+ @prerequisites = []
36
+ @depth = 0
35
37
  end
36
38
 
39
+ def record_evaluated_prereq_key(key)
40
+ @prerequisites.push(key) if @depth.zero?
41
+ end
42
+
43
+ attr_accessor :depth
44
+ attr_reader :prerequisites
37
45
  attr_reader :prereq_stack
38
46
  attr_reader :segment_stack
39
47
  end
@@ -135,7 +143,8 @@ module LaunchDarkly
135
143
  #
136
144
  # @param flag [LaunchDarkly::Impl::Model::FeatureFlag] the flag
137
145
  # @param context [LaunchDarkly::LDContext] the evaluation context
138
- # @return [EvalResult] the evaluation result
146
+ # @return [Array<EvalResult, EvaluatorState>] the evaluation result and a state object that may be used for
147
+ # inspecting the evaluation process
139
148
  def evaluate(flag, context)
140
149
  state = EvaluatorState.new(flag)
141
150
 
@@ -145,11 +154,11 @@ module LaunchDarkly
145
154
  rescue EvaluationException => exn
146
155
  LaunchDarkly::Util.log_exception(@logger, "Unexpected error when evaluating flag #{flag.key}", exn)
147
156
  result.detail = EvaluationDetail.new(nil, nil, EvaluationReason::error(exn.error_kind))
148
- return result
157
+ return result, state
149
158
  rescue => exn
150
159
  LaunchDarkly::Util.log_exception(@logger, "Unexpected error when evaluating flag #{flag.key}", exn)
151
160
  result.detail = EvaluationDetail.new(nil, nil, EvaluationReason::error(EvaluationReason::ERROR_EXCEPTION))
152
- return result
161
+ return result, state
153
162
  end
154
163
 
155
164
  unless result.big_segments_status.nil?
@@ -159,7 +168,7 @@ module LaunchDarkly
159
168
  detail.reason.with_big_segments_status(result.big_segments_status))
160
169
  end
161
170
  result.detail = detail
162
- result
171
+ [result, state]
163
172
  end
164
173
 
165
174
  # @param segment [LaunchDarkly::Impl::Model::Segment]
@@ -223,13 +232,16 @@ module LaunchDarkly
223
232
  )
224
233
  end
225
234
 
235
+ state.record_evaluated_prereq_key(prereq_key)
226
236
  prereq_flag = @get_flag.call(prereq_key)
227
237
 
228
238
  if prereq_flag.nil?
229
239
  @logger.error { "[LDClient] Could not retrieve prerequisite flag \"#{prereq_key}\" when evaluating \"#{flag.key}\"" }
230
240
  prereq_ok = false
231
241
  else
242
+ state.depth += 1
232
243
  prereq_res = eval_internal(prereq_flag, context, eval_result, state)
244
+ state.depth -= 1
233
245
  # Note that if the prerequisite flag is off, we don't consider it a match no matter what its
234
246
  # off variation was. But we still need to evaluate it in order to generate an event.
235
247
  if !prereq_flag.on || prereq_res.variation_index != prerequisite.variation
@@ -11,17 +11,10 @@ module LaunchDarkly
11
11
  # to ensure data consistency during non-atomic updates.
12
12
 
13
13
  # @private
14
- FEATURES = {
15
- namespace: "features",
16
- priority: 1, # that is, features should be stored after segments
17
- get_dependency_keys: lambda { |flag| (flag[:prerequisites] || []).map { |p| p[:key] } },
18
- }.freeze
14
+ FEATURES = Impl::DataStore::DataKind.new(namespace: "features", priority: 1).freeze
19
15
 
20
16
  # @private
21
- SEGMENTS = {
22
- namespace: "segments",
23
- priority: 0,
24
- }.freeze
17
+ SEGMENTS = Impl::DataStore::DataKind.new(namespace: "segments", priority: 0).freeze
25
18
 
26
19
  # @private
27
20
  ALL_KINDS = [FEATURES, SEGMENTS].freeze
@@ -546,7 +546,8 @@ module LaunchDarkly
546
546
  next
547
547
  end
548
548
  begin
549
- detail = @evaluator.evaluate(f, context).detail
549
+ (eval_result, eval_state) = @evaluator.evaluate(f, context)
550
+ detail = eval_result.detail
550
551
  rescue => exn
551
552
  detail = EvaluationDetail.new(nil, nil, EvaluationReason::error(EvaluationReason::ERROR_EXCEPTION))
552
553
  Util.log_exception(@config.logger, "Error evaluating flag \"#{k}\" in all_flags_state", exn)
@@ -558,6 +559,7 @@ module LaunchDarkly
558
559
  value: detail.value,
559
560
  variation: detail.variation_index,
560
561
  reason: detail.reason,
562
+ prerequisites: eval_state.prerequisites,
561
563
  version: f[:version],
562
564
  trackEvents: f[:trackEvents] || requires_experiment_data,
563
565
  trackReason: requires_experiment_data,
@@ -705,7 +707,7 @@ module LaunchDarkly
705
707
  end
706
708
 
707
709
  begin
708
- res = @evaluator.evaluate(feature, context)
710
+ (res, _) = @evaluator.evaluate(feature, context)
709
711
  unless res.prereq_evals.nil?
710
712
  res.prereq_evals.each do |prereq_eval|
711
713
  record_prereq_flag_eval(prereq_eval.prereq_flag, prereq_eval.prereq_of_flag, context, prereq_eval.detail, with_reasons)
@@ -1,3 +1,3 @@
1
1
  module LaunchDarkly
2
- VERSION = "8.7.1" # x-release-please-version
2
+ VERSION = "8.8.1" # x-release-please-version
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: launchdarkly-server-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.7.1
4
+ version: 8.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - LaunchDarkly
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-07 00:00:00.000000000 Z
11
+ date: 2024-10-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-dynamodb