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.