Skip to content

Instantly share code, notes, and snippets.

@ethnt
Last active February 24, 2017 19:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ethnt/9c96de38f7801b5f771322c2c9a876c8 to your computer and use it in GitHub Desktop.
Save ethnt/9c96de38f7801b5f771322c2c9a876c8 to your computer and use it in GitHub Desktop.
A resettable timeout for Ruby
require 'redis'
@redis = Redis.new
@redis.set('timeout', 0)
require 'redis'
module Referee
class Timeout < StandardError; end
class Timer
def initialize(key, limit = 5, &block)
@redis = Redis.new
@key = key
@limit = limit
@redis.set(@key, @limit)
start
@work = Thread.new { yield self }
@work.join
@timer.join if @timed_out
end
def start
@timer = Thread.new do
@counter = 0
# TODO: Use promises to make sure we have the limit from redis before
# incrementing the counter.
loop do
@limit = @redis.get(@key).to_i
@counter += 1
if @counter > @limit
break
end
sleep(1)
end
@timed_out = true
@work.kill
raise Referee::Timeout
end
end
def stop
@timer.kill
end
def reset
stop
start
end
end
end
require_relative 'referee'
begin
Referee::Timer.new(5) do |timer|
sleep(1)
puts "yup"
sleep(5)
puts "nope"
end
rescue Referee::Timeout
puts "timed out!"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment