Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/looping_batcher.rb')
-rw-r--r--lib/gitlab/looping_batcher.rb99
1 files changed, 0 insertions, 99 deletions
diff --git a/lib/gitlab/looping_batcher.rb b/lib/gitlab/looping_batcher.rb
deleted file mode 100644
index adf0aeda506..00000000000
--- a/lib/gitlab/looping_batcher.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- # Returns an ID range within a table so it can be iterated over. Repeats from
- # the beginning after it reaches the end.
- #
- # Used by Geo in particular to iterate over a replicable and its registry
- # table.
- #
- # Tracks a cursor for each table, by "key". If the table is smaller than
- # batch_size, then a range for the whole table is returned on every call.
- class LoopingBatcher
- # @param [Class] model_class the class of the table to iterate on
- # @param [String] key to identify the cursor. Note, cursor is already unique
- # per table.
- # @param [Integer] batch_size to limit the number of records in a batch
- def initialize(model_class, key:, batch_size: 1000)
- @model_class = model_class
- @key = key
- @batch_size = batch_size
- end
-
- # @return [Range] a range of IDs. `nil` if 0 records at or after the cursor.
- def next_range!
- return unless @model_class.any?
-
- batch_first_id = cursor_id
-
- batch_last_id = get_batch_last_id(batch_first_id)
- return unless batch_last_id
-
- batch_first_id..batch_last_id
- end
-
- private
-
- # @private
- #
- # Get the last ID of the batch. Increment the cursor or reset it if at end.
- #
- # @param [Integer] batch_first_id the first ID of the batch
- # @return [Integer] batch_last_id the last ID of the batch (not the table)
- def get_batch_last_id(batch_first_id)
- batch_last_id, more_rows = run_query(@model_class.table_name, @model_class.primary_key, batch_first_id, @batch_size)
-
- if more_rows
- increment_batch(batch_last_id)
- else
- reset if batch_first_id > 1
- end
-
- batch_last_id
- end
-
- def run_query(table, primary_key, batch_first_id, batch_size)
- sql = <<~SQL
- SELECT MAX(batch.id) AS batch_last_id,
- EXISTS (
- SELECT #{primary_key}
- FROM #{table}
- WHERE #{primary_key} > MAX(batch.id)
- ) AS more_rows
- FROM (
- SELECT #{primary_key}
- FROM #{table}
- WHERE #{primary_key} >= #{batch_first_id}
- ORDER BY #{primary_key}
- LIMIT #{batch_size}) AS batch;
- SQL
-
- result = ActiveRecord::Base.connection.exec_query(sql).first
-
- [result["batch_last_id"], result["more_rows"]]
- end
-
- def reset
- set_cursor_id(1)
- end
-
- def increment_batch(batch_last_id)
- set_cursor_id(batch_last_id + 1)
- end
-
- # @private
- #
- # @return [Integer] the cursor ID, or 1 if it is not set
- def cursor_id
- Rails.cache.fetch("#{cache_key}:cursor_id") || 1
- end
-
- def set_cursor_id(id)
- Rails.cache.write("#{cache_key}:cursor_id", id)
- end
-
- def cache_key
- @cache_key ||= "#{self.class.name.parameterize}:#{@model_class.name.parameterize}:#{@key}:cursor_id"
- end
- end
-end