0.01
No commit activity in last 3 years
No release in over 3 years
IO.select based timeouts; an alternative to Ruby's stdlib Timeout module.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.19.3
 Project Readme

MuchTimeout

IO.select based timeouts. This is an alternative to the stdlib's Timeout module that doesn't rely on sleep. This should produce more accurate timeouts with an expanded API for different handling options.

Usage

timeout

require 'much-timeout'

MuchTimeout.timeout(5) do
  # ... something that should be interrupted ...

  # raises a `MuchTimeout::TimeoutError` exception if it takes more than 5 seconds
  # returns the result of the block otherwise
end

MuchTimeout, in its basic form, is a replacement for Timeout. The main difference is that IO.select on an internal pipe is the mechanism for detecting the timeout.

Note: like Timeout, Thread#raise is used to interrupt the block. This technique is widely considered to be dangerous. Be aware and use responsibly.

MuchTimeout.timeout(5, MyCustomTimeoutError) do
  # ... something that should be interrupted ...

  # raises a `MyCustomTimeoutError` exception if it takes more than 5 seconds
end

Like Timeout, you can optionally specify a custom exception class to raise.

optional_timeout

seconds = [5, nil].sample
MuchTimeout.optional_timeout(seconds) do
  # ... something that should be interrupted ...

  # raises an exception if seconds is not nil and it takes more than 5 seconds
  # otherwise the block is called directly and will not be interrupted
end

In addtion to the basic timeout API, MuchTimeout provides optional_timeout which conditionally applies timeout handling based on the given seconds value. Passing nil seconds will just call the block and will not apply any timeout handling (where passing nil seconds to timeout raises an argument error).

just_{optional_}timeout

MuchTimeout.just_timeout(5, :do => proc{
  # ... something that should be interrupted ...

  # interrupt if it takes more than 5 seconds
  # no exceptions are raised (they are all rescued internally)
})

seconds = [5, nil].sample
MuchTimeout.just_optional_timeout(seconds, :do => proc{
  # ... something that should be interrupted ...

  # interrupt if seconds is not nil and it takes more than 5 seconds
  # no exceptions are raised (they are all rescued internally)
})

These alternative timeout methods execute and interrupt the given :do block if it times out. However, no exceptions are raised and no exception handling is required (the Thread#raise interrupt is rescued internally). Use this option to avoid any custom exception handling logic when you don't care about the timeout exception information.

In the case you want to run some custom logic when a timeout occurs, pass an optional :on_timeout proc:

MuchTimeout.just_timeout(5, {
  :do => proc{
    # ... something that should be interrupted ...
  },
  :on_timeout => proc{
    # ... something that should run when a timeout occurs ...
  }
})

This works as you'd expect for both just_timeout and just_optional_timeout.

Installation

Add this line to your application's Gemfile:

gem 'much-timeout'

And then execute:

$ bundle

Or install it yourself as:

$ gem install much-timeout

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request