summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShinya Maeda <shinya@gitlab.com>2018-05-03 15:40:43 +0900
committerShinya Maeda <shinya@gitlab.com>2018-05-03 15:40:43 +0900
commite0cc157b0084734081ca216bc8a5f86781613a93 (patch)
tree4c18ff9af5e4d7673b9696e072b752ececae5e41
parent45dc7ae2d22ceb2679a9c72367f3bb62051ce226 (diff)
downloadgitlab-ce-live-trace-v2-efficient-destroy-all-block-and-lambda.tar.gz
-rw-r--r--app/models/ci/build_trace_chunk.rb14
-rw-r--r--app/models/concerns/fast_destroy_all.rb48
2 files changed, 29 insertions, 33 deletions
diff --git a/app/models/ci/build_trace_chunk.rb b/app/models/ci/build_trace_chunk.rb
index 74b56ffed53..69af5bacddc 100644
--- a/app/models/ci/build_trace_chunk.rb
+++ b/app/models/ci/build_trace_chunk.rb
@@ -6,7 +6,7 @@ module Ci
belongs_to :build, class_name: "Ci::Build", foreign_key: :build_id
default_value_for :data_store, :redis
- fast_destroy_all_with :redis_delete_data, :redis_data_keys
+ # fast_destroy_all_with :redis_delete_data, :redis_data_keys
WriteError = Class.new(StandardError)
@@ -39,6 +39,18 @@ module Ci
redis.del(keys)
end
end
+
+ ##
+ # FastDestroyAll
+ def prepare_to_delete_all
+ keys = redis_data_keys
+
+ yield if block_given?
+
+ lambda do |_|
+ Ci::BuildTraceChunk.redis_delete_data(keys)
+ end
+ end
end
##
diff --git a/app/models/concerns/fast_destroy_all.rb b/app/models/concerns/fast_destroy_all.rb
index 0f6b57ff571..c54e0f2fd6d 100644
--- a/app/models/concerns/fast_destroy_all.rb
+++ b/app/models/concerns/fast_destroy_all.rb
@@ -19,8 +19,6 @@ module FastDestroyAll
ForbiddenActionError = Class.new(StandardError)
included do
- class_attribute :_delete_method, :_delete_params_generator
-
before_destroy do
raise ForbiddenActionError, '`destroy` and `destroy_all` are forbbiden. Please use `fast_destroy_all`'
end
@@ -28,40 +26,27 @@ module FastDestroyAll
class_methods do
##
- # This method is for registering :delete_method and :delete_params_generator
- # You have to define the method if you want to use `FastDestroyAll`` module.
- #
- # e.g. fast_destroy_all_with :delete_all_redis_data, :redis_all_data_keys
- def fast_destroy_all_with(delete_method, delete_params_generator)
- self._delete_method = delete_method
- self._delete_params_generator = delete_params_generator
- end
-
- ##
- # This method generates a proc to delete external data.
- # It's useful especially when you want to hook parent record's deletion event.
- #
- # e.g. before_destroy -> { run_after_commit(&build_trace_chunks.after_commit_cleanup_proc) }
- def after_commit_cleanup_proc
- params = send self._delete_params_generator # rubocop:disable GitlabSecurity/PublicSend
- subject = self # Preserve the subject class, otherwise `proc` uses a different class
-
- proc do
- subject.send subject._delete_method, params # rubocop:disable GitlabSecurity/PublicSend
-
- true
- end
- end
-
- ##
# This method deletes all rows at first and delete all external data at second.
# Before deleting the rows, it generates a proc to delete external data.
# So it won't lose the track of deleting external data, even if it happened after rows had been deleted.
+ # def fast_destroy_all
+ # after_commit_cleanup_proc.tap do |delete_all_external_data|
+ # delete_all
+ # delete_all_external_data.call
+ # end
+ # end
def fast_destroy_all
- after_commit_cleanup_proc.tap do |delete_all_external_data|
+ after_delete = prepare_to_delete_all do
delete_all
- delete_all_external_data.call
end
+
+ after_delete.call(nil)
+ end
+
+ ##
+ # This method has to be defined in the subject class as a class method
+ def prepare_to_delete_all
+ raise NotImplementedError
end
end
@@ -80,8 +65,7 @@ module FastDestroyAll
def use_fast_destroy(relation)
before_destroy do
subject = public_send(relation) # rubocop:disable GitlabSecurity/PublicSend
- after_commit_proc = subject.after_commit_cleanup_proc
- run_after_commit(&after_commit_proc)
+ run_after_commit(&subject.prepare_to_delete_all)
end
end
end