/sequel-connection_guard

A Sequel extension that provides a set of abstractions for working with unreliable database connections.

Primary LanguageRubyMIT LicenseMIT

sequel-connection_guard

Build Status Coverage Status Gem Version

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

Installation

Add this line to your application's Gemfile:

gem 'sequel-connection_guard'

And then execute:

$ bundle

Enable the extension:

Sequel.extension :connection_guard

Usage

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).

Database guard

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.

Safe access

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

Unsafe access

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 }

Accessing a raw database handle

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.

Model guard

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.

Safe access

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

Unsafe access

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 }

Accessing a raw model

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

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/umbrellio/sequel-connection_guard.

License

The gem is available as open source under the terms of the MIT License.

Authors

Created by Alexander Komarov.

Supported by Umbrellio