Giter Club home page Giter Club logo

activerecord-forbid_implicit_connection_checkout's Introduction

[Build Status][circleci]

ActiveRecord-ForbidImplicitCheckout

This gem allows a Thread to prevent itself from checking out out an ActiveRecord connection. This can be useful in preventing your application from accidentally checking out more connections than the database can handle.

Inspired by this blog post: https://bibwild.wordpress.com/2014/07/17/activerecord-concurrency-in-rails4-avoid-leaked-connections/

Installation

Add this line to your application's Gemfile:

gem 'activerecord-forbid_implicit_checkout'

And then execute:

$ bundle

Or install it yourself as:

$ gem install activerecord-forbid_implicit_checkout

Usage

require 'active_record-forbid_implicit_connection_checkout'

Thread.new do
  ActiveRecord::Base.forbid_implicit_connection_checkout_for_thread!
  # Code that doesn't require ActiveRecord
end

If your thread needs a connection at some point

Thread.new do
  ActiveRecord::Base.forbid_implicit_connection_checkout_for_thread!
  # Code that doesn't require ActiveRecord

  ActiveRecord::Base.connection_pool.with_connection do
    # Allow the thread to take a connection within this block
    ActiveRecord::Base.connection
  end

  # Code that doesn't require ActiveRecord
end

Why

Consider the following initially:

require 'active_record-forbid_implicit_connection_checkout'

class Foo
  def self.download(id)
    Net::HTTP.get(URI("http://example.com/products/#{URI.encode(id)}"))
  end
end

class Downloader
  def download_all(ids)
    threads = ids.map do |id|
      Thread.new do
        ActiveRecord::Base.forbid_implicit_connection_checkout_for_thread!
        Foo.download
      end
    end
    threads.each(&:join)
  end
end

Downloader.download_all([1,2,3,4,5])

The developer initially designed this parallel downloading to not be dependent on the database, so the developer feels confident in running many parallel processes of Downloader.download_all.

However, Foo.download might be subject to change.

class SomeModel < ApplicationRecord
  # ...
end

class Foo
  def self.download(id)
    id = SomeModel.find(id).alias_id
    Net::HTTP.get(URI("http://example.com/products/#{URI.encode(id)}"))
  end
end

After this modification to Foo.download, each thread will checkout a new connection to the database. Which could overwhelm the database if there are many parallel processes executing Downloader.download_all. While this violates, the initial assumption about Downloader.download_all using the database, it would have been useful to have a safeguard to prevent this situation from occurring.

The error generated by setting ActiveRecord::Base.forbid_implicit_connection_checkout_for_thread! could have detected this situation during testing which should have failed with ActiveRecord::ImplicitConnectionForbiddenError. In the worst case, the production code running this would have failed with ActiveRecord::ImplicitConnectionForbiddenError, but it would have prevented the database from being overwhelmed and have protected the rest of the application.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install.

To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org .

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/salsify/activerecord-forbid_implicit_checkout.## License

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

activerecord-forbid_implicit_connection_checkout's People

Contributors

atsheehan avatar fgarces avatar gremerritt avatar joshbranham avatar jturkel avatar will89 avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

activerecord-forbid_implicit_connection_checkout's Issues

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.