Runnin code at a certain time?

Hello all,
   I am new to ruby and I am attempting to run some code at a certain
time. The Ruby Time class is very interesting, you can add time, and do
all of these amazing things but i cannot find a way to run code at a
certain time. I feel like I'm missing something. So far all I have is:

sleep(1) while Time.now < ("Time")

How would I link some code to be run to this? Or is there an easier way?

···

--
Posted via http://www.ruby-forum.com/.

The proper answer depends on the context where this code will be used.
Do you want your whole program to stop until some target time? In that
case, something as simple as

  sleep(target_time-Time.now)
  code_to_be_delayed

will do the trick nicely. But if this code runs within the context of
some larger system, which cannot afford to have the whole program be
unable to respond to events for many seconds in a row (rails, for
example), then sleep is a bad idea. In some cases, you might be able
to put your sleep and code_to_be_delayed in another thread, but then
you run into the problem of thread synchronization. If neither of my
simple suggestions does the trick, you should post more details abut
your application. (Maybe then someone will have enough information to
make a specific suggestion... I doubt I will.)

···

On 5/25/09, Tom Ricks <carrottop123@gmail.com> wrote:

Hello all,
   I am new to ruby and I am attempting to run some code at a certain
time. The Ruby Time class is very interesting, you can add time, and do
all of these amazing things but i cannot find a way to run code at a
certain time. I feel like I'm missing something. So far all I have is:

sleep(1) while Time.now < ("Time")

How would I link some code to be run to this? Or is there an easier way?

You might want to try my Scheduler gem.

Scheduler.at_time(time_in_seconds_from_epoch) do
   # ... stuff to do ...
end

-mental

···

On Tue, 2009-05-26 at 05:36 +0900, Caleb Clausen wrote:

> I am new to ruby and I am attempting to run some code at a certain
> time. The Ruby Time class is very interesting, you can add time, and do
> all of these amazing things but i cannot find a way to run code at a
> certain time. I feel like I'm missing something. So far all I have is:
>
> sleep(1) while Time.now < ("Time")
>
> How would I link some code to be run to this? Or is there an easier way?

Caleb Clausen wrote:

Hello all,
   I am new to ruby and I am attempting to run some code at a certain
time. The Ruby Time class is very interesting, you can add time, and do
all of these amazing things but i cannot find a way to run code at a
certain time. I feel like I'm missing something. So far all I have is:

sleep(1) while Time.now < ("Time")

How would I link some code to be run to this? Or is there an easier way?

The proper answer depends on the context where this code will be used.
Do you want your whole program to stop until some target time?
But if this code runs within the context of
some larger system, which cannot afford to have the whole program be
unable to respond to events for many seconds in a row (rails, for
example), then sleep is a bad idea.

Well, I'm not really sure. The intent is to have a repetitive code ran
at quite a few different times with changing variables. The sleep option
doesn't really seem reliable and realistic, although its the only thing
so far. The code I can come up with is this:

class TestClass
  def testtime(timetorun)
    timetorun = @timetorun
    sleep(1) while Time.now.strftime("%I:%M:%S %p") < ("#{@timetorun}")
    #Somewhere code to run when Time.now = timetorun
  end
end
test = TestClass.new
test.testtime("11:04:40 AM")

The problems are #1. I don't know how to link the time code to the code
to be run when the time code is fulfilled. #2. If I have a list of times
to be run, and one time is out of order, it will just sleep past the out
of order time. #3. While the code is waiting for a certain time, with
sleep, it cannot do anything else. Is there a way that I can run code
that will watch for a time to be fulfilled on many levels instead of
just waiting until a time, moving on and waiting for the next? Is it
possible to do something like this:

when test.testtime is true/finished?
run some code
end

In some cases, you might be able
to put your sleep and code_to_be_delayed in another thread, but then
you run into the problem of thread synchronization.

How would I do this?

Your example of

sleep(target_time-Time.now)
code_to_be_delayed

seems to work better, although it still shuts the whole code down for a
while.

···

