launchdarkly-server-sdk 7.3.2 → 8.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4a03c0847cb10ea287eaa193067eb3e74191ea124faad2ec6a632ccd04b3297
4
- data.tar.gz: dc06eb1a9d68e1fa972751ac4273ecc3284737279d1715b2769fde52f8457def
3
+ metadata.gz: 133fe555993b53f1e53f3348242d1c96ac2318d2c2c1ebf48e33e4d23c6e97f3
4
+ data.tar.gz: 12f604c2a17d9d06433a1ad041051e41f767efa3c7310a5925553cb5678b5709
5
5
  SHA512:
6
- metadata.gz: 9496714bc7e4fe7ddfdf392255d89033a5d330b26397efd87ac166582d6ac74984843a91d5ee1236638f70310d8e4f03ab0d8fce0d0220381daed4b2bee9ea98
7
- data.tar.gz: ababf98f4a35776fcbd9911a06b2dca144fb5803a05ad9f1aabe5a5afcb776a9c76a9156059ccfc484888d32c1f3ef70a81b8060bb01bced991d72b417da0b5f
6
+ metadata.gz: 1be2d4708681d7e0a2665e68e878ed8d2e17975f6c28716ed139911b866acb067884b4af872e6f5469177f09b5071f1c8fbb0ac6b7519f581bb20ee11afb76df
7
+ data.tar.gz: 2d0a5df44d5de21887eb4330f34bf65d4a4bab9a153d7644077790e3262a8b6418c26c4ebe5612523be468d05ddd5a8b837dc22a347c08ef463229c337e040c3
@@ -13,18 +13,6 @@ module LaunchDarkly
13
13
  #
14
14
  # Constructor for creating custom LaunchDarkly configurations.
15
15
  #
16
- # `user_keys_capacity` and `user_keys_flush_interval` are deprecated
17
- # configuration options. They exist to maintain backwards compatibility
18
- # with previous configurations. Newer code should prefer their replacement
19
- # options -- `context_keys_capacity` and `context_keys_flush_interval`.
20
- #
21
- # In the event both the user and context variations are provided, the
22
- # context specific configuration option will take precedence.
23
- #
24
- # Similarly, `private_attribute_names` is deprecated. Newer code should
25
- # prefer `private_attributes`. If both are provided, `private_attributes`
26
- # will take precedence.
27
- #
28
16
  # @param opts [Hash] the configuration options
29
17
  # @option opts [Logger] :logger See {#logger}.
30
18
  # @option opts [String] :base_uri ("https://sdk.launchdarkly.com") See {#base_uri}.
@@ -42,12 +30,9 @@ module LaunchDarkly
42
30
  # @option opts [Float] :poll_interval (30) See {#poll_interval}.
43
31
  # @option opts [Boolean] :stream (true) See {#stream?}.
44
32
  # @option opts [Boolean] all_attributes_private (false) See {#all_attributes_private}.
45
- # @option opts [Array] :private_attribute_names See {#private_attribute_names}.
46
33
  # @option opts [Array] :private_attributes See {#private_attributes}.
47
34
  # @option opts [Boolean] :send_events (true) See {#send_events}.
48
- # @option opts [Integer] :user_keys_capacity (1000) See {#user_keys_capacity}.
49
35
  # @option opts [Integer] :context_keys_capacity (1000) See {#context_keys_capacity}.
50
- # @option opts [Float] :user_keys_flush_interval (300) See {#user_keys_flush_interval}.
51
36
  # @option opts [Float] :context_keys_flush_interval (300) See {#context_keys_flush_interval}.
52
37
  # @option opts [Object] :data_source See {#data_source}.
53
38
  # @option opts [Boolean] :diagnostic_opt_out (false) See {#diagnostic_opt_out?}.
@@ -76,10 +61,10 @@ module LaunchDarkly
76
61
  @offline = opts.has_key?(:offline) ? opts[:offline] : Config.default_offline
