Play nicely with adapters of form "mysql*_master_slave"

This commit moves the massage method into the intialize method of the
master_slave_adapter, where the massage()'d config is actually required.

We need to configure our adapter as 'mysql2_master_slave' so that we can run migrations
and other rake tasks. The expected/usual way of using the master_slave_adapter
is to specify:

  adapter: master_slave_adapter
  connection_adapter: mysql2

We need to specify:

  adapter: mysql2_master_slave_adapter
  connection_adapter: mysql2

One restriction is that we need to give it a name that will match the `/mysql/`
regex used by Rails in the `db:*` Rake tasks namespace (see
`activerecord/lib/active_record/railties/databases.rake`).  Without it, things
like migrations and Rake tasks will not work.

Unfortunately the Rails migration code directly hacks the
ActiveRecord::Base.connection, and so this change won't fix migrations, for
example, it will check the `schema_migrations` table on the slave in order to
decide what migrations to run, then run them on the master.  Ideally, it would
do all of this on the master alone.  In practice, we should be ok, and if we
want to be truly resilient we can make a "migration" environment that doesn't
have master-slave stuff configured at all, forcing migrations to always run on
the master.

Change-Id: I70242c48dc6f770c8ae3911a105a6feff8a56aae
Reviewed-on: https://gerrit.causes.com/16881
Reviewed-by: John Skopis <john.skopis@causes.com>
Tested-by: John Skopis <john.skopis@causes.com>
Support multiple clock and lag strategies

This commit refactors the default master slave adapter behaviors into different
modules:

Constency Behaviors:

  DefaultClock: Uses a Clock comparator to compare master/slave position
  HeartbeatClock: Queries a heartbeat table to determine consistency

Lag Strategies:

  DefaultStrategy: Only checks consistency in with_consistency
  RelaxedStrategy: Checks consistency by default, falling back to master if the
    amount of lag is greater than the allowed lag (config[:loose_lag]). When
    `with_constency` is requested the config[:strict_lag] threshold is used instead.
  StrictStrategy: Checks consistenvy by default, raising a LagException if the
    amount of lag is greater than the allowed lag (config[:loose_lag]). When
    `with_constency` is requested the config[:strict_lag] threshold is used instead.

The way to enable a HeartbeatClock or DefaultClock is to set
config[:clock_implementation] to 'HeartbeatClock' or 'DefaultClock'.

The way to enable a LagStrategy is to set config[:lag_strategy] to one of
'DefaultStrategy', 'RelaxedStrategy', or 'StrictStrategy'.

Change-Id: I2e9049bec9d8ef303c265588c0870a8f0bdff4eb
Reviewed-on: https://gerrit.causes.com/17242
Reviewed-by: John Skopis <john.skopis@causes.com>
Tested-by: John Skopis <john.skopis@causes.com>
Add test coverage for *Clock and *Strategy

We introduced the lag strategies 'RelaxedStrategy' and 'StrictStrategy' without
test coverage. Additionally, the default tests did not cover the case of an
inconsistent slave, likely because the default strategy does not attempt to
deal with slave lag unles with_consistency is used.

We broke master_slave_adapter_spec into a spec per strategy. Each spec will use
as much of the shared behavior (spec/common/support/strategies/default),
as possible.

TODO (grep for TODO):
  * fixup integration tests (or fixup clock interface)

Change-Id: I536803f92af32c837c36797edf6516ec2172562b
Reviewed-on: https://gerrit.causes.com/17349
Reviewed-by: John Skopis <john.skopis@causes.com>
Tested-by: John Skopis <john.skopis@causes.com>
Fix gemspec to not rely on `git`

This makes our deploys noisy, which makes me sad.

Related story:
  https://www.pivotaltracker.com/story/show/45264223
  ("Fix master_slave_adapter gemspec to not rely on `git`")

Change-Id: I944e723fd77d8819c456d35d347800a58e4efe45
Reviewed-on: https://gerrit.causes.com/19206
Tested-by: Aiden Scandella <aiden@causes.com>
Reviewed-by: Aiden Scandella <aiden@causes.com>
Handle connection errors inside transactions

Given a master connection, and a connection error, the `handle_error`
method would `reset_master_connection` by setting the connection to
nil.

When the adapter connection is nillified, after rails reconnects
(automatically), rails gets confused and attempts to rollback
transactions, on the fresh connection that does not have any
transactions.

This commit lets rails know the connection needs to be reset by
calling the underlying adapter's `reset!` method. When we call
`reset!`, the master slave adapter is able to raise the original
exception message, wrapped in a ActiveRecord::MasterUnavailable
exception, allowing the caller to handle the down master.

The MasterUnavailable exception should only happen when the connection
is lost mid-transaction, or when the master is legitimately down. In
all other cases the mysql2 client will reconnect via `ping`.

The proper way to handle this exception is:

    begin
      transaction { ... }
    except ActiveRecord::MasterUnavailable => e
      if retryable?
        retry
      else
        log ...
      end
    end

If you must have a long running (idle) transaction make sure the mysql
@@wait_timeout is set to a reasonable value.

Change-Id: Iff3bcaec6f7344d74101440e6b7c424c26927cd3