Cron Like Scheduler

Let's go back to the ticket scheduler implementation. As you remember, the scheduling information is stored in the probingschedule table, which has the following fields:

Table 9-10. The probing schedule table fields

Field

Data Type

Description

id

Integer

The unique identifier.

hostprobe_id

Integer

Points to the corresponding host probe entry. This field contains the ID of the host probe row.

probeinterval

Integer

The probing interval in minutes.

My implementation of the scheduler is slightly different from the logic that the cron application is using. The cron configuration allows you to specify exactly when something should happen, such as "5 minutes past the hour, every Tuesday" or "every 10 minutes, between 9 and 17 every day", whereas my scheduler understands only the time periods such as "every X minutes."

The algorithm I'm going to use to calculate whether something needs to happen is this:

• Take the number of seconds since the epoch, or arbitrary starting point (1970-01-01).

• Divide it by 60, so it is expressed in minutes.

• The recording is scheduled to happen at this time if the current time expressed in minutes is divisible by the probing interval value; in other words, current time modulus probe interval should equal zero.

This may sound rather complicated, but the SQLite3 SQL language allows me to perform all those checks within one SQL statement. I am using strftime( '%s', ' now') built-in function to get the number of seconds since the epoch, which is converted into minutes and the modulus of the probing interval checked in the same statement. Listing 9-10 shows the full code of the Ticket Scheduler class.

Listing 9-10. The TicketScheduler class inserts probing tickets into the ticket queue. class TicketScheduler(multiprocessing.Process):

def __init__(self, event): self.event = event self.con = sqlite3.connect('monitor.db') super(TicketScheduler, self).__init__()

from datetime import datetime while True:

self.event.wait()

res = [r[0] for r in self.con.execute( SELECT hostprobe_id

FROM probingschedule WHERE (strftime('%s', 'now')/60) % probingschedule.probeinterval = 0; )]

for probe_id in res:

self.con.execute("INSERT INTO ticketqueue VALUES

self.con.commit() except KeyboardInterrupt: pass

Therefore the result stored in the res array is going to contain the ID numbers of all host probes that need to be executed that minute. The next for loop inserts corresponding records into the ticket queue. Each record contains the probe ID and the timestamp, and the dispatched flag is set to zero, which means the ticket hasn't been sent to the target host yet.

Was this article helpful?

0 0

Post a comment