-
Notifications
You must be signed in to change notification settings - Fork 897
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Batch saving strategy that does not require unique indexes #15627
Changes from all commits
72e9c38
cdb3058
862820b
a60bfa2
b753983
05cfb60
25bf34f
f59cfcb
3127e3d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ class InventoryCollection | |
:inventory_object_attributes, :name, :saver_strategy, :parent_inventory_collections, :manager_uuids, | ||
:skeletal_manager_uuids, :targeted_arel, :targeted, :manager_ref_allowed_nil, :use_ar_object, | ||
:secondary_refs, :secondary_indexes, :created_records, :updated_records, :deleted_records, | ||
:custom_reconnect_block | ||
:custom_reconnect_block, :batch_extra_attributes | ||
|
||
delegate :each, :size, :to => :to_a | ||
|
||
|
@@ -321,6 +321,8 @@ class InventoryCollection | |
# Allowed saver strategies are: | ||
# - :default => Using Rails saving methods, this way is not safe to run in multiple workers concurrently, | ||
# since it will lead to non consistent data. | ||
# - :batch => Using batch SQL queries, this way is not safe to run in multiple workers | ||
# concurrently, since it will lead to non consistent data. | ||
# - :concurrent_safe => This method is designed for concurrent saving. It uses atomic upsert to avoid | ||
# data duplication and it uses timestamp based atomic checks to avoid new data being overwritten by the | ||
# the old data. | ||
|
@@ -368,14 +370,18 @@ class InventoryCollection | |
# @param use_ar_object [Boolean] True or False. Whether we need to initialize AR object as part of the saving | ||
# it's needed if the model have special setters, serialize of columns, etc. This setting is relevant only | ||
# for the batch saver strategy. | ||
# @param batch_extra_attributes [Array] Array of symbols marking which extra attributes we want to store into the | ||
# db. These extra attributes might be a product of :use_ar_object assignment and we need to specify them | ||
# manually, if we want to use a batch saving strategy and we have models that populate attributes as a side | ||
# effect. | ||
def initialize(model_class: nil, manager_ref: nil, association: nil, parent: nil, strategy: nil, saved: nil, | ||
custom_save_block: nil, delete_method: nil, data_index: nil, data: nil, dependency_attributes: nil, | ||
attributes_blacklist: nil, attributes_whitelist: nil, complete: nil, update_only: nil, | ||
check_changed: nil, custom_manager_uuid: nil, custom_db_finder: nil, arel: nil, builder_params: {}, | ||
inventory_object_attributes: nil, unique_index_columns: nil, name: nil, saver_strategy: nil, | ||
parent_inventory_collections: nil, manager_uuids: [], all_manager_uuids: nil, targeted_arel: nil, | ||
targeted: nil, manager_ref_allowed_nil: nil, secondary_refs: {}, use_ar_object: nil, | ||
custom_reconnect_block: nil) | ||
custom_reconnect_block: nil, batch_extra_attributes: []) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like there are a ridiculous number of parameters to this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @chessbyte indeed, we are at the point where this should be a final list, that should cover all the crazy corner cases we have. :-) So next will be to refactor these, part will got to the Settings, rest should be divided into more objects we will pass here(also consuming settings). There are already several areas we can group, e..g Saver, DatabaseLoader, AttributesBuilder, RecordsMatcher, etc. |
||
@model_class = model_class | ||
@manager_ref = manager_ref || [:ems_ref] | ||
@secondary_refs = secondary_refs | ||
|
@@ -402,6 +408,7 @@ def initialize(model_class: nil, manager_ref: nil, association: nil, parent: nil | |
@name = name || association || model_class.to_s.demodulize.tableize | ||
@saver_strategy = process_saver_strategy(saver_strategy) | ||
@use_ar_object = use_ar_object || false | ||
@batch_extra_attributes = batch_extra_attributes | ||
|
||
@manager_ref_allowed_nil = manager_ref_allowed_nil || [] | ||
|
||
|
@@ -502,11 +509,11 @@ def process_saver_strategy(saver_strategy) | |
return :default unless saver_strategy | ||
|
||
case saver_strategy | ||
when :default, :concurrent_safe, :concurrent_safe_batch | ||
when :default, :batch, :concurrent_safe, :concurrent_safe_batch | ||
saver_strategy | ||
else | ||
raise "Unknown InventoryCollection saver strategy: :#{saver_strategy}, allowed strategies are "\ | ||
":default, :concurrent_safe and :concurrent_safe_batch" | ||
":default, :batch, :concurrent_safe and :concurrent_safe_batch" | ||
end | ||
end | ||
|
||
|
@@ -996,7 +1003,7 @@ def full_collection_for_comparison | |
|
||
# Returns array of records identities | ||
def records_identities(records) | ||
records = [records] unless records.kind_of?(Array) | ||
records = [records] unless records.respond_to?(:map) | ||
records.map { |record| record_identity(record) } | ||
end | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module ManagerRefresh::SaveCollection | ||
module Saver | ||
class Batch < ManagerRefresh::SaveCollection::Saver::ConcurrentSafeBatch | ||
private | ||
|
||
def unique_index_columns | ||
inventory_collection.manager_ref_to_cols.map(&:to_sym) | ||
end | ||
|
||
def on_conflict_update | ||
false | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Scratch that, needs unique indexes https://www.postgresql.org/docs/9.5/static/sql-insert.html#SQL-ON-CONFLICT |
||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ladas do you have an example of needing this currently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for vm, when we change :raw_power_state, other attributes are set, so we need to have
:batch_extra_attributes => [:power_state, :state_changed_on, :previous_state],
hopefully this can be autodiscovered later, while passing the same specs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 thanks