77
62
  @poll_interval = opts.has_key?(:poll_interval) && opts[:poll_interval] > Config.default_poll_interval ? opts[:poll_interval] : Config.default_poll_interval
78
63
  @all_attributes_private = opts[:all_attributes_private] || false
79
- @private_attributes = opts[:private_attributes] || opts[:private_attribute_names] || []
64
+ @private_attributes = opts[:private_attributes] || []
80
65
  @send_events = opts.has_key?(:send_events) ? opts[:send_events] : Config.default_send_events
81
- @context_keys_capacity = opts[:context_keys_capacity] || opts[:user_keys_capacity] || Config.default_context_keys_capacity
82
- @context_keys_flush_interval = opts[:context_keys_flush_interval] || opts[:user_keys_flush_interval] || Config.default_user_keys_flush_interval
66
+ @context_keys_capacity = opts[:context_keys_capacity] || Config.default_context_keys_capacity
67
+ @context_keys_flush_interval = opts[:context_keys_flush_interval] || Config.default_context_keys_flush_interval
83
68
  @data_source = opts[:data_source]
84
69
  @diagnostic_opt_out = opts.has_key?(:diagnostic_opt_out) && opts[:diagnostic_opt_out]
85
70
  @diagnostic_recording_interval = opts.has_key?(:diagnostic_recording_interval) && opts[:diagnostic_recording_interval] > Config.minimum_diagnostic_recording_interval ?
@@ -258,14 +243,6 @@ module LaunchDarkly
258
243
  #
259
244
  attr_reader :private_attributes
260
245
 
261
- #
262
- # @deprecated Backwards compatibility alias for #private_attributes.
263
- #
264
- # @return [Integer]
265
- # @see #private_attributes
266
- #
267
- alias :private_attribute_names :private_attributes
268
-
269
246
  #
270
247
  # Whether to send events back to LaunchDarkly. This differs from {#offline?} in that it affects
271
248
  # only the sending of client-side events, not streaming or polling for events from the server.
@@ -281,14 +258,6 @@ module LaunchDarkly
281
258
  #
282
259
  attr_reader :context_keys_capacity
283
260
 
284
- #
285
- # @deprecated Backwards compatibility alias for #context_keys_capacity.
286
- #
287
- # @return [Integer]
288
- # @see #context_keys_flush_interval
289
- #
290
- alias :user_keys_capacity :context_keys_capacity
291
-
292
261
  #
293
262
  # The interval in seconds at which the event processor will reset its set of known context keys.
294
263
  # @return [Float]
@@ -296,14 +265,6 @@ module LaunchDarkly
296
265
  #
297
266
  attr_reader :context_keys_flush_interval
298
267
 
299
- #
300
- # @deprecated Backwards compatibility alias for #context_keys_flush_interval.
301
- #
302
- # @return [Integer]
303
- # @see #context_keys_flush_interval
304
- #
305
- alias :user_keys_flush_interval :context_keys_flush_interval
306
-
307
268
  #
308
269
  # An object that is responsible for receiving feature flag data from LaunchDarkly. By default,
309
270
  # the client uses its standard polling or streaming implementation; this is customizable for
@@ -570,18 +531,6 @@ module LaunchDarkly
570
531
  300
571
532
  end
572
533
 
573
- class << self
574
- #
575
- # @deprecated Backwards compatibility alias for #default_context_keys_capacity
576
- #
577
- alias :default_user_keys_capacity :default_context_keys_capacity
578
-
579
- #
580
- # @deprecated Backwards compatibility alias for #default_context_keys_flush_interval
581
- #
582
- alias :default_user_keys_flush_interval :default_context_keys_flush_interval
583
- end
584
-
585
534
  #
586
535
  # The default value for {#diagnostic_recording_interval}.
587
536
  # @return [Float] 900
@@ -647,25 +596,11 @@ module LaunchDarkly
647
596
  # @return [Integer]
648
597
  attr_reader :context_cache_size
649
598
 
