Class: LaunchDarkly::Impl::Integrations::DynamoDB::DynamoDBFeatureStoreCore Private

Inherits:
DynamoDBStoreImplBase show all
Defined in:
lib/ldclient-rb/impl/integrations/dynamodb_impl.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.

Internal implementation of the DynamoDB feature store, intended to be used with CachingStoreWrapper.

Since:

  • 5.5.0

Constant Summary collapse

VERSION_ATTRIBUTE =

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

Since:

  • 5.5.0

"version"
ITEM_JSON_ATTRIBUTE =

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

Since:

  • 5.5.0

"item"

Instance Method Summary collapse

Constructor Details

#initialize(table_name, opts) ⇒ DynamoDBFeatureStoreCore

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 new instance of DynamoDBFeatureStoreCore.

Since:

  • 5.5.0



57
58
59
# File 'lib/ldclient-rb/impl/integrations/dynamodb_impl.rb', line 57

def initialize(table_name, opts)
  super(table_name, opts)
end

Instance Method Details

#available?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.

Returns:

  • (Boolean)

Since:

  • 5.5.0



65
66
67
68
69
70
71
# File 'lib/ldclient-rb/impl/integrations/dynamodb_impl.rb', line 65

def available?
  resp = get_item_by_keys(inited_key, inited_key)
  !resp.item.nil? && resp.item.length > 0
  true
rescue
  false
end

#descriptionObject

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.

Since:

  • 5.5.0



61
62
63
# File 'lib/ldclient-rb/impl/integrations/dynamodb_impl.rb', line 61

def description
  "DynamoDBFeatureStore"
end

#get_all_internal(kind) ⇒ Object

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.

Since:

  • 5.5.0



109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ldclient-rb/impl/integrations/dynamodb_impl.rb', line 109

def get_all_internal(kind)
  items_out = {}
  req = make_query_for_kind(kind)
  while true
    resp = @client.query(req)
    resp.items.each do |item|
      item_out = unmarshal_item(kind, item)
      items_out[item_out[:key].to_sym] = item_out
    end
    break if resp.last_evaluated_key.nil? || resp.last_evaluated_key.length == 0
    req.exclusive_start_key = resp.last_evaluated_key
  end
  items_out
end

#get_internal(kind, key) ⇒ Object

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.

Since:

  • 5.5.0



104
105
106
107
# File 'lib/ldclient-rb/impl/integrations/dynamodb_impl.rb', line 104

def get_internal(kind, key)
  resp = get_item_by_keys(namespace_for_kind(kind), key)
  unmarshal_item(kind, resp.item)
end

#init_internal(all_data) ⇒ Object

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.

Since:

  • 5.5.0



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/ldclient-rb/impl/integrations/dynamodb_impl.rb', line 73

def init_internal(all_data)
  # Start by reading the existing keys; we will later delete any of these that weren't in all_data.
  unused_old_keys = read_existing_keys(all_data.keys)

  requests = []
  num_items = 0

  # Insert or update every provided item
  all_data.each do |kind, items|
    items.values.each do |item|
      requests.push({ put_request: { item: marshal_item(kind, item) } })
      unused_old_keys.delete([ namespace_for_kind(kind), item[:key] ])
      num_items = num_items + 1
    end
  end

  # Now delete any previously existing items whose keys were not in the current data
  unused_old_keys.each do |tuple|
    del_item = make_keys_hash(tuple[0], tuple[1])
    requests.push({ delete_request: { key: del_item } })
  end

  # Now set the special key that we check in initialized_internal?
  inited_item = make_keys_hash(inited_key, inited_key)
  requests.push({ put_request: { item: inited_item } })

  DynamoDBUtil.batch_write_requests(@client, @table_name, requests)

  @logger.info { "Initialized table #{@table_name} with #{num_items} items" }
end

#initialized_internal?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.

Returns:

  • (Boolean)

Since:

  • 5.5.0



148
149
150
151
# File 'lib/ldclient-rb/impl/integrations/dynamodb_impl.rb', line 148

def initialized_internal?
  resp = get_item_by_keys(inited_key, inited_key)
  !resp.item.nil? && resp.item.length > 0
end

#upsert_internal(kind, new_item) ⇒ Object

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.

Since:

  • 5.5.0



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/ldclient-rb/impl/integrations/dynamodb_impl.rb', line 124

def upsert_internal(kind, new_item)
  encoded_item = marshal_item(kind, new_item)
  begin
    @client.put_item({
      table_name: @table_name,
      item: encoded_item,
      condition_expression: "attribute_not_exists(#namespace) or attribute_not_exists(#key) or :version > #version",
      expression_attribute_names: {
        "#namespace" => PARTITION_KEY,
        "#key" => SORT_KEY,
        "#version" => VERSION_ATTRIBUTE,
      },
      expression_attribute_values: {
        ":version" => new_item[:version],
      },
    })
    new_item
  rescue Aws::DynamoDB::Errors::ConditionalCheckFailedException
    # The item was not updated because there's a newer item in the database.
    # We must now read the item that's in the database and return it, so CachingStoreWrapper can cache it.
    get_internal(kind, new_item[:key])
  end
end