Timers, scheduling and Ruby

Ok, since the original post migh just appear in a month’s time, lets
rephrase the question:

I’m building a set of tools for build and test management (yes, yes, it
will do DamagaControl’s work and yes, yes it will be released…and yes,
this is code that is used in real-life projects - it’s all so close to
public alpha status).
Now, I can leave scheduling to cron (or at/schtasks), but it would be
nice to provide an interface so that scheduling can be set in the
application via some administration console.
Behind the scenes cron manipulation is too flaky for my tastes (and for
windows I would need a separate implementation).
So, is there a library that will give me timers, a nice way to configure
them and a nice event driven interface? :slight_smile:
Cheers,
V.-

Damphyr wrote:

Ok, since the original post migh just appear in a month’s time, lets
rephrase the question:
You’ve discovered a chronosynclastic infundibulum, apparently. :slight_smile:
So, is there a library that will give me timers, a nice way to
configure them and a nice event driven interface? :slight_smile:
Cheers,
V.-
Event Machine?


M. Edward (Ed) Borasky, FBG, AB, PTA, PGS, MS, MNLP, NST, ACMC§
http://borasky-research.blogspot.com/

If God had meant for carrots to be eaten cooked, He would have given
rabbits fire.

On Nov 30, 2006, at 7:51 AM, Damphyr wrote:

Behind the scenes cron manipulation is too flaky for my tastes (and
for windows I would need a separate implementation).
So, is there a library that will give me timers, a nice way to
configure them and a nice event driven interface? :slight_smile:

I’ve wanted this myself. I wonder if we could get it down to Ruby
Quiz size…

James Edward G. II

M. Edward (Ed) Borasky wrote:

So, is there a library that will give me timers, a nice way to
configure them and a nice event driven interface? :slight_smile:
Cheers,
V.-
Event Machine?
I’m not sure about this. EventMachine seems geared towards networking.
I just want a class that will tick away on it’s own thread and fire
events at designated time points.
My requirements include firing at intervals (every thirty minutes, every
two days), once (in thirty minutes, on 1/1/2007 at 0:00 etc.) and I
would like to have named events if possible.
Getting the events should be as simple as observing the timer.
So will anybody save me the work or do I have to code the beast?
Cheers,
V.-

On Fri, 1 Dec 2006, James Edward G. II wrote:

On Nov 30, 2006, at 7:51 AM, Damphyr wrote:

Behind the scenes cron manipulation is too flaky for my tastes (and for
windows I would need a separate implementation).
So, is there a library that will give me timers, a nice way to configure
them and a nice event driven interface? :slight_smile:

I’ve wanted this myself. I wonder if we could get it down to Ruby Q.
size…

i’m working on a library for this now. any request?

-a

On 11/30/06, Damphyr [email protected] wrote:

I’m not sure about this. EventMachine seems geared towards networking.
I just want a class that will tick away on it’s own thread and fire
events at designated time points.
My requirements include firing at intervals (every thirty minutes, every
two days), once (in thirty minutes, on 1/1/2007 at 0:00 etc.) and I
would like to have named events if possible.
Getting the events should be as simple as observing the timer.
So will anybody save me the work or do I have to code the beast?
Cheers,
V.-

I have nothing worthwhile to add, other then that I’ve also definitely
wanted something like this. rubyquiz?

  • rob

On Fri, 1 Dec 2006, James Edward G. II wrote:

My biggest request: a sane way (read: not-cron-like) to schedule events. :wink:

how bout this as the time spec?

http://runt.rubyforge.org/

??

-a

On Nov 30, 2006, at 11:47 AM, [email protected] wrote:

Quiz size…

i’m working on a library for this now. any request?

Ara, you just plain rock.

My biggest request: a sane way (read: not-cron-like) to schedule
events. :wink:

James Edward G. II

James Edward G. II wrote:

My biggest request: a sane way (read: not-cron-like) to schedule
events. :wink:
How about stealing from schtasks
(http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/schtasks.mspx?mfr=true)?
(ducks away and hides)
It doesn’t have to be so convoluted.

Define the task like this

class ScheduledTask
attr_reader :name,:schedule,:schedule_params
end

Schedule is one of :minute, :hourly, :daily, :weekly, :monthly, :yearly