On 5/25/09, Tom Ricks <carrottop123@gmail.com> wrote:

--
Posted via http://www.ruby-forum.com/\.

Note that #sleep won't necessarily sleep as long as you like (second sentence):

$ ri Kernel#sleep
----------------------------------------------------------- Kernel#sleep
      sleep([duration]) => fixnum

      From Ruby 1.8

···

On May 25, 2009, at 13:36, Caleb Clausen wrote:

On 5/25/09, Tom Ricks <carrottop123@gmail.com> wrote:

I am new to ruby and I am attempting to run some code at a certain
time. The Ruby Time class is very interesting, you can add time, and do
all of these amazing things but i cannot find a way to run code at a
certain time. I feel like I'm missing something. So far all I have is:

sleep(1) while Time.now < ("Time")

How would I link some code to be run to this? Or is there an easier way?

The proper answer depends on the context where this code will be used.
Do you want your whole program to stop until some target time? In that
case, something as simple as

sleep(target_time-Time.now)
code_to_be_delayed

will do the trick nicely.

------------------------------------------------------------------------
      Suspends the current thread for duration seconds (which may be any
      number, including a Float with fractional seconds). Returns the
      actual number of seconds slept (rounded), which may be less than
      that asked for if another thread calls Thread#run. Zero arguments
      causes sleep to sleep forever.
[...]

Well, I'm not really sure. The intent is to have a repetitive code ran
at quite a few different times with changing variables. The sleep option
doesn't really seem reliable and realistic, although its the only thing
so far. The code I can come up with is this:

class TestClass
  def testtime(timetorun)
    timetorun = @timetorun
    sleep(1) while Time.now.strftime("%I:%M:%S %p") < ("#{@timetorun}")
    #Somewhere code to run when Time.now = timetorun
  end
end
test = TestClass.new
test.testtime("11:04:40 AM")

The problems are #1. I don't know how to link the time code to the code
to be run when the time code is fulfilled.

I think procs are the feature you want to know about here.

#2. If I have a list of times
to be run, and one time is out of order, it will just sleep past the out
of order time.

so, sort 'em.

#3. While the code is waiting for a certain time, with
sleep, it cannot do anything else.

Select, or threads, or some kind of event driven system like
EventMachine are the usual solutions to this problem. I forgot to
mention select before.

Is there a way that I can run code
that will watch for a time to be fulfilled on many levels instead of
just waiting until a time, moving on and waiting for the next? Is it
possible to do something like this:

when test.testtime is true/finished?
run some code
end

Well, in general what you want here is a timer. It's very easy to
write your own; it sounds like you're close now, you just need to
learn about sort.

In some cases, you might be able
to put your sleep and code_to_be_delayed in another thread, but then
you run into the problem of thread synchronization.

How would I do this?

Hmm, you have some learning to do. Including how to find information
about the standard library. I suggest you make friends with ri, which
is the command-line tool that displays stdlib documentation. Google
can also be very helpful. You also need some general background on
ruby and programming concepts; I'd suggest the book 'programming
ruby'. There's a free version of an old edition online.

···

On 5/25/09, Tom Ricks <carrottop123@gmail.com> wrote:

