[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Runnin code at a certain time?

Tom Ricks

5/25/2009 4:42:00 PM

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-....

19 Answers

Caleb Clausen

5/25/2009 8:37:00 PM

0

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?

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.)

MenTaLguY

5/25/2009 8:48:00 PM

0

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?

You might want to try my Scheduler gem.

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

-mental


Tom Ricks

5/25/2009 10:41:00 PM

0

Caleb Clausen wrote:
> 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?
>>
> 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.
--
Posted via http://www.ruby-....

Caleb Clausen

5/26/2009 1:55:00 AM

0

On 5/25/09, Tom Ricks <carrottop123@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.

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.

Anonymous

5/27/2009 4:41:00 PM

0

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.

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,
--
Charles DeRykus


Caleb Clausen

5/28/2009 12:08:00 AM

0

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/...

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?

Reid Thompson

5/28/2009 1:22:00 AM

0

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/...
>
> 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...

Reid Thompson

5/28/2009 1:23:00 AM

0

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/...
>
> 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/...

Jarmo Pertman

5/28/2009 6:13:00 AM

0

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

Jarmo

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

Charles Oliver Nutter

5/28/2009 5:22:00 PM

0

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