This Sequel extension provides a set of abstractions for working with databases that might not be reachable at any given moment in time.
This gem was only tested against PostgreSQL databases.
Goals:
- Allow to bootstrap an application when a database server is down
- Allow to safely and explicitly access a database
- In case connection fails, retry on next attempt
Add this line to your application's Gemfile:
gem 'sequel-connection_guard'
And then execute:
$ bundle
Enable the extension:
Sequel.extension :connection_guard
This extension provides two main abstractions for accessing unreliable databases. These are almost
identical, but one allows you to reach a database handle (instance of Sequel::Database
) and
another allows you to reach a Sequel model (instance of Sequel::Model
).
A database guard is what you use to access a database handle. First, you need to instantiate one:
::DB = Sequel::DatabaseGuard.new('postgres://localhost/mydb')
You can perform additional actions upon DB initialization, such as enabling Sequel plugins:
::DB = Sequel::DatabaseGuard.new('postgres://localhost/mydb') do |db|
db.extension :advisory_locking
db.extension :pg_json
end
There are two ways of using the guard.
You can safely access the database handle by using #safe_execute
:
users = DB.safe_execute do
# if the database is reachable
alive do |db|
db[:users].all
end
# if the database could not be reached. NOTE: this is optional
dead do
[]
end
end
When you don't care about safety (or you're already inside a safe_execute
context), use
#force_execute
:
users = DB.force_execute { |db| db[:users].all }
Sometimes it's necessary to get access to a raw instance of Sequel::Database
(for example, when
using the database_cleaner
gem). You can get a raw handle like this:
DB.raw_handle
Beware that this will raise Sequel::DatabaseConnectionError
if the database is currently
unreachable.
A model guard is what you use to access a model handle. To create a model guard:
# NOTE: `DB` must be an instance of Sequel::DatabaseGuard
UserGuard = Sequel::ModelGuard(DB[:users]) do
one_to_many :cookies, class: 'Cookie::RawModel'
def admin?
role == 'admin'
end
end
There are, again, two ways of using the guard.
You can safely access the model by using #safe_execute
:
users = UserGuard.safe_execute do
# if the database is reachable
alive do |model|
model.all
end
# if the database could not be reached. NOTE: this is optional
dead do
[]
end
end
When you don't care about safety (or you're already inside a safe_execute
context), use
#force_execute
:
users = UserGuard.force_execute { |model| model.all }
Sometimes it's necessary to get access to a raw instance of Sequel::Model
(good examples are
using this extension with factory_bot
and describing associations like shown above).
To get the raw model:
User = UserGuard::RawModel
Bug reports and pull requests are welcome on GitHub at https://github.com/umbrellio/sequel-connection_guard.
The gem is available as open source under the terms of the MIT License.
Created by Alexander Komarov.