650
- #
651
- # @deprecated Backwards compatibility alias for #context_cache_size
652
- #
653
- # @return [Integer]
654
- #
655
- alias :user_cache_size :context_cache_size
656
-
657
599
  # The maximum length of time (in seconds) that the Big Segment state for a context will be cached
658
600
  # by the SDK.
659
601
  # @return [Float]
660
602
  attr_reader :context_cache_time
661
603
 
662
- #
663
- # @deprecated Backwards compatibility alias for #context_cache_time
664
- #
665
- # @return [Float]
666
- #
667
- alias :user_cache_time :context_cache_time
668
-
669
604
  # The interval (in seconds) at which the SDK will poll the Big Segment store to make sure it is
670
605
  # available and to determine how long ago it was updated.
671
606
  # @return [Float]
@@ -47,9 +47,6 @@ module LaunchDarkly
47
47
  # @return [String, nil] Returns the error associated with this LDContext if invalid
48
48
  attr_reader :error
49
49
 
50
- # @return [Array<Reference>] Returns the private attributes associated with this LDContext
51
- attr_reader :private_attributes
52
-
53
50
  #
54
51
  # @private
55
52
  # @param key [String, nil]
@@ -69,10 +66,10 @@ module LaunchDarkly
69
66
  @name = name
70
67
  @anonymous = anonymous || false
71
68
  @attributes = attributes
72
- @private_attributes = []
69
+ @private_attributes = Set.new
73
70
  (private_attributes || []).each do |attribute|
74
71
  reference = Reference.create(attribute)
75
- @private_attributes << reference if reference.error.nil?
72
+ @private_attributes.add(reference) if reference.error.nil?
76
73
  end
77
74
  @error = error
78
75
  @contexts = contexts
@@ -80,6 +77,16 @@ module LaunchDarkly
80
77
  end
81
78
  private_class_method :new
82
79
 
80
+ protected attr_reader :name, :anonymous, :attributes
81
+
82
+ #
83
+ # @return [Array<Reference>] Returns the private attributes associated with this LDContext
84
+ #
85
+ def private_attributes
86
+ # TODO(sc-227265): Return a set instead of an array.
87
+ @private_attributes.to_a
88
+ end
89
+
83
90
  #
84
91
  # @return [Boolean] Is this LDContext a multi-kind context?
85
92
  #
@@ -274,6 +281,59 @@ module LaunchDarkly
274
281
  nil
275
282
  end
276
283
 
284
+ #
285
+ # An LDContext can be compared to other LDContexts or to a hash object. If
286
+ # a hash is provided, it is first converted to an LDContext using the
287
+ # `LDContext.create` method.
288
+ #
289
+ # @param other [LDContext, Hash]
290
+ # @return [Boolean]
291
+ #
292
+ def ==(other)
293
+ other = LDContext.create(other) if other.is_a? Hash
294
+ return false unless other.is_a? LDContext
295
+
296
+ return false unless self.kind == other.kind
297
+ return false unless self.valid? == other.valid?
298
+ return false unless self.error == other.error
299
+
300
+ return false unless self.individual_context_count == other.individual_context_count
301
+
302
+ if self.multi_kind?
303
+ self.kinds.each do |kind|
304
+ return false unless self.individual_context(kind) == other.individual_context(kind)
305
+ end
306
+
307
+ return true
308
+ end
309
+
310
+ return false unless self.key == other.key
311
+ return false unless self.name == other.name
312
+ return false unless self.anonymous == other.anonymous
313
+ return false unless self.attributes == other.attributes
314
+
315
+ # TODO(sc-227265): Calling .to_set is unnecessary once private_attributes are sets.
316
+ return false unless self.private_attributes.to_set == other.private_attributes.to_set
317
+
318
+ true
319
+ end
320
+ alias eql? ==
321
+
322
+ #
323
+ # For a single-kind context, the provided key will return the attribute value specified. This is the same as calling
324
+ # `LDCotnext.get_value`.
325
+ #
326
+ # For multi-kind contexts, the key will be interpreted as a context kind. If the multi-kind context has an
327
+ # individual context of that kind, it will be returned. Otherwise, this method will return nil. This behaves the
328
+ # same as calling `LDContext.individual_context`.
329
+ #
330
+ # @param key [Symbol, String]
331
+ #
332
+ def [](key)
333
+ return nil unless key.is_a? Symbol or key.is_a? String
334
+ multi_kind? ? individual_context(key.to_s) : get_value(key)
335
+ end
336
+
277
337
  #
