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:
$ bundleEnable the extension:
Sequel.extension :connection_guardThis 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
endThere 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
endWhen 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_handleBeware 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
endThere 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
endWhen 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::RawModelBug 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.