Class: Pgtk::Retry
- Inherits:
-
Object
- Object
- Pgtk::Retry
- Defined in:
- lib/pgtk/retry.rb
Overview
Retry is a decorator for Pool that automatically retries failed SELECT queries. It provides fault tolerance for transient database errors by retrying read-only operations a configurable number of times before giving up.
This class implements the same interface as Pool but adds retry logic specifically for SELECT queries. Non-SELECT queries are executed without retry to maintain data integrity and avoid unintended side effects from duplicate writes.
Basic usage:
# Create and configure a regular pool
pool = Pgtk::Pool.new(wire, max: 4)
pool.start!
# Wrap the pool in a retry decorator with 3 attempts
retry_pool = Pgtk::Retry.new(pool, attempts: 3)
# SELECT queries are automatically retried on failure
begin
retry_pool.exec('SELECT * FROM users WHERE id = $1', [42])
rescue PG::Error => e
puts "Query failed after 3 attempts: #{e.}"
end
# Non-SELECT queries are not retried
retry_pool.exec('UPDATE users SET active = true WHERE id = $1', [42])
# Transactions pass through without retry logic
retry_pool.transaction do |t|
t.exec('SELECT * FROM accounts') # No retry within transaction
t.exec('UPDATE accounts SET balance = balance + 100')
end
# Combining with other decorators
impatient = Pgtk::Impatient.new(retry_pool, 5)
spy = Pgtk::Spy.new(impatient) do |sql, duration|
puts "Query: #{sql} (#{duration}s)"
end
- Author
-
Yegor Bugayenko ([email protected])
- Copyright
-
Copyright © 2019-2025 Yegor Bugayenko
- License
-
MIT
Instance Method Summary collapse
-
#dump ⇒ Object
Convert internal state into text.
-
#exec(sql) ⇒ Array
Execute a SQL query with automatic retry for SELECT queries.
-
#initialize(pool, attempts: 3) ⇒ Retry
constructor
Constructor.
-
#start! ⇒ Object
Start a new connection pool with the given arguments.
-
#transaction {|Object| ... } ⇒ Object
Run a transaction without retry logic.
-
#version ⇒ String
Get the version of PostgreSQL server.
Constructor Details
#initialize(pool, attempts: 3) ⇒ Retry
Constructor.
55 56 57 58 |
# File 'lib/pgtk/retry.rb', line 55 def initialize(pool, attempts: 3) @pool = pool @attempts = attempts end |
Instance Method Details
#dump ⇒ Object
Convert internal state into text.
73 74 75 76 77 78 79 |
# File 'lib/pgtk/retry.rb', line 73 def dump [ @pool.dump, '', "Pgtk::Retry (attempts=#{@attempts})" ].join("\n") end |
#exec(sql) ⇒ Array
Execute a SQL query with automatic retry for SELECT queries.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/pgtk/retry.rb', line 85 def exec(sql, *) query = sql.is_a?(Array) ? sql.join(' ') : sql if query.strip.upcase.start_with?('SELECT') attempt = 0 begin @pool.exec(sql, *) rescue StandardError => e attempt += 1 raise e if attempt >= @attempts retry end else @pool.exec(sql, *) end end |
#start! ⇒ Object
Start a new connection pool with the given arguments.
61 62 63 |
# File 'lib/pgtk/retry.rb', line 61 def start! @pool.start! end |
#transaction {|Object| ... } ⇒ Object
Run a transaction without retry logic.
105 106 107 |
# File 'lib/pgtk/retry.rb', line 105 def transaction(&) @pool.transaction(&) end |
#version ⇒ String
Get the version of PostgreSQL server.
68 69 70 |
# File 'lib/pgtk/retry.rb', line 68 def version @pool.version end |