launchdarkly-server-sdk 8.11.2 → 8.11.3

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ldclient-rb/config.rb +66 -3
  3. data/lib/ldclient-rb/context.rb +1 -1
  4. data/lib/ldclient-rb/data_system.rb +243 -0
  5. data/lib/ldclient-rb/events.rb +34 -19
  6. data/lib/ldclient-rb/flags_state.rb +1 -1
  7. data/lib/ldclient-rb/impl/big_segments.rb +4 -4
  8. data/lib/ldclient-rb/impl/cache_store.rb +44 -0
  9. data/lib/ldclient-rb/impl/data_source/polling.rb +108 -0
  10. data/lib/ldclient-rb/impl/data_source/requestor.rb +106 -0
  11. data/lib/ldclient-rb/impl/data_source/status_provider.rb +78 -0
  12. data/lib/ldclient-rb/impl/data_source/stream.rb +198 -0
  13. data/lib/ldclient-rb/impl/data_source.rb +3 -3
  14. data/lib/ldclient-rb/impl/data_store/data_kind.rb +108 -0
  15. data/lib/ldclient-rb/impl/data_store/feature_store_client_wrapper.rb +187 -0
  16. data/lib/ldclient-rb/impl/data_store/in_memory_feature_store.rb +130 -0
  17. data/lib/ldclient-rb/impl/data_store/status_provider.rb +82 -0
  18. data/lib/ldclient-rb/impl/data_store/store.rb +371 -0
  19. data/lib/ldclient-rb/impl/data_store.rb +11 -97
  20. data/lib/ldclient-rb/impl/data_system/fdv1.rb +20 -7
  21. data/lib/ldclient-rb/impl/data_system/fdv2.rb +471 -0
  22. data/lib/ldclient-rb/impl/data_system/polling.rb +601 -0
  23. data/lib/ldclient-rb/impl/data_system/protocolv2.rb +264 -0
  24. data/lib/ldclient-rb/impl/dependency_tracker.rb +21 -9
  25. data/lib/ldclient-rb/impl/evaluator.rb +3 -2
  26. data/lib/ldclient-rb/impl/event_sender.rb +4 -3
  27. data/lib/ldclient-rb/impl/expiring_cache.rb +79 -0
  28. data/lib/ldclient-rb/impl/integrations/file_data_source.rb +8 -8
  29. data/lib/ldclient-rb/impl/integrations/test_data/test_data_source_v2.rb +288 -0
  30. data/lib/ldclient-rb/impl/memoized_value.rb +34 -0
  31. data/lib/ldclient-rb/impl/migrations/migrator.rb +2 -1
  32. data/lib/ldclient-rb/impl/migrations/tracker.rb +2 -1
  33. data/lib/ldclient-rb/impl/model/serialization.rb +6 -6
  34. data/lib/ldclient-rb/impl/non_blocking_thread_pool.rb +48 -0
  35. data/lib/ldclient-rb/impl/repeating_task.rb +2 -2
  36. data/lib/ldclient-rb/impl/simple_lru_cache.rb +27 -0
  37. data/lib/ldclient-rb/impl/util.rb +65 -0
  38. data/lib/ldclient-rb/impl.rb +1 -2
  39. data/lib/ldclient-rb/in_memory_store.rb +1 -18
  40. data/lib/ldclient-rb/integrations/test_data/flag_builder.rb +9 -9
  41. data/lib/ldclient-rb/integrations/test_data.rb +11 -11
  42. data/lib/ldclient-rb/integrations/test_data_v2/flag_builder_v2.rb +582 -0
  43. data/lib/ldclient-rb/integrations/test_data_v2.rb +248 -0
  44. data/lib/ldclient-rb/integrations/util/store_wrapper.rb +3 -2
  45. data/lib/ldclient-rb/interfaces/data_system.rb +755 -0
  46. data/lib/ldclient-rb/interfaces/feature_store.rb +3 -0
  47. data/lib/ldclient-rb/ldclient.rb +55 -131
  48. data/lib/ldclient-rb/util.rb +11 -70
  49. data/lib/ldclient-rb/version.rb +1 -1
  50. data/lib/ldclient-rb.rb +8 -17
  51. metadata +35 -17
  52. data/lib/ldclient-rb/cache_store.rb +0 -45
  53. data/lib/ldclient-rb/expiring_cache.rb +0 -77
  54. data/lib/ldclient-rb/memoized_value.rb +0 -32
  55. data/lib/ldclient-rb/non_blocking_thread_pool.rb +0 -46
  56. data/lib/ldclient-rb/polling.rb +0 -102
  57. data/lib/ldclient-rb/requestor.rb +0 -102
  58. data/lib/ldclient-rb/simple_lru_cache.rb +0 -25
  59. data/lib/ldclient-rb/stream.rb +0 -197
