Skip to content

Instantly share code, notes, and snippets.

@soulcutter
Created April 8, 2018 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save soulcutter/8175b9ca74b4c8e6ba97f5f35d1ed3cf to your computer and use it in GitHub Desktop.
Save soulcutter/8175b9ca74b4c8e6ba97f5f35d1ed3cf to your computer and use it in GitHub Desktop.
A simple way to throttle enumeration
class SpeedLimit
def initialize(enumerator)
@enumerator = enumerator.to_enum
end
def at(count, per:)
increment_seconds = case per
when :second then 1.0 / count.to_f
when :minute then 60.0 / count.to_f
when :hour then 3600.0 / count.to_f
else raise ArgumentError, "Expected :second, :hour, or :minute, got #{per.inspect}"
end
Enumerator.new do |yielder|
loop do
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
yielder.yield(@enumerator.next).tap do
end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
duration = end_time - start_time
wait = increment_seconds - duration
Kernel.sleep wait
end
end
end
end
end
SpeedLimit.new(1..10).at(6, per: :second).each { |x| puts x }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment