Created
April 8, 2018 21:09
-
-
Save soulcutter/8175b9ca74b4c8e6ba97f5f35d1ed3cf to your computer and use it in GitHub Desktop.
A simple way to throttle enumeration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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