@@ -0,0 +1,755 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LaunchDarkly
4
+ module Interfaces
5
+ module DataSystem
6
+ #
7
+ # EventName represents the name of an event that can be sent by the server for FDv2.
8
+ #
9
+ # This type is not stable, and not subject to any backwards
10
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
11
+ #
12
+ # Do not use it.
13
+ # You have been warned.
14
+ #
15
+ module EventName
16
+ # Specifies that an object should be added to the data set with upsert semantics.
17
+ PUT_OBJECT = "put-object"
18
+
19
+ # Specifies that an object should be removed from the data set.
20
+ DELETE_OBJECT = "delete-object"
21
+
22
+ # Specifies the server's intent.
23
+ SERVER_INTENT = "server-intent"
24
+
25
+ # Specifies that all data required to bring the existing data set to a new version has been transferred.
26
+ PAYLOAD_TRANSFERRED = "payload-transferred"
27
+
28
+ # Keeps the connection alive.
29
+ HEARTBEAT = "heart-beat"
30
+
31
+ # Specifies that the server is about to close the connection.
32
+ GOODBYE = "goodbye"
33
+
34
+ # Specifies that an error occurred while serving the connection.
35
+ ERROR = "error"
36
+ end
37
+
38
+ #
39
+ # ObjectKind represents the kind of object.
40
+ #
41
+ # This type is not stable, and not subject to any backwards
42
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
43
+ #
44
+ # Do not use it.
45
+ # You have been warned.
46
+ #
47
+ module ObjectKind
48
+ # Represents a feature flag.
49
+ FLAG = "flag"
50
+
51
+ # Represents a segment.
52
+ SEGMENT = "segment"
53
+ end
54
+
55
+ #
56
+ # ChangeType specifies if an object is being upserted or deleted.
57
+ #
58
+ # This type is not stable, and not subject to any backwards
59
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
60
+ #
61
+ # Do not use it.
62
+ # You have been warned.
63
+ #
64
+ module ChangeType
65
+ # Represents an object being upserted.
66
+ PUT = "put"
67
+
68
+ # Represents an object being deleted.
69
+ DELETE = "delete"
70
+ end
71
+
72
+ #
73
+ # IntentCode represents the various intents that can be sent by the server.
74
+ #
75
+ # This type is not stable, and not subject to any backwards
76
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
77
+ #
78
+ # Do not use it.
79
+ # You have been warned.
80
+ #
81
+ module IntentCode
82
+ # The server intends to send a full data set.
83
+ TRANSFER_FULL = "xfer-full"
84
+
85
+ # The server intends to send only the necessary changes to bring an existing data set up-to-date.
86
+ TRANSFER_CHANGES = "xfer-changes"
87
+
88
+ # The server intends to send no data (payload is up to date).
89
+ TRANSFER_NONE = "none"
90
+ end
91
+
92
+ #
93
+ # DataStoreMode represents the mode of operation of a Data Store in FDV2 mode.
94
+ #
95
+ # This type is not stable, and not subject to any backwards
96
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
97
+ #
98
+ # Do not use it.
99
+ # You have been warned.
100
+ #
101
+ module DataStoreMode
102
+ # Indicates that the data store is read-only. Data will never be written back to the store by the SDK.
103
+ READ_ONLY = :read_only
104
+
105
+ # Indicates that the data store is read-write. Data from initializers/synchronizers may be written
106
+ # to the store as necessary.
107
+ READ_WRITE = :read_write
108
+ end
109
+
110
+ #
111
+ # Selector represents a particular snapshot of data.
112
+ #
113
+ # This type is not stable, and not subject to any backwards
114
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
115
+ #
116
+ # Do not use it.
117
+ # You have been warned.
118
+ #
119
+ class Selector
120
+ # @return [String] The state
121
+ attr_reader :state
122
+
123
+ # @return [Integer] The version
124
+ attr_reader :version
125
+
126
+ #
127
+ # @param state [String] The state
128
+ # @param version [Integer] The version
129
+ #
130
+ def initialize(state: "", version: 0)
131
+ @state = state
132
+ @version = version
133
+ end
134
+
135
+ #
136
+ # Returns an empty Selector.
137
+ #
138
+ # @return [Selector]
139
+ #
140
+ def self.no_selector
141
+ Selector.new
142
+ end
143
+
144
+ #
145
+ # Returns true if the Selector has a value.
146
+ #
147
+ # @return [Boolean]
148
+ #
149
+ def defined?
150
+ self != Selector.no_selector
151
+ end
152
+
153
+ #
154
+ # Returns the event name for payload transfer.
155
+ #
156
+ # @return [String]
157
+ #
158
+ def name
159
+ EventName::PAYLOAD_TRANSFERRED
160
+ end
161
+
162
+ #
163
+ # Creates a new Selector from a state string and version.
164
+ #
165
+ # @param state [String] The state
166
+ # @param version [Integer] The version
167
+ # @return [Selector]
168
+ #
169
+ def self.new_selector(state, version)
170
+ Selector.new(state: state, version: version)
171
+ end
172
+
173
+ #
174
+ # Serializes the Selector to a Hash.
175
+ #
176
+ # @return [Hash]
177
+ #
178
+ def to_h
179
+ {
180
+ state: @state,
181
+ version: @version,
182
+ }
183
+ end
184
+
185
+ #
186
+ # Deserializes a Selector from a Hash.
187
+ #
188
+ # @param data [Hash] The hash representation
189
+ # @return [Selector]
190
+ # @raise [ArgumentError] if required fields are missing
191
+ #
192
+ def self.from_h(data)
193
+ state = data['state'] || data[:state]
194
+ version = data['version'] || data[:version]
195
+
196
+ raise ArgumentError, "Missing required fields in Selector" if state.nil? || version.nil?
197
+
198
+ Selector.new(state: state, version: version)
199
+ end
200
+
201
+ def ==(other)
202
+ other.is_a?(Selector) && @state == other.state && @version == other.version
203
+ end
204
+
205
+ def eql?(other)
206
+ self == other
207
+ end
208
+
209
+ def hash
210
+ [@state, @version].hash
211
+ end
212
+ end
213
+
214
+ #
215
+ # Change represents a change to a piece of data, such as an update or deletion.
216
+ #
217
+ # This type is not stable, and not subject to any backwards
218
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
219
+ #
220
+ # Do not use it.
221
+ # You have been warned.
222
+ #
223
+ class Change
224
+ # @return [String] The action ({ChangeType})
225
+ attr_reader :action
226
+
227
+ # @return [String] The kind ({ObjectKind})
228
+ attr_reader :kind
229
+
230
+ # @return [String] The key
231
+ attr_reader :key
232
+
233
+ # @return [Integer] The version
234
+ attr_reader :version
235
+
236
+ # @return [Hash, nil] The object data (for PUT actions)
237
+ attr_reader :object
238
+
239
+ #
240
+ # @param action [String] The action type ({ChangeType})
241
+ # @param kind [String] The object kind ({ObjectKind})
242
+ # @param key [String] The key
243
+ # @param version [Integer] The version
244
+ # @param object [Hash, nil] The object data
245
+ #
246
+ def initialize(action:, kind:, key:, version:, object: nil)
247
+ @action = action
248
+ @kind = kind
249
+ @key = key
250
+ @version = version
251
+ @object = object
252
+ end
253
+ end
254
+
255
+ #
256
+ # ChangeSet represents a list of changes to be applied.
257
+ #
258
+ # This type is not stable, and not subject to any backwards
259
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
260
+ #
261
+ # Do not use it.
262
+ # You have been warned.
263
+ #
264
+ class ChangeSet
265
+ # @return [String] The intent code ({IntentCode})
266
+ attr_reader :intent_code
267
+
268
+ # @return [Array<Change>] The changes
269
+ attr_reader :changes
270
+
271
+ # @return [Selector, nil] The selector
272
+ attr_reader :selector
273
+
274
+ #
275
+ # @param intent_code [String] The intent code ({IntentCode})
276
+ # @param changes [Array<Change>] The changes
277
+ # @param selector [Selector, nil] The selector
278
+ #
279
+ def initialize(intent_code:, changes:, selector:)
280
+ @intent_code = intent_code
281
+ @changes = changes
282
+ @selector = selector
283
+ end
284
+ end
285
+
286
+ #
287
+ # Basis represents the initial payload of data that a data source can provide.
288
+ #
289
+ # This type is not stable, and not subject to any backwards
290
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
291
+ #
292
+ # Do not use it.
293
+ # You have been warned.
294
+ #
295
+ class Basis
296
+ # @return [ChangeSet] The change set
297
+ attr_reader :change_set
298
+
299
+ # @return [Boolean] Whether to persist
300
+ attr_reader :persist
301
+
302
+ # @return [String, nil] The environment ID
303
+ attr_reader :environment_id
304
+
305
+ #
306
+ # @param change_set [ChangeSet] The change set
307
+ # @param persist [Boolean] Whether to persist
308
+ # @param environment_id [String, nil] The environment ID
309
+ #
310
+ def initialize(change_set:, persist:, environment_id: nil)
311
+ @change_set = change_set
312
+ @persist = persist
313
+ @environment_id = environment_id
314
+ end
315
+ end
316
+
317
+ #
318
+ # Payload represents a payload delivered in a streaming response.
319
+ #
320
+ # This type is not stable, and not subject to any backwards
321
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
322
+ #
323
+ # Do not use it.
324
+ # You have been warned.
325
+ #
326
+ class Payload
327
+ # @return [String] The payload ID
328
+ attr_reader :id
329
+
330
+ # @return [Integer] The target
331
+ attr_reader :target
332
+
333
+ # @return [String] The intent code ({IntentCode})
334
+ attr_reader :code
335
+
336
+ # @return [String] The reason
337
+ attr_reader :reason
338
+
339
+ #
340
+ # @param id [String] The payload ID
341
+ # @param target [Integer] The target
342
+ # @param code [String] The intent code ({IntentCode})
343
+ # @param reason [String] The reason
344
+ #
345
+ def initialize(id:, target:, code:, reason:)
346
+ @id = id
347
+ @target = target
348
+ @code = code
349
+ @reason = reason
350
+ end
351
+
352
+ #
353
+ # Serializes the Payload to a Hash.
354
+ #
355
+ # @return [Hash]
356
+ #
357
+ def to_h
358
+ {
359
+ id: @id,
360
+ target: @target,
361
+ intentCode: @code,
362
+ reason: @reason,
363
+ }
364
+ end
365
+
366
+ #
367
+ # Deserializes a Payload from a Hash.
368
+ #
369
+ # @param data [Hash] The hash representation
370
+ # @return [Payload]
371
+ # @raise [ArgumentError] if required fields are missing or invalid
372
+ #
373
+ def self.from_h(data)
374
+ intent_code = data['intentCode'] || data[:intentCode]
375
+
376
+ raise ArgumentError, "Invalid data for Payload: 'intentCode' key is missing or not a string" if intent_code.nil? || !intent_code.is_a?(String)
377
+
378
+ Payload.new(
379
+ id: data['id'] || data[:id] || "",
380
+ target: data['target'] || data[:target] || 0,
381
+ code: intent_code,
382
+ reason: data['reason'] || data[:reason] || ""
383
+ )
384
+ end
385
+ end
386
+
387
+ #
388
+ # ServerIntent represents the type of change associated with the payload.
389
+ #
390
+ # This type is not stable, and not subject to any backwards
391
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
392
+ #
393
+ # Do not use it.
394
+ # You have been warned.
395
+ #
396
+ class ServerIntent
397
+ # @return [Payload] The payload
398
+ attr_reader :payload
399
+
400
+ #
401
+ # @param payload [Payload] The payload
402
+ #
403
+ def initialize(payload:)
404
+ @payload = payload
405
+ end
406
+
407
+ #
408
+ # Serializes the ServerIntent to a Hash.
409
+ #
410
+ # @return [Hash]
411
+ #
412
+ def to_h
413
+ {
414
+ payloads: [@payload.to_h],
415
+ }
416
+ end
417
+
418
+ #
419
+ # Deserializes a ServerIntent from a Hash.
420
+ #
421
+ # @param data [Hash] The hash representation
422
+ # @return [ServerIntent]
423
+ # @raise [ArgumentError] if required fields are missing or invalid
424
+ #
425
+ def self.from_h(data)
426
+ payloads = data['payloads'] || data[:payloads]
427
+
428
+ raise ArgumentError, "Invalid data for ServerIntent: 'payloads' key is missing or not an array" unless payloads.is_a?(Array)
429
+ raise ArgumentError, "Invalid data for ServerIntent: expected exactly one payload" unless payloads.length == 1
430
+
431
+ payload = payloads[0]
432
+ raise ArgumentError, "Invalid payload in ServerIntent: expected a hash" unless payload.is_a?(Hash)
433
+
434
+ ServerIntent.new(payload: Payload.from_h(payload))
435
+ end
436
+ end
437
+
438
+ #
439
+ # ChangeSetBuilder is a helper for constructing a ChangeSet.
440
+ #
441
+ # This type is not stable, and not subject to any backwards
442
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
443
+ #
444
+ # Do not use it.
445
+ # You have been warned.
446
+ #
447
+ class ChangeSetBuilder
448
+ # @return [String, nil] The current intent ({IntentCode})
449
+ attr_accessor :intent
450
+
451
+ # @return [Array<Change>] The changes
452
+ attr_accessor :changes
453
+
454
+ def initialize
455
+ @intent = nil
456
+ @changes = []
457
+ end
458
+
459
+ #
460
+ # Represents an intent that the current data is up-to-date and doesn't require changes.
461
+ #
462
+ # @return [ChangeSet]
463
+ #
464
+ def self.no_changes
465
+ ChangeSet.new(
466
+ intent_code: IntentCode::TRANSFER_NONE,
467
+ selector: Selector.no_selector,
468
+ changes: []
469
+ )
470
+ end
471
+
472
+ #
473
+ # Returns an empty ChangeSet, useful for initializing without data.
474
+ #
475
+ # @param selector [Selector] The selector
476
+ # @return [ChangeSet]
477
+ #
478
+ def self.empty(selector)
479
+ ChangeSet.new(
480
+ intent_code: IntentCode::TRANSFER_FULL,
481
+ selector: selector,
482
+ changes: []
483
+ )
484
+ end
485
+
486
+ #
487
+ # Begins a new change set with a given intent.
488
+ #
489
+ # @param intent [String] The intent code ({IntentCode})
490
+ # @return [void]
491
+ #
492
+ def start(intent)
493
+ @intent = intent
494
+ @changes = []
495
+ end
496
+
497
+ #
498
+ # Ensures that the current ChangeSetBuilder is prepared to handle changes.
499
+ #
500
+ # @return [void]
501
+ # @raise [RuntimeError] if no server-intent has been set
502
+ #
503
+ def expect_changes
504
+ raise "changeset: cannot expect changes without a server-intent" if @intent.nil?
505
+
506
+ return unless @intent == IntentCode::TRANSFER_NONE
507
+
508
+ @intent = IntentCode::TRANSFER_CHANGES
509
+ end
510
+
511
+ #
512
+ # Clears any existing changes while preserving the current intent.
513
+ #
514
+ # @return [void]
515
+ #
516
+ def reset
517
+ @changes = []
518
+ end
519
+
520
+ #
521
+ # Identifies a changeset with a selector and returns the completed changeset.
522
+ #
523
+ # @param selector [Selector] The selector
524
+ # @return [ChangeSet]
525
+ # @raise [RuntimeError] if no server-intent has been set
526
+ #
527
+ def finish(selector)
528
+ raise "changeset: cannot complete without a server-intent" if @intent.nil?
529
+
530
+ changeset = ChangeSet.new(
531
+ intent_code: @intent,
532
+ selector: selector,
533
+ changes: @changes
534
+ )
535
+ @changes = []
536
+
537
+ # Once a full transfer has been processed, all future changes should be
538
+ # assumed to be changes. Flag delivery can override this behavior by
539
+ # sending a new server intent to any connected stream.
540
+ @intent = IntentCode::TRANSFER_CHANGES if @intent == IntentCode::TRANSFER_FULL
541
+
542
+ changeset
543
+ end
544
+
545
+ #
546
+ # Adds a new object to the changeset.
547
+ #
548
+ # @param kind [String] The object kind ({ObjectKind})
549
+ # @param key [String] The key
550
+ # @param version [Integer] The version
551
+ # @param obj [Hash] The object data
552
+ # @return [void]
553
+ #
554
+ def add_put(kind, key, version, obj)
555
+ @changes << Change.new(
556
+ action: ChangeType::PUT,
557
+ kind: kind,
558
+ key: key,
559
+ version: version,
560
+ object: obj
561
+ )
562
+ end
563
+
564
+ #
565
+ # Adds a deletion to the changeset.
566
+ #
567
+ # @param kind [String] The object kind ({ObjectKind})
568
+ # @param key [String] The key
569
+ # @param version [Integer] The version
570
+ # @return [void]
571
+ #
572
+ def add_delete(kind, key, version)
573
+ @changes << Change.new(
574
+ action: ChangeType::DELETE,
575
+ kind: kind,
576
+ key: key,
577
+ version: version
578
+ )
579
+ end
580
+ end
581
+
582
+ #
583
+ # Update represents the results of a synchronizer's ongoing sync method.
584
+ #
585
+ # This type is not stable, and not subject to any backwards
586
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
587
+ #
588
+ # Do not use it.
589
+ # You have been warned.
590
+ #
591
+ class Update
592
+ # @return [Symbol] The data source state ({LaunchDarkly::Interfaces::DataSource::Status})
593
+ attr_reader :state
594
+
595
+ # @return [ChangeSet, nil] The change set
596
+ attr_reader :change_set
597
+
598
+ # @return [LaunchDarkly::Interfaces::DataSource::ErrorInfo, nil] Error information
599
+ attr_reader :error
600
+
601
+ # @return [Boolean] Whether to revert to FDv1
602
+ attr_reader :revert_to_fdv1
603
+
604
+ # @return [String, nil] The environment ID
605
+ attr_reader :environment_id
606
+
607
+ #
608
+ # @param state [Symbol] The data source state ({LaunchDarkly::Interfaces::DataSource::Status})
609
+ # @param change_set [ChangeSet, nil] The change set
610
+ # @param error [LaunchDarkly::Interfaces::DataSource::ErrorInfo, nil] Error information
611
+ # @param revert_to_fdv1 [Boolean] Whether to revert to FDv1
612
+ # @param environment_id [String, nil] The environment ID
613
+ #
614
+ def initialize(state:, change_set: nil, error: nil, revert_to_fdv1: false, environment_id: nil)
615
+ @state = state
616
+ @change_set = change_set
617
+ @error = error
618
+ @revert_to_fdv1 = revert_to_fdv1
619
+ @environment_id = environment_id
620
+ end
621
+ end
622
+
623
+ #
624
+ # SelectorStore represents a component capable of providing Selectors for data retrieval.
625
+ #
626
+ # This type is not stable, and not subject to any backwards
627
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
628
+ #
629
+ # Do not use it.
630
+ # You have been warned.
631
+ #
632
+ module SelectorStore
633
+ #
634
+ # Returns a Selector object that defines the criteria for data retrieval.
635
+ #
636
+ # @return [Selector]
637
+ #
638
+ def selector
639
+ raise NotImplementedError, "#{self.class} must implement #selector"
640
+ end
641
+ end
642
+
643
+ #
644
+ # ReadOnlyStore represents a read-only store interface for retrieving data.
645
+ #
646
+ # This type is not stable, and not subject to any backwards
647
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
648
+ #
649
+ # Do not use it.
650
+ # You have been warned.
651
+ #
652
+ module ReadOnlyStore
653
+ #
654
+ # Retrieves an item by kind and key.
655
+ #
656
+ # @param kind [LaunchDarkly::Impl::DataStore::DataKind] The data kind (e.g., LaunchDarkly::Impl::DataStore::FEATURES, LaunchDarkly::Impl::DataStore::SEGMENTS)
657
+ # @param key [String] The item key
658
+ # @return [Hash, nil] The item, or nil if not found or deleted
659
+ #
660
+ def get(kind, key)
661
+ raise NotImplementedError, "#{self.class} must implement #get"
662
+ end
663
+
664
+ #
665
+ # Retrieves all items of a given kind.
666
+ #
667
+ # @param kind [LaunchDarkly::Impl::DataStore::DataKind] The data kind (e.g., LaunchDarkly::Impl::DataStore::FEATURES, LaunchDarkly::Impl::DataStore::SEGMENTS)
668
+ # @return [Hash] Hash of keys to items (excluding deleted items)
669
+ #
670
+ def all(kind)
671
+ raise NotImplementedError, "#{self.class} must implement #all"
672
+ end
673
+
674
+ #
675
+ # Returns whether the store has been initialized.
676
+ #
677
+ # @return [Boolean]
678
+ #
679
+ def initialized?
680
+ raise NotImplementedError, "#{self.class} must implement #initialized?"
681
+ end
682
+ end
683
+
684
+ #
685
+ # Initializer represents a component capable of retrieving a single data result.
686
+ #
687
+ # This type is not stable, and not subject to any backwards
688
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
689
+ #
690
+ # Do not use it.
691
+ # You have been warned.
692
+ #
693
+ module Initializer
694
+ #
695
+ # Returns the name of the initializer.
696
+ #
697
+ # @return [String]
698
+ #
699
+ def name
700
+ raise NotImplementedError, "#{self.class} must implement #name"
701
+ end
702
+
703
+ #
704
+ # Retrieves the initial data set for the data source.
705
+ #
706
+ # @param selector_store [SelectorStore] Provides the Selector
707
+ # @return [LaunchDarkly::Result<Basis, String>]
708
+ #
709
+ def fetch(selector_store)
710
+ raise NotImplementedError, "#{self.class} must implement #fetch"
711
+ end
712
+ end
713
+
714
+ #
715
+ # Synchronizer represents a component capable of synchronizing data from an external source.
716
+ #
717
+ # This type is not stable, and not subject to any backwards
718
+ # compatibility guarantees or semantic versioning. It is not suitable for production usage.
719
+ #
720
+ # Do not use it.
721
+ # You have been warned.
722
+ #
723
+ module Synchronizer
724
+ #
725
+ # Returns the name of the synchronizer.
726
+ #
727
+ # @return [String]
728
+ #
729
+ def name
730
+ raise NotImplementedError, "#{self.class} must implement #name"
731
+ end
732
+
733
+ #
734
+ # Begins the synchronization process, yielding Update objects.
735
+ #
736
+ # @param selector_store [SelectorStore] Provides the Selector
737
+ # @yieldparam update [Update] The update
738
+ # @return [void]
739
+ #
740
+ def sync(selector_store, &block)
741
+ raise NotImplementedError, "#{self.class} must implement #sync"
742
+ end
743
+
744
+ #
745
+ # Halts the synchronization process.
746
+ #
747
+ # @return [void]
748
+ #
749
+ def stop
750
+ raise NotImplementedError, "#{self.class} must implement #stop"
751
+ end
752
+ end
753
+ end
754
+ end
755
+ end