Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Representing windows of time in a string

by Nitrox (Chaplain)
on Oct 30, 2003 at 16:04 UTC ( #303290=perlquestion: print w/replies, xml ) Need Help??

Nitrox has asked for the wisdom of the Perl Monks concerning the following question:

I've written an application that monitors the health of numerous servers and now I need to expand the "alerting" routine.

I'm trying to find the best way to store "windows of time" in a string (or an array of strings) (which is stored in a database and relates to the pager group that is responsible for that particular server). For example, "if server Foo fails and its currently Monday-Friday, 9:00-17:00 then page Group1".

The format that Swatch uses in it's config for the "when" option looked hopeful but only supports one "window". Here's an example: when=range_of_days:range_of_hours So if I wanted to be paged any time of the day on Saturday or Sunday the syntax would be: 7-1:1-24.

That works great for simplex windows but I already need to account for situations like:

If Foo fails: AND its Mon-Sat (any hour) OR its Sun !6-8 (any hour except between 6-8am) THEN page Group3
I also thought about utilizing the crontab syntax, so I went and read through the docs for many of the Schedule::Cron::* modules. Unfortunately I didn't see "the one" that I have envisioned in my head. I'd like to pass a crontab style string to the module and have it simply return true if the passed string would currently trigger an event.

Has anyone done any projects similar to this?


Replies are listed 'Best First'.
Re: Representing windows of time in a string
by Limbic~Region (Chancellor) on Oct 30, 2003 at 17:03 UTC
    As I mentioned in the CB, The Panther has a section on using bitmap vectors to determine scheduling conflicts. It is just a matter of logically AND-ing the two bitmaps.

    Each hour in the week would be one bit. You would be storing a 21 byte bitmap vector. If the bit is set, then there is a problem if the event happens at this hour. The task then is to design a way to parse your range and localtime() into the bitmap vector.

    The following is very basic, but it gives you a fully functional framework. Expand it as you see fit.

    I hope this helps - L~R

      L~R, thanks for the full framework! I was headed down the same path and manipulated the examples from the Panther to work with 24 hours per day:
      #!/usr/bin/perl -w use strict; my %base_hours = ( sun => 0, mon => 24, tue => 48, wed => 72 , thu => +96, fri => 120, sat => 144 ); my $vector = interval_parse("Sat 9-17, Sun 9-17"); my $bits = unpack("b*", $vector); print $bits, "\n"; sub interval_parse { my ($interval_sequence) = @_; my ($time_range) = ""; foreach my $day_hours (split /,/, $interval_sequence) { my ($day, $from, $to) = ($day_hours =~ /([A-Za-z]+).*(\d+)-(\d+ +)/); my $base = $base_hours{lc $day}; $from += $base; $to += $base; for (my $i = $from; $i < $to; $i++) { vec($time_range, $i, 1) = 1; } } return($time_range); }
      Thanks for the pointer!


Re: Representing windows of time in a string
by simonm (Vicar) on Oct 30, 2003 at 16:50 UTC

    Strictly speaking, crontab schedules define "points" in time when the specific actions are triggered, whereas it seems you need a broader "range" or "set" of time spans.

    It might be overkill, but I think you should be able to accomplish this with the DateTime modules.

    For example, take a look at DateTime::Event::ICal... Using the ICal format, you could express your rules as:

    my $incident = DateTime->from_epoch( time() ); # your data here my $ok_down = DateTime::Event::ICal->recur( byday=>["su"], byhour=>[ +6, 7] ); unless ( $ok_down->contains( $incident ) { # notify }
Re: Representing windows of time in a string
by davido (Cardinal) on Oct 30, 2003 at 17:11 UTC
    Advanced Perl Programming, otherwise known as the Panther book from O'Reilly & Assoc. has a discussion that you would probably find beneficial. Chapter two, section three:

    Consider that there are only 24 * 7 = 168 hours in a week, the entire week's schedule can be represented by a bitmap vector of 21 bytes (168 / 8) .... The other cool thing is that you can obtain time conflicts by logically AND-ing two bitmaps.

    The implementation example provided in the book uses vec to construct the bitmaps, and logical 'and' to check for overlaps.

    Hope this helps...


    "If I had my life to live over again, I'd be a plumber." -- Albert Einstein

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://303290]
Approved by gjb
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (2)
As of 2023-06-07 23:11 GMT
Find Nodes?
    Voting Booth?
    How often do you go to conferences?

    Results (29 votes). Check out past polls.