278
338
  # Retrieve the value of any top level, addressable attribute.
279
339
  #
@@ -324,7 +384,6 @@ module LaunchDarkly
324
384
  #
325
385
  def self.create(data)
326
386
  return create_invalid_context(ERR_NOT_HASH) unless data.is_a?(Hash)
327
- return create_legacy_context(data) unless data.has_key?(:kind)
328
387
 
329
388
  kind = data[:kind]
330
389
  if kind == KIND_MULTI
@@ -394,52 +453,6 @@ module LaunchDarkly
394
453
  new(nil, nil, nil, nil, false, nil, nil, error)
395
454
  end
396
455
 
397
- #
398
- # @param data [Hash]
399
- # @return [LDContext]
400
- #
401
- private_class_method def self.create_legacy_context(data)
402
- warn("DEPRECATED: legacy user format will be removed in 8.0.0", uplevel: 1)
403
-
404
- key = data[:key]
405
-
406
- # Legacy users are allowed to have "" as a key but they cannot have nil as a key.
407
- return create_invalid_context(ERR_KEY_EMPTY) if key.nil?
408
-
409
- name = data[:name]
410
- name_error = LaunchDarkly::Impl::Context.validate_name(name)
411
- return create_invalid_context(name_error) unless name_error.nil?
412
-
413
- anonymous = data[:anonymous]
414
- anonymous_error = LaunchDarkly::Impl::Context.validate_anonymous(anonymous, true)
415
- return create_invalid_context(anonymous_error) unless anonymous_error.nil?
416
-
417
- custom = data[:custom]
418
- unless custom.nil? || custom.is_a?(Hash)
419
- return create_invalid_context(ERR_CUSTOM_NON_HASH)
420
- end
421
-
422
- # We only need to create an attribute hash if one of these keys exist.
423
- # Everything else is stored in dedicated instance variables.
424
- attributes = custom.clone
425
- data.each do |k, v|
426
- case k
427
- when :ip, :email, :avatar, :firstName, :lastName, :country
428
- attributes ||= {}
429
- attributes[k] = v.clone
430
- else
431
- next
432
- end
433
- end
434
-
435
- private_attributes = data[:privateAttributeNames]
436
- if private_attributes && !private_attributes.is_a?(Array)
437
- return create_invalid_context(ERR_PRIVATE_NON_ARRAY)
438
- end
439
-
440
- new(key.to_s, key.to_s, KIND_DEFAULT, name, anonymous, attributes, private_attributes)
441
- end
442
-
443
456
  #
444
457
  # @param data [Hash]
445
458
  # @param kind [String]
@@ -1,4 +1,3 @@
1
-
2
1
  module LaunchDarkly
3
2
  # An object returned by {LDClient#variation_detail}, combining the result of a flag evaluation with
4
3
  # an explanation of how it was calculated.
@@ -13,6 +12,7 @@ module LaunchDarkly
13
12
  def initialize(value, variation_index, reason)
14
13
  raise ArgumentError.new("variation_index must be a number") if !variation_index.nil? && !(variation_index.is_a? Numeric)
15
14
  raise ArgumentError.new("reason must be an EvaluationReason") unless reason.is_a? EvaluationReason
15
+
16
16
  @value = value
17
17
  @variation_index = variation_index
18
18
  @reason = reason
@@ -100,6 +100,10 @@ module LaunchDarkly
100
100
  # a rule specified a nonexistent variation. An error message will always be logged in this case.
