Subject: New version of the $scheduler

From: [email-masked] (C. Regis Wilson)
Date: Sun, 26 Sep 1993 13:11:03 -0700

Hello, Gustavo ([email-masked]) and I have been
working on the latest version of the $scheduler.  It's not ready yet
for a full release, but we are looking for some "beta" testers.  I would
like to get a response from current users of the $scheduler that is on
parcftp:/pub/MOO/contrib/moocode, or any users who run code based
on, or close to the $scheduler there.  Please mail me if you are
interested.

For those who don't know what the scheduler is, I include part of a help
file: 

---------------------
Premise:  Sometimes, it is necessary to have moo-tasks (processes) which execute with a long period, say once a day, every month,  
etc.  Sometimes, it is necessary to have verbs execute repetitively, over and over and over again.  Sometimes, it is necessary to  
have verbs which need to be executed at a particular time.  And, sometimes, a combination of the above needs to occur:  A verb  
that runs every hour on the hour, for example.  Assuming the premises are true, these processes must stay in the task queue, often  
forming clutter which must be weeded through by the wizards.  Thus, the scheduler is born.

Scheduler:  The scheduler is designed as a process storage chamber.  Verbs which execute with a long period (an hour, a day, etc.)  
can be stored on the scheduler, without filling up the queued task list.  Verbs which need to happen with a certain number of  
iterations, or infinitely, can be handled by code in the scheduler, reducing the burden on the programmer.  The scheduler also  
accounts for drift in lag, allowing a verb to run at a certain time, every time.

Building Blocks:

:schedule       (rel_time,obj,verb[,args])
:schedule_at    (abs_time,obj,verb[,args])
:schedule_every (rel_time,obj,verb[,args])

  "rel_time" indicates a time interval from the present moment, that is: a relative time, or "x seconds from now"
  "abs_time" indicates an absolute time, for example: 749069038
  "obj" indicates the object on which the verb you will call resides
  "verb" is the verb you will be calling
  "args" is/are the argument(s) you will use in the verb call.

  The "rel_time" is a number, given in seconds.  The "obj" is an object number, like #1, the verb is a string, like "tell".  The  
"args" is a list of arguments to be passed, and may be left off.  If left off, the null list {} will be used as argument.

Examples:

:schedule(35,#11,"announce_all",{"I am here!"})

  which is equivalent to:

  ;fork(35) #11:announce_all("I am here!"); endfork

:schedule_at(749069497,$fountain,"start")

  equals:

  ;fork(time()+6*24*3600) $fountain:start(); endfork

:schedule_every(15,$puppet,"action",{"move","eat","walk"})

  is fairly close in meaning to:

  [verb code on $puppet]
      ...
  fork (15)
    this:(verb)("move","eat","walk");
  endfork

Stuff on top of building blocks:

  Naturally, you may build neat nestings on the scheduler.  You could do a ":schedule_at(time,$scheduler,"schedule_every",{..."  
etc.  However, this is messy, and not easy for beginners.  Hence, the scheduler now has an english-like parser.  Wouldn't it be  
great if you could tell the scheduler to do things "every 5 minutes", "6 times every 3 minutes starting in 5 hours", or "Sun Sep 26  
12:01:29 1993"?  Well you can!

:schedule_english(english_string,obj,verb,args)

"english_string" is of the following form, each part optional, anything not in <brackets> is a string literal:

[<number> times] [every [<number>] <interval>] [starting] [in [<number>] <interval>] [<time>]

  <number> is an integer: positive, of course.
  <interval> is a time interval, recognized by being in the .intervals property.  The lenght of the interval (in seconds) should be in  
the same position in the .intervaltimes property list.  Examples include "6 seconds", "5 minutes", etc., and linked with the key  
word "and".  Other intevals include a digital readout form like ":30" (30 seconds), "1:00:00" (1 hour)
  <time> is an abolute time, same as the output from time() or ctime().  You can also specify a relative time from now, like "12:30  
pm", or "11:30" (defaults to a.m.)

Short List of Examples:

"" (once, now)
"now" (same as above)
"6 times every 5 seconds starting at 12:30 pm"
"every 1:30 starting in 5 minutes"
"every 1 minute and 30 seconds starting in 5:00" (same as above)
"every minute and 30 seconds starting in 0:5:0" (same as above)
"at Sun Sep 26 13:01:29 1993"
"Sun Sep 26 13:01:29 1993" (same as above)
"in 1 hour and 15 minutes and 12 seconds"
"in 1:15:12" (same as above)
"at 1:15:12 am"  (NOT the same as above)
"at 11:30 a.m."
"at 11:30:00" (same as above)
"every 15 minutes and 1 second starting next tuesday" (at midnight)
"starting next month" (not advisable, since a "month" is 4 weeks, NOT today's date next month)
"next july at 12:30" (begins 12:30 am on July 1)

More Stuff on top of Building Blocks:

Beside "hiding" tasks on the scheduler from the queued task list, one may categorize tasks.  For example, tasks which deal with  
clocks can be grouped on one scheduler called "Clock Tasks".  However, each scheduler uses a process itself.  Thus, if you have  
many schedulers, your queued task list can be cluttered with scheduler tasks.  To fix this, you can have master schedulers.  Set  
the .master property of a scheduler to the object number of some other scheduler.  The master will then be in charge of running  
its subordinate.  The child scheduler will register its task on the master, without creating another entry in the queued tasks list.   
Any scheduler can be the master of another, and you can create tree structures of master schedulers.  BUT!  There is no code to  
look for circular references.  Be smart.