wanelo/sequel-replica-failover

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Automatic read-only failover for Sequel

[![Gem Version](https://badge.fury.io/rb/sequel-replica-failover.png)](http://badge.fury.io/rb/sequel-replica-failover)
[![Build
Status](https://travis-ci.org/wanelo/sequel-replica-failover.svg?branch=master)](https://travis-ci.org/wanelo/sequel-replica-failover)
[![Code Climate](https://codeclimate.com/github/wanelo/sequel-replica-failover.png)](https://codeclimate.com/github/wanelo/sequel-replica-failover)

This provides a NOT-THREADSAFE sharded connection pool for failing over between configured replicas.

The mechanisms it provides are as follows:

1. When a DatabaseDisconnectError or DatabaseConnectError occurs, the pool attempt to make another connection to the
   :read_only server and retry.
2. The pool will retry `:pool_retry_count` times afterwhich it will raise the exception that triggered the failover.
3. The pool will stick to a working connection for `:pool_stick_timeout` (in seconds) after which it will
   try connecting back to a replica.
4. Anytime a transaction has been started, the pool will NOT failover.

## Installation

Add this line to your application's Gemfile:

    gem 'sequel-replica-failover'

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install sequel-replica-failover

## Usage

When initializing a Sequel connection, set the pool class:

```ruby
DB = Sequel.connect({
                      :adapter => 'postgres',
                      :user => 'postgres',
                      :password => 'postgres',
                      :host => '127.0.0.1',
                      :database => 'postgres',
                      :port => 5432,
                      :pool_class => Sequel::ShardedSingleFailoverConnectionPool,
                      :pool_retry_count => 10,
                      :pool_stick_timeout => 30
                    })
```

Please note that if you were to open a transaction on a `:read_only` connection,
queries could be retried on a different connection. Why one would open a transaction
on a `:read_only` connection is unclear to us, but it is possible and a concern to
be aware of.

## Callbacks

The connection pool allows for user-defined callbacks when a query is retried as well
as when the retry logic is reset (on timeout or on retry count). Callbacks should be
a `Proc`, or something that ducktypes to one.

Callbacks to retry take an `error` object and a `pool`, as follows:

```ruby
Sequel::ShardedSingleFailoverConnectionPool.register_on_retry_callback ->(error, pool) {
  ReportingTool.notify(error)
  puts pool.inspect
  puts pool.failing_over?
}
```

Callbacks on reset take a `pool` object, as follows:

```ruby
Sequel::ShardedSingleFailoverConnectionPool.register_on_reset_callback ->(pool) {
  puts pool.inspect
}
```

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request