[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Cute little simple scheduling code hack

KCons

2/23/2007 6:31:00 AM

I'm sure there is some far superior prior art out there somewhere, but
this is a useful little hack I threw together today that I thought
someone else might find interesting.

I wanted to do a little task every few seconds for some duration of
time, and after a bit of overkill I came up with a little library that
lets me do stuff like:

every( 5.seconds ).for( 2.days ) { puts "Chunky bacon, k?" }

or

every( 2.minutes ).until ( Time.now + 4.hours ) { dance_for_a_while }

or even

class String
def gradual_out( n = 1 )
ix = 0
every( n.seconds ).unless(lambda {ix >= size}) do
print self[ix].chr
ix += 1
end
end
end

"Tuesday is the new Thursday".gradual_out( 400.milliseconds )


Fun to play with.
Again, just a quick hack, so if you see any glaring issues or useful
improvements, let me know, because I'm sure I'll find use for it again
later.

--Code below--

class Scheduler
def initialize( int )
@interval = int
end

def for( secs )
self.until( Time.now + secs ) { |x| yield x }
end

def until( endtime )
self.unless( lambda { Time.now >= endtime } ) { |x| yield x }
end

def unless( cond )
while !cond.call do
current = Time.now
yield current
wait_time = (current + @interval) - Time.now
begin
sleep( wait_time ) unless wait_time <= 0 or cond.call
rescue Interrupt
break
end
end
end
end

module Kernel
def every( int )
Scheduler.new( int )
end
end

class Numeric
def seconds; self; end
def minutes; self * 60; end
def hours; self.minutes * 60; end
def milliseconds; self / 1000.0; end
def days; self.hours * 24; end
end

6 Answers

John Mettraux

2/23/2007 7:10:00 AM

0

2007/2/23, KCons <consalus@gmail.com>:
> I'm sure there is some far superior prior art out there somewhere, but
> this is a useful little hack I threw together today that I thought
> someone else might find interesting.
>
> I wanted to do a little task every few seconds for some duration of
> time, and after a bit of overkill I came up with a little library that
> lets me do stuff like:
>
> every( 5.seconds ).for( 2.days ) { puts "Chunky bacon, k?" }
>
> or
>
> every( 2.minutes ).until ( Time.now + 4.hours ) { dance_for_a_while }
>
> or even
>
> class String
> def gradual_out( n = 1 )
> ix = 0
> every( n.seconds ).unless(lambda {ix >= size}) do
> print self[ix].chr
> ix += 1
> end
> end
> end
>
> "Tuesday is the new Thursday".gradual_out( 400.milliseconds )

Hi,

I had come up with that :

http://openwferu.rubyforge.org/sche...

advantage : one thread for all the tasks
disadvantage : has to wake up to pool its jobqueue


But your approach is definitely more cute and more 'rubystic'.

Quick question : is the "rescue Interrupt" really needed ? Does it
avoid some "under the carpet thread problems" ?


Best regards,

--
John Mettraux -///- http://jmettraux.o...

KCons

2/23/2007 7:33:00 AM

0


>
> I had come up with that :
>
> http://openwferu.rubyforge.org/sche...
>

Neat, that'll certainly come in handy when I'm doing more complicated
scheduling.
Clean interface, too.


> Quick question : is the "rescue Interrupt" really needed ? Does it
> avoid some "under the carpet thread problems" ?
Y'know, I imagine the 'rescue Interrupt' business is not actually
needed. It is just there because I got seeing exception dumps when I
Ctrl-C'd out of the sleep. :)

Michael Brooks

2/23/2007 7:50:00 AM

0

KCons wrote:
> I'm sure there is some far superior prior art out there somewhere, but
> this is a useful little hack I threw together today that I thought
> someone else might find interesting.
>
> I wanted to do a little task every few seconds for some duration of
> time, and after a bit of overkill I came up with a little library that
> lets me do stuff like:
>
> every( 5.seconds ).for( 2.days ) { puts "Chunky bacon, k?" }
>
> or
>
> every( 2.minutes ).until ( Time.now + 4.hours ) { dance_for_a_while }
>
> or even
>
> class String
> def gradual_out( n = 1 )
> ix = 0
> every( n.seconds ).unless(lambda {ix >= size}) do
> print self[ix].chr
> ix += 1
> end
> end
> end
>
> "Tuesday is the new Thursday".gradual_out( 400.milliseconds )
>
>
> Fun to play with.
> Again, just a quick hack, so if you see any glaring issues or useful
> improvements, let me know, because I'm sure I'll find use for it again
> later.
>
<snip>

Hello KCons:

Wow... I'm just (8 hours into both) learning Python and Ruby and I
didn't realize how powerful / extensible Ruby was until I saw your
example. Great stuff!

Thanks,

Michael

Ara.T.Howard

2/23/2007 3:43:00 PM

0

John Mettraux

2/23/2007 10:53:00 PM

0

2007/2/24, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov>:
> On Fri, 23 Feb 2007, John Mettraux wrote:
>
> > http://openwferu.rubyforge.org/sche...
>
> looks very interesting!
>
> > advantage : one thread for all the tasks disadvantage : has to wake up to
> > pool its jobqueue
>
> hmmm. is that even possible?
>
>
> harp :~/openwferu/trunk/openwfe-ruby > cat a.rb
> require "time"
> require "openwfe/util/otime"
> require "openwfe/util/scheduler"
> include OpenWFE
>
> scheduler = Scheduler.new
>
> i = -1
>
> scheduler.schedule('*/1 * * * *') do
> 4.times{ puts Time.now.iso8601(2); sleep 30 } ### this takes 120s!
> puts(i += 1)
> end
>
> scheduler.sstart
>
> STDIN.gets
>
>
>
> harp :~/openwferu/trunk/openwfe-ruby > RUBYLIB=lib ruby a.rb
> 2007-02-23T08:29:00.22-07:00
> 2007-02-23T08:29:30.22-07:00
> 2007-02-23T08:30:00.22-07:00
> 2007-02-23T08:30:30.22-07:00
> 0
> ...
>
> it seems like a single threaded/processed scheduler is an imposibility?

Hey, thanks for the light, I'll fix that / make it better.

I'll have to correct from "one thread for all tasks" to something like
"one thread as an alarm clock for all tasks".


> nevertheless i've already found a use for this code in a situation where i
> don't care if events are fired precisely (as is possible) as i declare them or
> not.

Glad to read that.


Cheers,

--
John Mettraux -///- http://jmettraux.o...

Pete Yandell

2/26/2007 7:59:00 AM

0


On 23/02/2007, at 5:35 PM, KCons wrote:

> I'm sure there is some far superior prior art out there somewhere, but
> this is a useful little hack I threw together today that I thought
> someone else might find interesting.

It is interesting! You need to blog about it somewhere so I can
bookmark it for later. :)

Pete Yandell
http://no...