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
# 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
  @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



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

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

#closeException?

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



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

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

#commitException?

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



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

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_storeLaunchDarkly::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



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

def get_active_store
  @lock.synchronize do
    @active_store
  end
end

#get_data_store_status_providerLaunchDarkly::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



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

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



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

def initialized?
  get_active_store.initialized?
end

#selectorSelector

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



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

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



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

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