101
101
  ERROR_MALFORMED_FLAG = :MALFORMED_FLAG
102
102
 
103
+ # Value for {#error_kind} indicating that there was an inconsistency between the expected type of the flag, and the
104
+ # actual type of the variation evaluated.
105
+ ERROR_WRONG_TYPE = :WRONG_TYPE
106
+
103
107
  # Value for {#error_kind} indicating that the caller passed `nil` for the context parameter, or the
104
108
  # context was invalid.
105
109
  ERROR_USER_NOT_SPECIFIED = :USER_NOT_SPECIFIED
@@ -40,7 +40,9 @@ module LaunchDarkly
40
40
  default = nil,
41
41
  track_events = false,
42
42
  debug_until = nil,
43
- prereq_of = nil
43
+ prereq_of = nil,
44
+ sampling_ratio = nil,
45
+ exclude_from_summaries = false
44
46
  )
45
47
  end
46
48
 
@@ -55,6 +57,9 @@ module LaunchDarkly
55
57
  )
56
58
  end
57
59
 
60
+ def record_migration_op_event(event)
61
+ end
62
+
58
63
  def flush
59
64
  end
60
65
 
@@ -153,10 +158,12 @@ module LaunchDarkly
153
158
  default = nil,
154
159
  track_events = false,
155
160
  debug_until = nil,
156
- prereq_of = nil
161
+ prereq_of = nil,
162
+ sampling_ratio = nil,
163
+ exclude_from_summaries = false
157
164
  )
158
165
  post_to_inbox(LaunchDarkly::Impl::EvalEvent.new(timestamp, context, key, version, variation, value, reason,
159
- default, track_events, debug_until, prereq_of))
166
+ default, track_events, debug_until, prereq_of, sampling_ratio, exclude_from_summaries))
160
167
  end
161
168
 
162
169
  def record_identify_event(context)
@@ -167,6 +174,10 @@ module LaunchDarkly
167
174
  post_to_inbox(LaunchDarkly::Impl::CustomEvent.new(timestamp, context, key, data, metric_value))
168
175
  end
169
176
 
177
+ def record_migration_op_event(event)
178
+ post_to_inbox(event)
179
+ end
180
+
170
181
  def flush
171
182
  # flush is done asynchronously
172
183
  post_to_inbox(FlushMessage.new)
@@ -220,6 +231,7 @@ module LaunchDarkly
220
231
  @config = config
221
232
  @diagnostic_accumulator = config.diagnostic_opt_out? ? nil : diagnostic_accumulator
222
233
  @event_sender = event_sender
234
+ @sampler = LaunchDarkly::Impl::Sampler.new(Random.new)
223
235
 
224
236
  @context_keys = SimpleLRUCacheSet.new(config.context_keys_capacity)
225
237
  @formatter = EventOutputFormatter.new(config)
@@ -292,7 +304,7 @@ module LaunchDarkly
292
304
  return if @disabled.value
293
305
 
294
306
  # Always record the event in the summary.
295
- outbox.add_to_summary(event)
307
+ outbox.add_to_summary(event) unless event.exclude_from_summaries
296
308
 
297
309
  # Decide whether to add the event to the payload. Feature events may be added twice, once for
298
310
  # the event (if tracked) and once for debugging.
@@ -309,12 +321,12 @@ module LaunchDarkly
309
321
 
310
322
  # For each context we haven't seen before, we add an index event - unless this is already
311
323
  # an identify event for that context.
312
- if !event.context.nil? && !notice_context(event.context) && !event.is_a?(LaunchDarkly::Impl::IdentifyEvent)
324
+ if !event.context.nil? && !notice_context(event.context) && !event.is_a?(LaunchDarkly::Impl::IdentifyEvent) && !event.is_a?(LaunchDarkly::Impl::MigrationOpEvent)
313
325
  outbox.add_event(LaunchDarkly::Impl::IndexEvent.new(event.timestamp, event.context))
314
326
  end
315
327
 
