|
Schedules can not be embedded. A program can have one schedule running at a time. Each schedule is run by a timer called $$timer
. It can be accessed in the scheduler code, which has these members: time
for the current event being handled, period
for the current period, htmlOut
is the HTML output stream and cmd
is the command sent by the control panel client (most likely a brower) -- the last two are valid only in the control block.
To abort a schedule job, run break schedule;
.
The following program emulates a count-down process, where 4 one-time events are run one second apart.
Listing 18.4 countdown.judo -- one-time event |
---|
1: time = date(2001,10,12,19,4,57); 2: schedule starting time { println $$timer.time, ": Three!"; } 3: ++time.second; 4: schedule starting time { println $$timer.time, ": Two!"; } 5: ++time.second; 6: schedule starting time { println $$timer.time, ": One!"; } 7: ++time.second; 8: schedule starting time { println $$timer.time, ": LAUNCH!"; } |
This is a simple repetitive motion:
Listing 18.4 heart_beat.judo -- not-so-accurate repetitive events |
---|
1: beats_per_minute = 80; 2: 3: schedule repeat 60000 / beats_per_minute 4: { 5: println 'puh ... at ', $$timer.time; 6: } |
Next, we emulate a coocoo clock that every hour it plays so many "Cukoo" sound. Lines 1 through 4 gets the time for the next hour. Line 7 gets the time for this event, and its hour attribute is used for the number of "Cucoo" sound.
Listing 18.4 coocoo_clock.judo -- accurate repetitive events |
---|
1: $start = date(); 2: ++$start.hour; 3: $start.minute = 0; 4: $start.second = 0; 5: schedule absolute starting $start repeat 3600000 6: { 7: local time = $$timer.time; 8: for $i from 1 to time.hour { print 'Cukoo...'; } 9: println; 10: } |
Scheduled jobs should run quickly, that is, they should not run longer than the scheduled periods. If they do sometimes and mess up the operation, practical synchronization mechanism should be put in place. For instance, suppose every 5 minutes the job checks the database for unprocessed order data. If it founds some, process them. Sometimes e-commerce site may take so many orders in a short period of time, that within that 5-minute period they can not be all processed. What you can do is, for instance, use a temporary database table; when start processing, set a flag there, and reset it when done; if this flag is set, other jobs will simply bypass. The crux of this solution is, use an operation that is always short than the period to enforce the synchronization.
By issuing a listen on
clause with a port number, you have the scheduled job start a single-thread HTTP server. A title can be specified for the HTML output. If not, the default title is "Judo Scheduler Control Panel".
Listing 18.4 changing_time.judo |
---|
1: history = linkedList{}; 2: 3: schedule repeat 2000 4: { 5: history.add($$timer.time); 6: if $history.length() > 10 { history.remove(0); } 7: } 8: listen on 3333 title '<h1>Changing Time</h1>' 9: { 10: println <$$timer.htmlOut> '<h3>Latest Events</h3>'; 11: for x in history backward { println <$$timer.htmlOut> x, '<br>'; } 12: } |
The job itself does nothing but keeping the execution time in a list for the last 10 events (line 6). Its control panel server listens on port 3333. The control panel is typically run from a browser. The title, "Changing Time", is issued on line 8. The screen is standard above the horizontal line. If and only if both boxes are checked will the job be stopped and closed. Anything user type in to the edit box is sent to the server and becomes the content of $$timer.cmd
. What it means is totally up to your interpretation, such as a mini command system. In the control panel code, we used $$timer.htmlOut
to write out custom content that shows below the horizontal line (lines 10 and 11).