Tell Ruby Program to Wait some amount of time - ruby

How do you tell a Ruby program to wait an arbitrary amount of time before moving on to the next line of code?

Like this:
sleep(num_secs)
The num_secs value can be an integer or float.
Also, if you're writing this within a Rails app, or have included the ActiveSupport library in your project, you can construct longer intervals using the following convenience syntax:
sleep(4.minutes)
# or, even longer...
sleep(2.hours); sleep(3.days) # etc., etc.
# or shorter
sleep(0.5) # half a second

Use sleep like so:
sleep 2
That'll sleep for 2 seconds.
Be careful to give an argument. If you just run sleep, the process will sleep forever. (This is useful when you want a thread to sleep until it's woken.)

I find until very useful with sleep. example:
> time = Time.now
> sleep 2.seconds until Time.now > time + 10.seconds # breaks when true
> # or
> sleep 2 and puts 'still sleeping' until Time.now > time + 10
> # or
> sleep 1.seconds until !req.loading # suggested by ohsully

Like this
sleep(no_of_seconds)
Or you may pass other possible arguments like:
sleep(5.seconds)
sleep(5.minutes)
sleep(5.hours)
sleep(5.days)

Implementation of seconds/minutes/hours, which are rails methods. Note that implicit returns aren't needed, but they look cleaner, so I prefer them. I'm not sure Rails even has .days or if it goes further, but these are the ones I need.
class Integer
def seconds
return self
end
def minutes
return self * 60
end
def hours
return self * 3600
end
def days
return self * 86400
end
end
After this, you can do:
sleep 5.seconds to sleep for 5 seconds. You can do sleep 5.minutes to sleep for 5 min. You can do sleep 5.hours to sleep for 5 hours. And finally, you can do sleep 5.days to sleep for 5 days... You can add any method that return the value of self * (amount of seconds in that timeframe).
As an exercise, try implementing it for months!

sleep 6 will sleep for 6 seconds. For a longer duration, you can also use sleep(6.minutes) or sleep(6.hours).

This is an example of using sleep with sidekiq
require 'sidekiq'
class PlainOldRuby
include Sidekiq::Worker
def perform(how_hard="super hard", how_long=10)
sleep how_long
puts "Workin' #{how_hard}"
end
end
sleep for 10 seconds and print out "Working super hard" .

Related

Why does sleep in a thread have no puts output?

I'm using Ruby 2.0, Cygwin, and Windows 8. The following program produces no output; it will loop forever and not puts the time.
hi = Thread.new do
while true do
puts Time.now # or call tick function
sleep 1
end
end
hi.join
Am I missing something?
I want the functionality to be:
Do something
Wait for 3-10 seconds
Do it again etc.
Seems like your output is buffered ($stdout.sync defaults to false). To flush all output immediately, start your script with:
$stdout.sync = true

Changing variable into string

Please see the following code (taken from Learning Ruby book):
def timer(start)
puts "Minutes: " + start.to_s
start_time = Time.now
puts start_time.strftime("Start time: %I:%M:%S: %p")
start.downto(1) { |i| sleep 60 }
end_time = Time.now
print end_time.strftime("Elapsed time: %I:%M:%S: %p\n")
end
timer 10
Why would there be a need to change the start variable into a string on the puts line? Couldn't I, for example, simply put in puts "Minutes: #{start}"?
Also, the start.downto(1) line: Is the block {|i| sleep 60} specifying how many seconds a minute should be?
Yes, you can also say:
puts "Mintues: #{start}"
It's one of many nice Ruby choices. :) In this case, it doesn't make much difference.
Regarding the loop:
start.downto(1) { |i| sleep 60 }
Yes, this is counting minutes down to 1 and each time is sleeping 60 seconds. So it will sleep for start minutes. If start isn't too large, you could just use sleep 60*start.

ping function every x amount seconds

How would I do a specific task every x amount of seconds in ruby? I've tried using Time.now.to_i for epoch then once a Time.now_i hits that task second it executes, but I have not successfuly done this, can someone show me a small example on how to execute a function every x amount of seconds?
Attempt:
def interval(timeout,function,*data)
now = Time.now.to_i
tasktime = Time.now.to_i + timeout
taskfunction = function
taskdata = data
end
I stopped the code there because I do not know how/what to do next in ruby, so what it should do for example if someone can generate a code that can do something like this example,
def say(word)
puts word
end
If you set a interval for the function would be say, the data would be the "word" then it would execute that function every x amount of seconds
If you simply sleep for a constant amount of time as suggested in other answers, the error will contaminate as it keeps running, and will not be accurate. In fact, each iteration would take longer than the given interval.
The answer shown below adjusts the lag each time per iteration.
module Kernel
def tick_every sec, &pr
Thread.new do loop do
pr.call
t = Time.now.to_f
frac = t.modulo(sec.to_f)
sleep(sec - frac)
end end
end
end
thread = tick_every(2) do
puts "foo"
end
...
some_other_tasks
...
thread.kill
You can use Kernel#sleep method for the same.
Here is the post
Ruby sleep or delay less than a second?
Tell Ruby Program to Wait some amount of time
This method would puts the word every 2 seconds endless, synchronously (means other ruby code has to wait until this execution is finished (..endless..:)).
def say(word)
while true do
t = Time.now.to_f
puts word
frac = t.modulo(2.to_f)
sleep(2 - frac)
end
end

how to invoke a method for every second in ruby

I wanted to create a stopwatch program in ruby so I googled it and found this SO Q.
But over there, the author calls the tick function with 1000xxx.times. I wanted to know how I can do it using something like (every second).times or for each increment of second do call the tick function.
This function:
def every_so_many_seconds(seconds)
last_tick = Time.now
loop do
sleep 0.1
if Time.now - last_tick >= seconds
last_tick += seconds
yield
end
end
end
When used like this:
every_so_many_seconds(1) do
p Time.now
end
Results in this:
# => 2012-09-20 16:43:35 -0700
# => 2012-09-20 16:43:36 -0700
# => 2012-09-20 16:43:37 -0700
The trick is to sleep for less than a second. That helps to keep you from losing ticks. Note that you cannot guarantee you'll never lose a tick. That's because the operating system cannot guarantee that your unprivileged program gets processor time when it wants it.
Therefore, make sure your clock code does not depend on the block getting called every second. For example, this would be bad:
every_so_many_seconds(1) do
#time += 1
display_time(#time)
end
This would be fine:
every_so_many_seconds(1) do
display_time(Time.now)
end
Thread.new do
while true do
puts Time.now # or call tick function
sleep 1
end
end

Is there a way to write a Ruby loop that runs one iteration for a maximum set amount of time?

I'm looking to create a Ruby (MRI 1.9.3) loop that runs at most for a certain amount of time, and once that time is up it goes to the next iteration of the loop.
For example, this is what I'm hoping to achieve:
timer = Timer.new
while foo
timer.after 5 do # The loop on foo only gets to run for 5 seconds
next
end
# Do some work here
end
So far, I've found tarcieri's gem called Timers (https://github.com/tarcieri/timers) which is what I'm trying to emulate in the code above, but my implementation doesn't give the behavior I expect, which is for the loop to go to the next iteration after 5 seconds if my work takes longer than that. Any ideas?
require 'timeout'
timeout_in_seconds = 5
while foo
begin
Timeout.timeout(timeout_in_seconds) do
# Do some work here
end
rescue Timeout::Error
next
end
end
It's been awhile since I brushed off my Ruby skills, but I believe you can do this with the timeout library.
require 'timeout'
while foo
Timeout.timeout(5) do
work()
end
end
You can also try this:
time = 60
time_start = Time.now
begin
time_running = Time.now - time_start
#You_code_goes_here
end until (time_running.to_i >= time)
That loop will happen until the time_running var is equal or greater than "60".

Resources