Class: LaunchDarkly::Impl::DataStore::Store Private

Inherits:
Object
  • Object
show all
Includes:
LaunchDarkly::Interfaces::DataSystem::SelectorStore
Defined in:
lib/ldclient-rb/impl/data_store/store.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Store is a dual-mode persistent/in-memory store that serves requests for data from the evaluation algorithm.

At any given moment one of two stores is active: in-memory, or persistent. Once the in-memory store has data (either from initializers or a synchronizer), the persistent store is no longer read from. From that point forward, calls to get data will serve from the memory store.

Since:

  • 5.5.0

Instance Method Summary collapse

Constructor Details

#initialize(flag_change_broadcaster, change_set_broadcaster, logger) ⇒ Store

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initialize a new Store.

Parameters:

Since:

  • 5.5.0



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/ldclient-rb/impl/data_store/store.rb', line 32

def initialize(flag_change_broadcaster, change_set_broadcaster, logger)
  @logger = logger
  @persistent_store = nil
  @persistent_store_status_provider = nil
  @persistent_store_writable = false

  # Source of truth for flag evaluations once initialized
  @memory_store = InMemoryFeatureStoreV2.new(logger)

  # Used to track dependencies between items in the store. Items are keyed by string,
  # the form in which the data model names prerequisites and segments.
  @dependency_tracker = LaunchDarkly::Impl::DependencyTracker.new(logger)

  # Broadcasters for events
  @flag_change_broadcaster = flag_change_broadcaster
  @change_set_broadcaster = change_set_broadcaster

  # True if the data in the memory store may be persisted to the persistent store
  @persist = false

  # Points to the active store. Swapped upon initialization.
  @active_store = @memory_store

  # Identifies the current data
  @selector = LaunchDarkly::Interfaces::DataSystem::Selector.no_selector

  # Thread synchronization
  @lock = Mutex.new
end

Instance Method Details

#apply(change_set, persist) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Apply a changeset to the store.

Parameters:

Since:

  • 5.5.0



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/ldclient-rb/impl/data_store/store.rb', line 116

def apply(change_set, persist)
  collections = changes_to_store_data(change_set.changes)

  @lock.synchronize do
    begin
      case change_set.intent_code
      when LaunchDarkly::Interfaces::DataSystem::IntentCode::TRANSFER_FULL
        set_basis(collections, change_set.selector, persist)
      when LaunchDarkly::Interfaces::DataSystem::IntentCode::TRANSFER_CHANGES
        apply_delta(collections, change_set.selector, persist)
      when LaunchDarkly::Interfaces::DataSystem::IntentCode::TRANSFER_NONE
        # No-op, no changes to apply
        return
      end

      # Notify changeset listeners
      @change_set_broadcaster.broadcast(change_set)
    rescue => e
      @logger.error { "[LDClient] Couldn't apply changeset: #{e.message}" }
    end
  end
end

#close ⇒ Exception?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Close the store and any persistent store if configured.

Returns:

  • (Exception, nil) —

    Exception if close failed, nil otherwise

Since:

  • 5.5.0



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/ldclient-rb/impl/data_store/store.rb', line 95

def close
  @lock.synchronize do
    return nil if @persistent_store.nil?

    begin
      @persistent_store.stop if @persistent_store.respond_to?(:stop)
    rescue => e
      return e
    end
  end

  nil
end

#commit ⇒ Exception?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Commit persists the data in the memory store to the persistent store, if configured.

Returns:

  • (Exception, nil) —

    Exception if commit failed, nil otherwise

Since:

  • 5.5.0



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/ldclient-rb/impl/data_store/store.rb', line 144

def commit
  @lock.synchronize do
    return nil unless should_persist?

    begin
      # Get all data from memory store and write to persistent store
      all_data = {}
      [FEATURES, SEGMENTS].each do |kind|
        all_data[kind] = @memory_store.all(kind)
      end
      @persistent_store.init(all_data)
    rescue => e
      return e
    end
  end

  nil
end

#get_active_store ⇒ LaunchDarkly::Interfaces::FeatureStore

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the currently active store for reading data.

Returns:

Since:

  • 5.5.0



168
169
170
171
172
# File 'lib/ldclient-rb/impl/data_store/store.rb', line 168

def get_active_store
  @lock.synchronize do
    @active_store
  end
end

#get_data_store_status_provider ⇒ LaunchDarkly::Impl::DataStore::StatusProviderV2?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the data store status provider for the persistent store, if configured.

Returns:

Since:

  • 5.5.0



188
189
190
191
192
# File 'lib/ldclient-rb/impl/data_store/store.rb', line 188

def get_data_store_status_provider
  @lock.synchronize do
    @persistent_store_status_provider
  end
end

#initialized? ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if the active store is initialized.

Returns:

  • (Boolean)

Since:

  • 5.5.0



179
180
181
# File 'lib/ldclient-rb/impl/data_store/store.rb', line 179

def initialized?
  get_active_store.initialized?
end

#selector ⇒ Selector

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a Selector object that defines the criteria for data retrieval.

Returns:

  • (Selector)

Since:

  • 5.5.0



84
85
86
87
88
# File 'lib/ldclient-rb/impl/data_store/store.rb', line 84

def selector
  @lock.synchronize do
    @selector
  end
end

#with_persistence(persistent_store, writable, status_provider = nil) ⇒ Store

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Configure the store with a persistent store for read-only or read-write access.

Parameters:

Returns:

  • (Store) —

    self for method chaining

Since:

  • 5.5.0



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/ldclient-rb/impl/data_store/store.rb', line 70

def with_persistence(persistent_store, writable, status_provider = nil)
  @lock.synchronize do
    @persistent_store = persistent_store
    @persistent_store_writable = writable
    @persistent_store_status_provider = status_provider

    # Initially use persistent store as active until memory store has data
    @active_store = persistent_store
  end

  self
end