I'm totally new to Ruby so I'm sorry for the piggyback question but,
in Perl you could
set an alarm clock that'd leave the program unfettered:

  { local $SIG{ALRM} = sub { die "timeout" };
    alarm( "target_time" - "Time.now" );
     # do other things
    alarm( 0 );
  };
  if ( $@ =~ /^timeout/ ) {# time's up... }
  elsif ( $@ ) {# other error... }

How would Ruby do this?

Thanks,

···

On May 25, 3:40 pm, Tom Ricks <carrottop...@gmail.com> wrote:

Caleb Clausen wrote:
> On 5/25/09, Tom Ricks <carrottop...@gmail.com> wrote:
...

Well, I'm not really sure. The intent is to have a repetitive code ran
at quite a few different times with changing variables. The sleep option
doesn't really seem reliable and realistic, although its the only thing
so far. The code I can come up with is this:

class TestClass
def testtime(timetorun)
timetorun = @timetorun
sleep(1) while Time.now.strftime("%I:%M:%S %p") < ("#{@timetorun}")
#Somewhere code to run when Time.now = timetorun
end
end
test = TestClass.new
test.testtime("11:04:40 AM")

The problems are #1. I don't know how to link the time code to the code
to be run when the time code is fulfilled. #2. If I have a list of times
to be run, and one time is out of order, it will just sleep past the out
of order time. #3. While the code is waiting for a certain time, with
sleep, it cannot do anything else. Is there a way that I can run code
that will watch for a time to be fulfilled on many levels instead of
just waiting until a time, moving on and waiting for the next? Is it
possible to do something like this:

when test.testtime is true/finished?
run some code
end

> In some cases, you might be able
> to put your sleep and code_to_be_delayed in another thread, but then
> you run into the problem of thread synchronization.

How would I do this?

Your example of

sleep(target_time-Time.now)
code_to_be_delayed

seems to work better, although it still shuts the whole code down for a
while.

--
Charles DeRykus

Is there some particular danger that Thread#run will be called on my
threads without my asking?

···

On 5/28/09, Eric Hodel <drbrain@segment7.net> wrote:

On May 25, 2009, at 13:36, Caleb Clausen wrote:

Do you want your whole program to stop until some target time? In that
case, something as simple as

sleep(target_time-Time.now)
code_to_be_delayed

will do the trick nicely.

Note that #sleep won't necessarily sleep as long as you like (second
sentence):

$ ri Kernel#sleep
----------------------------------------------------------- Kernel#sleep
      sleep([duration]) => fixnum

      From Ruby 1.8
------------------------------------------------------------------------
      Suspends the current thread for duration seconds (which may be any
      number, including a Float with fractional seconds). Returns the
      actual number of seconds slept (rounded), which may be less than
      that asked for if another thread calls Thread#run. Zero arguments
      causes sleep to sleep forever.
[...]

I went and looked again, and there is a Timeout module in ruby's
stdlib, which I had forgotten about:
http://www.ruby-doc.org/stdlib/libdoc/timeout/rdoc/index.html

So the equivalent of the perl code you posted should be:

#UNTESTED!!!
require 'timeout'
begin
  Timeout.timeout(target_time-Time.now){
    #do other things
  }
rescue Timeout::Error
  #time's up
rescue Exception
  #other error
end

Timeout uses Thread#raise, which I think is not reliable on JRuby or
other implementations that use native threads.

PS: does anyone know why Timeout::Error < Interrupt ? Interrupt is for
^C... why would you want timeouts to be handled like ^C?

···

On 5/27/09, Anonymous <derykus@gmail.com> wrote:

I'm totally new to Ruby so I'm sorry for the piggyback question but,
in Perl you could
set an alarm clock that'd leave the program unfettered:

  { local $SIG{ALRM} = sub { die "timeout" };
    alarm( "target_time" - "Time.now" );
     # do other things
    alarm( 0 );
  };
  if ( $@ =~ /^timeout/ ) {# time's up... }
  elsif ( $@ ) {# other error... }

How would Ruby do this?

If it's library code, yes. If it's application code, probably not.

···

On May 29, 2009, at 12:49, Caleb Clausen wrote:

On 5/28/09, Eric Hodel <drbrain@segment7.net> wrote:

On May 25, 2009, at 13:36, Caleb Clausen wrote:

Do you want your whole program to stop until some target time? In that
case, something as simple as

sleep(target_time-Time.now)
code_to_be_delayed

will do the trick nicely.

Note that #sleep won't necessarily sleep as long as you like (second
sentence):

$ ri Kernel#sleep
----------------------------------------------------------- Kernel#sleep
     sleep([duration]) => fixnum

     From Ruby 1.8
------------------------------------------------------------------------
     Suspends the current thread for duration seconds (which may be any
     number, including a Float with fractional seconds). Returns the
     actual number of seconds slept (rounded), which may be less than
     that asked for if another thread calls Thread#run. Zero arguments
     causes sleep to sleep forever.
[...]

Is there some particular danger that Thread#run will be called on my
threads without my asking?

Caleb Clausen wrote:

···

On 5/27/09, Anonymous <derykus@gmail.com> wrote:

I'm totally new to Ruby so I'm sorry for the piggyback question but,
in Perl you could
set an alarm clock that'd leave the program unfettered:

  { local $SIG{ALRM} = sub { die "timeout" };
    alarm( "target_time" - "Time.now" );
     # do other things
    alarm( 0 );
  };
  if ( $@ =~ /^timeout/ ) {# time's up... }
  elsif ( $@ ) {# other error... }

How would Ruby do this?

I went and looked again, and there is a Timeout module in ruby's
stdlib, which I had forgotten about:
http://www.ruby-doc.org/stdlib/libdoc/timeout/rdoc/index.html

So the equivalent of the perl code you posted should be:

#UNTESTED!!!
require 'timeout'
begin
  Timeout.timeout(target_time-Time.now){
    #do other things
  }
rescue Timeout::Error
  #time's up
rescue Exception
  #other error
end

Timeout uses Thread#raise, which I think is not reliable on JRuby or
other implementations that use native threads.

PS: does anyone know why Timeout::Error < Interrupt ? Interrupt is for
^C... why would you want timeouts to be handled like ^C?

may be of interest
http://rubyforge.org/projects/rubycron/

Caleb Clausen wrote:

···

On 5/27/09, Anonymous <derykus@gmail.com> wrote:

I'm totally new to Ruby so I'm sorry for the piggyback question but,
in Perl you could
set an alarm clock that'd leave the program unfettered:

  { local $SIG{ALRM} = sub { die "timeout" };
    alarm( "target_time" - "Time.now" );
     # do other things
    alarm( 0 );
  };
  if ( $@ =~ /^timeout/ ) {# time's up... }
  elsif ( $@ ) {# other error... }

How would Ruby do this?

I went and looked again, and there is a Timeout module in ruby's
stdlib, which I had forgotten about:
http://www.ruby-doc.org/stdlib/libdoc/timeout/rdoc/index.html

So the equivalent of the perl code you posted should be:

#UNTESTED!!!
require 'timeout'
begin
  Timeout.timeout(target_time-Time.now){
    #do other things
  }
rescue Timeout::Error
  #time's up
rescue Exception
  #other error
end

Timeout uses Thread#raise, which I think is not reliable on JRuby or
other implementations that use native threads.

PS: does anyone know why Timeout::Error < Interrupt ? Interrupt is for
^C... why would you want timeouts to be handled like ^C?

also
http://www.notwork.org/~gotoken/ruby/p/crontab/crontab/crontab.rb

Caleb Clausen wrote:

Timeout uses Thread#raise, which I think is not reliable on JRuby or
other implementations that use native threads.

It should be reliable, and in fact we reimplemented Timeout in Java to reduce the cost almost down to zero. I don't like that things like raise and kill and Timeout are used, but we've made sure they work well when they are.

PS: does anyone know why Timeout::Error < Interrupt ? Interrupt is for
^C... why would you want timeouts to be handled like ^C?

I do not.

- Charlie

Can you be more specific? I'm curious as to how exactly this could
happen. I suspect you speak from experience, but I can't see how if an
application fiddles with a libraries internals in this way, that's not
considered a bug in the application.

···

On 5/30/09, Eric Hodel <drbrain@segment7.net> wrote:

Is there some particular danger that Thread#run will be called on my
threads without my asking?

If it's library code, yes. If it's application code, probably not.

I've used rufus-scheduler gem to achieve this functionality:
http://rufus.rubyforge.org/rufus-scheduler/

Jarmo

···

--
Posted via http://www.ruby-forum.com/.

I thought you'd made some long blog post proving how it's impossible
to Thread#raise perfectly reliably in JRuby. I may be confused. I'm
glad to hear that it does work and I apologize for spreading
misinformation.

···

On 5/28/09, Charles Oliver Nutter <charles.nutter@sun.com> wrote:

Caleb Clausen wrote:

Timeout uses Thread#raise, which I think is not reliable on JRuby or
other implementations that use native threads.

It should be reliable, and in fact we reimplemented Timeout in Java to
reduce the cost almost down to zero. I don't like that things like raise
and kill and Timeout are used, but we've made sure they work well when
they are.

Since threads are involved, it doesn't need to muck with any internals, it just has to wake up the thread your sleep was running in:

class YourLib
   def your_sleep
     sleep 1_000_000
   end
end

class MyApp
   # ...
   def do_stuff
     @threads << Thread.start do
       # ...
       YourLib.new.your_sleep
       # ...
     end
   end

   def wakeup
     @threads.each do |thread|
       thread.run
     end
   end
end

···

On May 30, 2009, at 12:46, Caleb Clausen wrote:

On 5/30/09, Eric Hodel <drbrain@segment7.net> wrote:

Is there some particular danger that Thread#run will be called on my
threads without my asking?

If it's library code, yes. If it's application code, probably not.

Can you be more specific? I'm curious as to how exactly this could
happen. I suspect you speak from experience, but I can't see how if an
application fiddles with a libraries internals in this way, that's not
considered a bug in the application.

Jarmo Pertman wrote:

I've used rufus-scheduler gem to achieve this functionality:
http://rufus.rubyforge.org/rufus-scheduler/

Jarmo

Thank you for this awesome gem, it looks to be almost exactly what i
need!

···

--
Posted via http://www.ruby-forum.com/\.

Is there some particular danger that Thread#run will be called on my
threads without my asking?

If it's library code, yes. If it's application code, probably not.

Can you be more specific? I'm curious as to how exactly this could
happen. I suspect you speak from experience, but I can't see how if an
application fiddles with a libraries internals in this way, that's not
considered a bug in the application.

Since threads are involved, it doesn't need to muck with any
internals, it just has to wake up the thread your sleep was running in:

The only purpose of run is to break a call to sleep (or select, or
join. Anything else?) If code external to my library decides to call
run on me, it ought to know what it's doing. If something bad happens,
it seems to me that that's a bug in the external code.

class YourLib
   def your_sleep
     sleep 1_000_000
   end
end

class MyApp
   # ...
   def do_stuff
     @threads << Thread.start do
       # ...
       YourLib.new.your_sleep
       # ...
     end
   end

   def wakeup
     @threads.each do |thread|
       thread.run
     end
   end
end

What application actually does this?

···

On 5/30/09, Eric Hodel <drbrain@segment7.net> wrote:

On May 30, 2009, at 12:46, Caleb Clausen wrote:

On 5/30/09, Eric Hodel <drbrain@segment7.net> wrote:

In general if you're writing a library that makes use of threads it's your responsibility to make them behave correctly when 'interrupted' by application code. Otherwise you have a fragile library that will greatly complicate debugging for its users.

Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net

···

On 31 May 2009, at 13:00, Caleb Clausen wrote:

On 5/30/09, Eric Hodel <drbrain@segment7.net> wrote:

On May 30, 2009, at 12:46, Caleb Clausen wrote:

On 5/30/09, Eric Hodel <drbrain@segment7.net> wrote:

Is there some particular danger that Thread#run will be called on my
threads without my asking?

If it's library code, yes. If it's application code, probably not.

Can you be more specific? I'm curious as to how exactly this could
happen. I suspect you speak from experience, but I can't see how if an
application fiddles with a libraries internals in this way, that's not
considered a bug in the application.

Since threads are involved, it doesn't need to muck with any
internals, it just has to wake up the thread your sleep was running in:

The only purpose of run is to break a call to sleep (or select, or
join. Anything else?) If code external to my library decides to call
run on me, it ought to know what it's doing. If something bad happens,
it seems to me that that's a bug in the external code.

----
raise ArgumentError unless @reality.responds_to? :reason