Class: ActiveRecord::ConnectionAdapters::PostgreSQLAdapter

Inherits:
AbstractAdapter
  • Object
show all
Defined in:
lib/activerecord_postgresql_retry.rb

Constant Summary collapse

PG_SLEEP_RETRY =
ENV['PG_SLEEP_RETRY'].to_f || 0.33
PG_QUERY_RETRY =
ENV['PG_QUERY_RETRY'].to_i || 0

Instance Method Summary collapse

Instance Method Details

#connectObject



32
33
34
# File 'lib/activerecord_postgresql_retry.rb', line 32

def connect
  with_retry { old_connect }
end

#exec_cache(sql, name, binds) ⇒ Object



20
21
22
# File 'lib/activerecord_postgresql_retry.rb', line 20

def exec_cache(sql, name, binds)
  with_retry { old_exec_cache(sql, name, binds) }
end

#exec_no_cache(sql, name, binds) ⇒ Object



16
17
18
# File 'lib/activerecord_postgresql_retry.rb', line 16

def exec_no_cache(sql, name, binds)
  with_retry { old_exec_no_cache(sql, name, binds) }
end

#execute(sql, name = nil) ⇒ Object



24
25
26
# File 'lib/activerecord_postgresql_retry.rb', line 24

def execute(sql, name = nil)
  with_retry { old_execute(sql, name) }
end

#old_connectObject



10
# File 'lib/activerecord_postgresql_retry.rb', line 10

alias_method :old_connect, :connect

#old_exec_cacheObject



6
# File 'lib/activerecord_postgresql_retry.rb', line 6

alias_method :old_exec_cache, :exec_cache

#old_exec_no_cacheObject



7
# File 'lib/activerecord_postgresql_retry.rb', line 7

alias_method :old_exec_no_cache, :exec_no_cache

#old_executeObject



8
# File 'lib/activerecord_postgresql_retry.rb', line 8

alias_method :old_execute, :execute

#old_reconnect!Object



9
# File 'lib/activerecord_postgresql_retry.rb', line 9

alias_method :old_reconnect!, :reconnect!

#old_transactionObject



11
# File 'lib/activerecord_postgresql_retry.rb', line 11

alias_method :old_transaction, :transaction

#reconnect!Object



28
29
30
# File 'lib/activerecord_postgresql_retry.rb', line 28

def reconnect!
  with_retry { old_reconnect! }
end

#transaction(options = {}, &block) ⇒ Object



36
37
38
# File 'lib/activerecord_postgresql_retry.rb', line 36

def transaction(options = {}, &block)
  with_retry { old_transaction(options = {}, &block) }
end

#with_retryObject



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/activerecord_postgresql_retry.rb', line 40

def with_retry
  retry_count = 0

  begin
    yield
  rescue PG::Error, PG::ConnectionBad, PG::UnableToSend, ActiveRecord::StatementInvalid => ex
    raise unless ex.message =~ /invalid encoding name/ if ex.is_a? PG::Error
    raise if open_transactions != 0
    raise if retry_count >= PG_QUERY_RETRY
    raise unless (
    ex.original_exception.is_a?(PG::ConnectionBad) ||
        ex.original_exception.is_a?(PG::UnableToSend)
    ) if ex.is_a?(ActiveRecord::StatementInvalid) && ex.respond_to?(:original_exception)

    sleep PG_SLEEP_RETRY
    retry_count += 1
    $log.warn "PostgreSQL retry ##{retry_count} '#{defined?(sql) ? sql : ''}' because #{ex}"
    old_reconnect! rescue nil
    retry
  end

end