316
- outbox.add_event(event) if will_add_full_event
317
- outbox.add_event(debug_event) unless debug_event.nil?
328
+ outbox.add_event(event) if will_add_full_event && @sampler.sample(event.sampling_ratio.nil? ? 1 : event.sampling_ratio)
329
+ outbox.add_event(debug_event) if !debug_event.nil? && @sampler.sample(event.sampling_ratio.nil? ? 1 : event.sampling_ratio)
318
330
  end
319
331
 
320
332
  #
@@ -443,6 +455,7 @@ module LaunchDarkly
443
455
  CUSTOM_KIND = 'custom'
444
456
  INDEX_KIND = 'index'
445
457
  DEBUG_KIND = 'debug'
458
+ MIGRATION_OP_KIND = 'migration_op'
446
459
  SUMMARY_KIND = 'summary'
447
460
 
448
461
  def initialize(config)
@@ -476,6 +489,64 @@ module LaunchDarkly
476
489
  out[:reason] = event.reason unless event.reason.nil?
477
490
  out
478
491
 
492
+ when LaunchDarkly::Impl::MigrationOpEvent
493
+ out = {
494
+ kind: MIGRATION_OP_KIND,
495
+ creationDate: event.timestamp,
496
+ contextKeys: event.context.keys,
497
+ operation: event.operation.to_s,
498
+ evaluation: {
499
+ key: event.key,
500
+ value: event.evaluation.value,
501
+ },
502
+ }
503
+
504
+ out[:evaluation][:version] = event.version unless event.version.nil?
505
+ out[:evaluation][:default] = event.default unless event.default.nil?
506
+ out[:evaluation][:variation] = event.evaluation.variation_index unless event.evaluation.variation_index.nil?
507
+ out[:evaluation][:reason] = event.evaluation.reason unless event.evaluation.reason.nil?
508
+ out[:samplingRatio] = event.sampling_ratio unless event.sampling_ratio.nil? || event.sampling_ratio == 1
509
+
510
+ measurements = []
511
+
512
+ unless event.invoked.empty?
513
+ measurements << {
514
+ "key": "invoked",
515
+ "values": event.invoked.map { |origin| [origin, true] }.to_h,
516
+ }
517
+ end
518
+
519
+ unless event.consistency_check.nil?
520
+ measurement = {
521
+ "key": "consistent",
522
+ "value": event.consistency_check,
523
+ }
524
+
525
+ unless event.consistency_check_ratio.nil? || event.consistency_check_ratio == 1
526
+ measurement[:samplingRatio] = event.consistency_check_ratio
527
+ end
528
+
529
+ measurements << measurement
530
+ end
531
+
532
+
533
+ unless event.latencies.empty?
534
+ measurements << {
535
+ "key": "latency_ms",
536
+ "values": event.latencies,
537
+ }
538
+ end
539
+
540
+ unless event.errors.empty?
541
+ measurements << {
542
+ "key": "error",
543
+ "values": event.errors.map { |origin| [origin, true] }.to_h,
544
+ }
545
+ end
546
+ out[:measurements] = measurements unless measurements.empty?
547
+
548
+ out
549
+
479
550
  when LaunchDarkly::Impl::IdentifyEvent
