Git Product home page Git Product logo

octoshark's Introduction

Travis status

Octoshark

Octoshark is a simple ActiveRecord connection switcher. It provides a general purpose connection switching mechanism that can be used in sharding and master-slave multi-database environments. It's up to you to specify how ActiveRecord models will use the Octoshark connections, see below for example scenarios.

Installation

Add this line to your application's Gemfile:

gem 'octoshark'

And then execute:

$ bundle

Or install it yourself as:

$ gem install octoshark

Usage

Specify the connections for Octoshark to manage. This is usually done in an app initializer.

Octoshark.configure({
  db1: { adapter: "sqlite3", database: "db/db1.sqlite" },
  db2: { adapter: "sqlite3", database: "db/db2.sqlite" }
})

Configure which ActiveRecord models will use the Octoshark connection by overriding the Model.connection method. If there are many models, extract it in a module and include it.

class Post < ActiveRecord::Base
  def self.connection
    Octoshark.current_connection
  end
end

To use a specific database connection, do:

Octoshark.with_connection(:db1) do
  # work with db1
  Post.first
end

Octoshark connection is changed for the duration of the block and then reversed back to the previous connection.

Octoshark.current_connection returns the active connection while in with_connection block, and outside it raises Octoshark::NoCurrentConnectionError error.

Multiple connection switch blocks can be nested:

Octoshark.with_connection(:db1) do
  # work with db1

  Octoshark.with_connection(:db2) do
    # work with db2
  end

  # work with db1
end

Sharding Example

For example, let's say we have few models that are in the default Rails database (User, Account, etc) and few models that we want to shard (Blog, Post, Comment, etc). For all models in the default database, we can use the default ActiveRecord connection, and for all sharded models we need to the Octoshark connection.

We specify the connection for the sharded models based on the shard key (User) in a controller with an around filter:

# before_filter :find_user
around_filter :select_shard

def select_shard(&block)
  Octoshark.with_connection(current_user.shard, &block)
end

Similarly, in all other application entry-points that start with the default ActiveRecord connection (background jobs for an example), we need to switch the shard connection and then proceed.

Master-Slave Example

When we want to do something in the slave database with all ActiveRecord models, then we need to add Octoshark's current or default connection to all models, either by overriding ActiveRecord:Base.connection or using a module that we include in all models.

class ActiveRecord::Base
  def self.connection
    # Some rake tasks like `rake db:create` does not load initializers,
    # and because we're overriding ActiveRecord::Base.connection,
    # we need to make sure Octoshark is configured before using it.
    Octoshark.configure(configs) unless Octoshark.configured?

    # Return the current connection (from with_connection block) or default one
    Octoshark.current_or_default_connection
  end
end

Here we use Octoshark.current_or_default_connection method which returns the current connection while in with_connection block and fallback to the default connection when outside.

Octoshark.reload!

Whenever ActiveRecord::Base establishes a new database connection, Octoshark.reload! is called. This is necessary for Octoshark to disconnect old connection pools and set new ones, otherwise ActiveRecord::ConnectionNotEstablished will be raised.

Few examples where database connections are re-established:

  • Unicorn before/after fork
  • Spring prefork/serve
  • Some rake tasks like rake db:test:prepare

Database Cleaner

Here's an example how to clean default and shard databases using both default connection and Octoshark connections:

config.before(:suite) do
  clean_database_with(:truncation)
end

config.before(:each) do
  DatabaseCleaner.start
end

config.after(:each) do
  clean_database_with(:transaction)
end

def clean_database_with
  # default ActiveRecord::Base connection pool
  DatabaseCleaner[:active_record, {connection: ActiveRecord::Base.connection_pool}]

  # Octoshark connection pool for the connection
  Octoshark.connection_pools.each_pair do |name, connection_pool|
    DatabaseCleaner[:active_record, {connection: connection_pool}]
  end

  DatabaseCleaner.clean_with(strategy)
end

Contributing

  1. Fork it ( http://github.com/dalibor/octoshark/fork )
  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

octoshark's People

Contributors

dalibor avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.