Class: OnlineMigrations::LockRetrier
- Inherits:
-
Object
- Object
- OnlineMigrations::LockRetrier
- Defined in:
- lib/online_migrations/lock_retrier.rb
Overview
This class provides a way to automatically retry code that relies on acquiring a database lock in a way designed to minimize impact on a busy production database.
This class defines an interface for child classes to implement to configure timing configurations and the maximum number of attempts.
There are two predefined implementations (see OnlineMigrations::ConstantLockRetrier and OnlineMigrations::ExponentialLockRetrier). It is easy to provide more sophisticated implementations.
Direct Known Subclasses
ConstantLockRetrier, ExponentialLockRetrier, NullLockRetrier
Instance Attribute Summary collapse
-
#connection ⇒ Object
Database connection on which retries are run.
Instance Method Summary collapse
-
#attempts ⇒ Object
Returns the number of retrying attempts.
-
#delay(_attempt) ⇒ Object
Returns sleep time after unsuccessful lock attempt (in seconds).
-
#lock_timeout(_attempt) ⇒ Object
Returns database lock timeout value (in seconds) for specified attempt number.
-
#with_lock_retries(&block) ⇒ void
Executes the block with a retry mechanism that alters the ‘lock_timeout` and sleep time between attempts.
Instance Attribute Details
#connection ⇒ Object
Database connection on which retries are run
51 52 53 |
# File 'lib/online_migrations/lock_retrier.rb', line 51 def connection @connection end |
Instance Method Details
#attempts ⇒ Object
Returns the number of retrying attempts
55 56 57 |
# File 'lib/online_migrations/lock_retrier.rb', line 55 def attempts raise NotImplementedError end |
#delay(_attempt) ⇒ Object
Returns sleep time after unsuccessful lock attempt (in seconds)
69 70 71 |
# File 'lib/online_migrations/lock_retrier.rb', line 69 def delay(_attempt) raise NotImplementedError end |
#lock_timeout(_attempt) ⇒ Object
Returns database lock timeout value (in seconds) for specified attempt number
63 |
# File 'lib/online_migrations/lock_retrier.rb', line 63 def lock_timeout(_attempt); end |
#with_lock_retries(&block) ⇒ void
This method returns an undefined value.
Executes the block with a retry mechanism that alters the ‘lock_timeout` and sleep time between attempts.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/online_migrations/lock_retrier.rb', line 83 def with_lock_retries(&block) return yield if lock_retries_disabled? current_attempt = 0 begin current_attempt += 1 current_lock_timeout = lock_timeout(current_attempt) if current_lock_timeout with_lock_timeout(current_lock_timeout.in_milliseconds, &block) else yield end rescue ActiveRecord::LockWaitTimeout if current_attempt <= attempts current_delay = delay(current_attempt) Utils.say("Lock timeout. Retrying in #{current_delay} seconds...") sleep(current_delay) retry end raise end end |