480
551
  {
481
552
  kind: IDENTIFY_KIND,
@@ -23,7 +23,7 @@ module LaunchDarkly
23
23
  @last_status = nil
24
24
 
25
25
  unless @store.nil?
26
- @cache = ExpiringCache.new(big_segments_config.user_cache_size, big_segments_config.user_cache_time)
26
+ @cache = ExpiringCache.new(big_segments_config.context_cache_size, big_segments_config.context_cache_time)
27
27
  @poll_worker = RepeatingTask.new(big_segments_config.status_poll_interval, 0, -> { poll_store_and_update_status }, logger)
28
28
  @poll_worker.start
29
29
  end
@@ -142,4 +142,4 @@ module LaunchDarkly
142
142
  end
143
143
  end
144
144
  end
145
- end
145
+ end
@@ -1,23 +1,33 @@
1
+ require 'set'
2
+
1
3
  module LaunchDarkly
2
4
  module Impl
3
5
  class Event
4
6
  # @param timestamp [Integer]
5
7
  # @param context [LaunchDarkly::LDContext]
6
- def initialize(timestamp, context)
8
+ # @param sampling_ratio [Integer, nil]
9
+ # @param exclude_from_summaries [Boolean]
10
+ def initialize(timestamp, context, sampling_ratio = nil, exclude_from_summaries = false)
7
11
  @timestamp = timestamp
8
12
  @context = context
13
+ @sampling_ratio = sampling_ratio
14
+ @exclude_from_summaries = exclude_from_summaries
9
15
  end
10
16
 
11
17
  # @return [Integer]
12
18
  attr_reader :timestamp
13
19
  # @return [LaunchDarkly::LDContext]
14
20
  attr_reader :context
21
+ # @return [Integer, nil]
22
+ attr_reader :sampling_ratio
23
+ # @return [Boolean]
24
+ attr_reader :exclude_from_summaries
15
25
  end
16
26
 
17
27
  class EvalEvent < Event
18
28
  def initialize(timestamp, context, key, version = nil, variation = nil, value = nil, reason = nil, default = nil,
19
- track_events = false, debug_until = nil, prereq_of = nil)
20
- super(timestamp, context)
29
+ track_events = false, debug_until = nil, prereq_of = nil, sampling_ratio = nil, exclude_from_summaries = false)
30
+ super(timestamp, context, sampling_ratio, exclude_from_summaries)
21
31
  @key = key
22
32
  @version = version
23
33
  @variation = variation
@@ -41,6 +51,54 @@ module LaunchDarkly
41
51
  attr_reader :prereq_of
42
52
  end
43
53
 
54
+ class MigrationOpEvent < Event
55
+ #
56
+ # A migration op event represents the results of a migration-assisted read or write operation.
57
+ #
58
+ # The event includes optional measurements reporting on consistency checks, error reporting, and operation latency
59
+ # values.
60
+ #
61
+ # @param timestamp [Integer]
62
+ # @param context [LaunchDarkly::LDContext]
63
+ # @param key [string]
64
+ # @param flag [LaunchDarkly::Impl::Model::FeatureFlag, nil]
65
+ # @param operation [Symbol]
66
+ # @param default_stage [Symbol]
67
+ # @param evaluation [LaunchDarkly::EvaluationDetail]
68
+ # @param invoked [Set]
69
+ # @param consistency_check [Boolean, nil]
70
+ # @param consistency_check_ratio [Integer, nil]
71
+ # @param errors [Set]
72
+ # @param latencies [Hash<Symbol, Float>]
73
+ #
74
+ def initialize(timestamp, context, key, flag, operation, default_stage, evaluation, invoked, consistency_check, consistency_check_ratio, errors, latencies)
75
+ super(timestamp, context)
76
+ @operation = operation
77
+ @key = key
78
+ @version = flag&.version
79
+ @sampling_ratio = flag&.sampling_ratio
80
+ @default = default_stage
81
+ @evaluation = evaluation
82
+ @consistency_check = consistency_check
83
+ @consistency_check_ratio = consistency_check.nil? ? nil : consistency_check_ratio
84
+ @invoked = invoked
85
+ @errors = errors
86
+ @latencies = latencies
87
+ end
88
+
89
+ attr_reader :operation
90
+ attr_reader :key
91
+ attr_reader :version
92
+ attr_reader :sampling_ratio
93
+ attr_reader :default
94
+ attr_reader :evaluation
95
+ attr_reader :consistency_check
96
+ attr_reader :consistency_check_ratio
97
+ attr_reader :invoked
98
+ attr_reader :errors
99
+ attr_reader :latencies
100
+ end
101
+
44
102
  class IdentifyEvent < Event
45
103
  def initialize(timestamp, context)
46
104
  super(timestamp, context)