class ActiveRecord::OverflowSignalizer
Constants
- DAY
- DEFAULT_AVG
- MAX_VALUE
- VERSION
Public Class Methods
new(logger: nil, models: nil, days_count: 60, signalizer: nil)
click to toggle source
# File lib/activerecord/overflow_signalizer.rb, line 17 def initialize(logger: nil, models: nil, days_count: 60, signalizer: nil) @logger = logger || ActiveRecord::Base.logger @models = models || ActiveRecord::Base.descendants @days_count = days_count @signalizer = signalizer end
Public Instance Methods
analyse()
click to toggle source
# File lib/activerecord/overflow_signalizer.rb, line 49 def analyse analyse! rescue Overflow => e signalize(e.message) end
analyse!()
click to toggle source
# File lib/activerecord/overflow_signalizer.rb, line 24 def analyse! overflowed_tables = [] @models.group_by(&:table_name).each do |table, models| model = models.first next if model.abstract_class? || model.last.nil? pk = model.columns.select { |c| c.name == model.primary_key }.first max = MAX_VALUE.fetch(pk.sql_type) do |type| @logger.warn "Model #{model} has primary_key #{model.primary_key} with unsupported type #{type}" nil end next unless max if overflow_soon?(max, model) if (remaining = max - model.maximum(pk.name)) == 0 @logger.warn("Table #{table} field #{pk.name} has overflown!") else @logger.warn("Table #{table} field #{pk.name} will overflow after #{remaining} records!") end overflowed_tables << [table, model.last.public_send(pk.name), max] else @logger.info("Table #{table} field #{pk.name} is not going to overflow in the next #{@days_count} days.") end end raise Overflow, overflow_message(overflowed_tables) if overflowed_tables.any? end
Private Instance Methods
avg(model)
click to toggle source
# File lib/activerecord/overflow_signalizer.rb, line 65 def avg(model) to = model.last.created_at from = to - 7 * DAY amount = model.where(created_at: from..to).count average = amount / 7 average.zero? ? 1 : average end
overflow_message(overflowed_tables)
click to toggle source
# File lib/activerecord/overflow_signalizer.rb, line 73 def overflow_message(overflowed_tables) overflowed = [] overflow_soon = [] overflowed_tables.each do |table, current_value, max_value| if current_value == max_value overflowed << table else overflow_soon << table end end "Owerflowed tables: #{overflowed}. Overflow soon tables: #{overflow_soon}" end
overflow_soon?(max, model)
click to toggle source
# File lib/activerecord/overflow_signalizer.rb, line 57 def overflow_soon?(max, model) if model.columns.select { |c| c.name == 'created_at' }.empty? (max - model.last.id) / DEFAULT_AVG <= @days_count else (max - model.last.id) / avg(model) <= @days_count end end
signalize(msg)
click to toggle source
# File lib/activerecord/overflow_signalizer.rb, line 86 def signalize(msg) if @logger && @logger.respond_to?(:warn) @logger.warn(msg) end if @signalizer && @signalizer.respond_to?(:signalize) @signalizer.signalize(msg) end end