ActiveRecord::PgTimeout

This provides a way to wrap one action in a database transaction that will timeout in a pre-configured time. When the operation times out the transaction is cancelled and a custom handler is executed.

Installation

Add this line to your application's Gemfile:

gem 'activerecord-pgtimeout'

And then execute:

$ bundle

Or install it yourself as:

$ gem install activerecord-pgtimeout

Usage

Given that there is an ActiveRecord model called User, and I want to fetch all users under 10 seconds:

timeoutable_executor = new ActiveRecord::PgTimeout.new(10_000)
users = timeoutable_executor.execute(->{ User.all }, ->{ puts "Timed out user loading"; [] })

The threshold is defined in milliseconds, if the users cannot be fecthed in the configured time the timeout handler lambda will be evaluated and returned. In the example above whenever the timeout occurs we display a message in the console and return an empty collection.

In most use cases we want to handle the timeout case, but whenever we have a global timeout defined, it might be useful to disable the timeout inside our block and ignore the timeout handler. Consider a database with a default timeout of 60 seconds, and we want to execute a long running migration that need to run for as long as it is needed. We could write such migration like this:

timeoutable_executor = new ActiveRecord::PgTimeout.new(0)
timeoutable_executor.execute(->{ execute "CREATE TABLE long_running AS SELECT * FROM pg_sleep(90);" })

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. Please always provide concrete use cases with any feature request or bug report.