then according to schedule you have different options.
Universal options:
:once to generate the event only once. It’s not there, then we get
repeats.
:start_time to define when to start counting. If you leave it undefined
the timer starts immediately. If you define it, it should be in the
future.
interval (after x minutes/hours/days/weeks/months/years an event will be
generated. if once is defined it runs once x /whatever/ after
start_time)

An option valid for weekly and monthly can be :day, where you can
specify the day of the week (1-7) or month (1-31).

Would that be simple enough?
Cheers,
V.-

On 11/30/06, Damphyr [email protected] wrote:

My requirements include firing at intervals (every thirty minutes, every

Try this in EventMachine:

require ‘rubygems’
require ‘eventmachine’

EventMachine.run {
EventMachine.add_periodic_timer(60) {
# The code in this block gets executed every sixty seconds
}
EventMachine.add_periodic_timer(3600) {
# The code in this block gets executed once an hour
}
}

You can read the timer definitions out of a config file, configure
them dynamically on the fly, or build them with a GUI.

James Edward G. II wrote:

??

Ah yes, I looked into Runy recently when someone use it to solve a Ruby
Quiz. Neat stuff. Plus, if we want additions we can just patch them
into Runt. I like it.
Nice ideas. I still need a UI wrapper for this code though and a way to
configure events that is non-programmer friendly.
And ofcourse the little ticker in it’s thread that checks the schedule
and fires the events.

Cheers,
V.-

[email protected] schrieb:

how bout this as the time spec?

http://runt.rubyforge.org/

Ara, this would be nice, but I think it’s difficult to determine the
time of the next event with Runt’s temporal expressions. I’m sure you
don’t want to call Runt::TExpr#include? every n seconds.

Regards,
Pit

On Nov 30, 2006, at 2:30 PM, [email protected] wrote:

On Fri, 1 Dec 2006, James Edward G. II wrote:

My biggest request: a sane way (read: not-cron-like) to schedule
events. :wink:

how bout this as the time spec?

http://runt.rubyforge.org/

??

Ah yes, I looked into Runy recently when someone use it to solve a
Ruby Q… Neat stuff. Plus, if we want additions we can just patch
them into Runt. I like it.

James Edward G. II

On Fri, 1 Dec 2006, Pit C. wrote:

[email protected] schrieb:

how bout this as the time spec?

http://runt.rubyforge.org/

Ara, this would be nice, but I think it’s difficult to determine the time of
the next event with Runt’s temporal expressions. I’m sure you don’t want to
call Runt::TExpr#include? every n seconds.

indeed. this is the only major design flaw. still, if one assumes a
granualrity of not more than 60s (ala cron) then this approach isn’t too
bad.
between the dates/include methods one can determine apriori if an event
should
be scheduled for the next minute ‘tick’.

i’m assuming there is either a solution implied in the code or that one
can be
added without too much trouble - the bulk of the work has already been
done in
this lib, so even if it isn’t there now, i’m sure a solution will
present
itself.

now. what do you suggest?

:wink:

-a

On 12/1/06, [email protected] [email protected] wrote:

now. what do you suggest?

Runt looks nice. Another package is Chronic. It was part of the
natural language processing presentation at RubyConf this year. All
Chronic does, though, is take human “fuzzy” times and turns them into
actual Time objects.

Chronic.parse “next Thursday at seven am” #=> Time object

http://rubyforge.org/projects/chronic/

What is needed to make Runt work for a scheduler is a next_time method
that would return the next Time that this event should happen given
Time.now. The scheduler then maintains a queue of the “next time” for
all events and pulls them from the queue in order. When an event runs,
the last thing it does is pulls the next_time from Runt and adds that
to the queue (in the proper location). The scheduler thread then
sleeps for N seconds where N is the time till the next event in the
queue needs to happen.

So, maybe a combination of Chronic (to get the nice human readable
format) and Runt (to keep track of recurring events) would work?

TwP

[email protected] schrieb:

now. what do you suggest?

:wink:

I, too, think it should be possible to add the missing functionality to
Runt. Unfortunately I have no time to do it myself, so all I can say is:

Go ahead :wink:

Regards,
Pit

On 12/1/06, [email protected] [email protected] wrote:

http://rubyforge.org/projects/chronic/

rather, i think one must

  1. constrain even runner to check only every n seconds, ala cron

You’re still going to have the missed events problem with the runner
regardless of the time granularity. If you only check every ten
seconds but notifications take twenty, then a whole set of
notifications are missed.

Sounds like (regardless of using cron style runner or Runt “next time”
conventions) missed notifications need to be handled in a predictable
manner.

  1. just drop them
  2. send out an extra notification immediately
  3. queue up the missed notifications for the next time
  1. have the event interalize the time iteration itself so it can start
    threads whenever it needs

Will this cause a slow thread death with lots and lots of events? The
ruby thread scheduler might eat up all your processor trying to
schedule 1000+ threads?

At the last ruby group meeting, Nathan Witmer showed me a nice little
“thread per notification” system he put together. It sounds very
useful for this project of yours.

My $0.02

Blessings,
TwP

On Sat, 2 Dec 2006, Tim P. wrote:

rather, i think one must

  1. constrain even runner to check only every n seconds, ala cron

You’re still going to have the missed events problem with the runner
regardless of the time granularity. If you only check every ten seconds but
notifications take twenty, then a whole set of notifications are missed.

nah. you’d raise an error if events were scheduled at finer than ‘n’.
in
cron it’s simply not possible - same thing. alternatively you can merge
into
minute buckets.

Sounds like (regardless of using cron style runner or Runt “next time”
conventions) missed notifications need to be handled in a predictable
manner.

  1. just drop them
  2. send out an extra notification immediately
  3. queue up the missed notifications for the next time

agreed. i’d add:

  1. call user handler - specification possible at event creation

there is some uber cron thingy on macs that handles this i think…
anyone?

  1. have the event interalize the time iteration itself so it can start
    threads whenever it needs

Will this cause a slow thread death with lots and lots of events? The
ruby thread scheduler might eat up all your processor trying to
schedule 1000+ threads?

it sure could. i’m of the opinion though, that users should be allowed
to
shoot themselves in the foot - if you want to schedule 40,000 events per
second then fine, maybe your quantum computer can actually handle it!
:wink:

a warning or hard/soft limits might be a good compromise.

At the last ruby group meeting, Nathan Witmer showed me a nice little
“thread per notification” system he put together. It sounds very useful for
this project of yours.

link?

-a

On Sat, 2 Dec 2006, Tim P. wrote:

now. what do you suggest?

Runt looks nice. Another package is Chronic. It was part of the natural
language processing presentation at RubyConf this year. All Chronic does,
though, is take human “fuzzy” times and turns them into actual Time objects.

Chronic.parse “next Thursday at seven am” #=> Time object

http://rubyforge.org/projects/chronic/

oh yeah - i’d forgotten about that. thanks.

What is needed to make Runt work for a scheduler is a next_time method that
would return the next Time that this event should happen given Time.now. The
scheduler then maintains a queue of the “next time” for all events and pulls
them from the queue in order. When an event runs, the last thing it does is
pulls the next_time from Runt and adds that to the queue (in the proper
location). The scheduler thread then sleeps for N seconds where N is the
time till the next event in the queue needs to happen.

i don’t think that’ll quite work because:

scheduler.on(every_minute) do
task_that_takes_five_minutes
end

of course threads can help, but it the scheduler allowed milli-second
precision for firing events (why not) you’d have a race condition where
new
evnets might not be started because ‘next time’ was missing during the
time we
started the last one.

rather, i think one must

  1. constrain even runner to check only every n seconds, ala cron

  2. have the event interalize the time iteration itself so it can
    start
    threads whenever it needs

So, maybe a combination of Chronic (to get the nice human readable format)
and Runt (to keep track of recurring events) would work?

yeah. whatever solution comes out should definitely add nice syntax for
common dates.

cheers.

-a

On 12/1/06, Michael G. [email protected] wrote:

You’re still going to have the missed events problem with the runner
minute buckets.

restrictions<
http://en.wikipedia.org/wiki/Daemon_(computer_software)>,

xinetd http://en.wikipedia.org/wiki/Xinetd,
atdhttp://en.wikipedia.org/w/index.php?title=Atd&action=edit,
crond http://en.wikipedia.org/wiki/Crond and
watchdogd<http://en.wikipedia.org/w/index.php?title=Watchdogd&action=edit

.
Apple has stated that it intends to eliminate all of the aformentioned
services in favor of launchd. As of OS X v10.4 Apple has moved most of the
processes handled by the previously mentioned daemons to launchd. By
consolidating all the launch services into one program, launchd
significantly shortens boot time on slow computers."[1]
[1] http://en.wikipedia.org/wiki/Launchd

Sorry everyone, I had no idea this paste would turn out so hideous.