# Cute little simple scheduling code hack

**URL:** <https://www.ruby-forum.com/t/cute-little-simple-scheduling-code-hack/86557>\
**Category:** Ruby\
**Created:** [February 23, 2007, 7:36am UTC](https://www.ruby-forum.com/t/cute-little-simple-scheduling-code-hack/86557 "2007-02-23T07:36:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![KCons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@KCons](https://www.ruby-forum.com/u/KCons)\
**Post date:** [February 23, 2007, 7:36am UTC](https://www.ruby-forum.com/t/cute-little-simple-scheduling-code-hack/86557/1 "2007-02-23T07:36:40Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![KCons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@KCons](https://www.ruby-forum.com/u/KCons)\
**Post date:** [February 23, 2007, 8:10am UTC](https://www.ruby-forum.com/t/cute-little-simple-scheduling-code-hack/86557/2 "2007-02-23T08:10:42Z")

</div>

2007/2/23, KCons [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> or  
> 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/scheduler.html](http://openwferu.rubyforge.org/scheduler.html)

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,

---

<div class="post-metadata">

**Author:** ![KCons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@KCons](https://www.ruby-forum.com/u/KCons)\
**Post date:** [February 23, 2007, 8:35am UTC](https://www.ruby-forum.com/t/cute-little-simple-scheduling-code-hack/86557/3 "2007-02-23T08:35:44Z")

</div>

> I had come up with that :
> 
> [http://openwferu.rubyforge.org/scheduler.html](http://openwferu.rubyforge.org/scheduler.html)

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

---

<div class="post-metadata">

**Author:** ![KCons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@KCons](https://www.ruby-forum.com/u/KCons)\
**Post date:** [February 23, 2007, 4:43pm UTC](https://www.ruby-forum.com/t/cute-little-simple-scheduling-code-hack/86557/4 "2007-02-23T16:43:06Z")

</div>

On Fri, 23 Feb 2007, John M. wrote:

> Hi,
> 
> I had come up with that :
> 
> [http://openwferu.rubyforge.org/scheduler.html](http://openwferu.rubyforge.org/scheduler.html)

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
 2007-02-23T08:31:00.47-07:00
 2007-02-23T08:31:30.47-07:00
 2007-02-23T08:32:00.47-07:00
 2007-02-23T08:32:30.47-07:00
 1
 2007-02-23T08:33:00.73-07:00
 2007-02-23T08:33:30.73-07:00
 2007-02-23T08:34:00.73-07:00
 2007-02-23T08:34:30.73-07:00
 2
 2007-02-23T08:35:00.98-07:00
 2007-02-23T08:35:30.98-07:00
 2007-02-23T08:36:00.98-07:00
 2007-02-23T08:36:30.98-07:00
 3
 2007-02-23T08:38:00.23-07:00
 2007-02-23T08:38:30.23-07:00
 ...
 ...
 ...

```

it seems like a single threaded/processed scheduler is an imposibility?

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.

cheers.

-a

---

<div class="post-metadata">

**Author:** ![KCons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@KCons](https://www.ruby-forum.com/u/KCons)\
**Post date:** [February 23, 2007, 11:53pm UTC](https://www.ruby-forum.com/t/cute-little-simple-scheduling-code-hack/86557/5 "2007-02-23T23:53:17Z")

</div>

2007/2/24, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ```
> 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,

---

<div class="post-metadata">

**Author:** ![KCons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@KCons](https://www.ruby-forum.com/u/KCons)\
**Post date:** [February 26, 2007, 8:59am UTC](https://www.ruby-forum.com/t/cute-little-simple-scheduling-code-hack/86557/6 "2007-02-26T08:59:59Z")

</div>

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

> **[Pete Yandell — Principal Engineer / Architect](https://notahat.com/)**
>
> Pete Yandell is an experienced Principal Software Engineer and Architect based in Melbourne, Australia.

---

<div class="post-metadata">

**Author:** ![KCons](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/ed8c4c/32.png) [@KCons](https://www.ruby-forum.com/u/KCons)\
**Post date:** [February 23, 2007, 8:55am UTC](https://www.ruby-forum.com/t/cute-little-simple-scheduling-code-hack/86557/7 "2007-02-23T08:55:46Z")

</div>

KCons wrote:

> or  
> ix += 1  
> later.

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
