ashok.g has asked for the wisdom of the Perl Monks concerning the following question:

Hi Folks,

I am looking at all the ways where I can have Perl to do my task.

This is more of a logic, but just want to make sure is there any Perl module defined for this (I don't think so but trying by posting this link).

I need to retrieve data from a file which has two values: 1) a Perl script and 2) An interval. After retrieving the Perl script should always be execute based on the respective interval and all the entries are dynamic.
For Example:
a.pl:15 b.pl 25 ... ...
I can do that using CRON to add each entry but this is always dynamic and I don't want to use CRON.

Can anyone give your suggestions in this regard?

Thanks,
Ashok.

Replies are listed 'Best First'.
Re: Help with Perl
by i5513 (Pilgrim) on Jan 23, 2012 at 23:03 UTC

    Hi Ashok.g,

    Ok, your task can be programmed dynamicaly, but .. why don't you want to use cron (if you are in Unix wolrd)?

    Two approaches:

  • Regenerate /var/spool/cron/user when you need, cron will reload in the next minute
  • Regenerate /etc/cron.d/yourtask when you need it, cron will reload it, and surely will be more readable and maybe easy to implement.
  • Of course where you write "a.pl 25" will be "*/25 * * * * /path/to/a.pl"

    So, if you are in Unix environment, why not cron ?

    Thanks

      I gotta chime in on this one ... agreeing wholeheartedly.   Always look for the simplest available solution that leverages existing facilities.   If cron can reasonably do the job, without you creating something that will be impossible to understand three months from now, then that is probably the way that you want to do it.

      Another notion would be that you could use cron simply to execute some script at the smallest possible interval ... then maintain a list or database (SQLite?) of “what needs to be done” and “the last time it was done.”   The script simply executes each command that has come due, then exits until next time.   But, I am very reluctant to build complicated solutions to what ought to be simple, routine problems.

      As I said in my post, the scripts and interval are always dynamic..... So I didn't want to always add and delete CRON entries... may be this will be my last option....
        Maybe you didn't get the idea:

        Your scheduler can be regenerate by another script which can be launch at regular intervals (by cron) or by a daemon which is always investigating if changes to scheduler are necessary

        Where does my proposition fail?
Re: Help with Perl
by choroba (Cardinal) on Jan 23, 2012 at 17:36 UTC
    I do not get it. What separator is used, space or colon? How do you get an interval from a single number?
      Here Space or tab is used and the interval is in seconds so it might be a single digit or any. Please suggest.
        Oh, do you mean each script should be called repeatedly after the given interval?
Re: Help with Perl
by choroba (Cardinal) on Jan 24, 2012 at 09:02 UTC
    I still do net get it. If the file contains the line
    a.pl 30 b.pl 35
    does it mean that in 30 secs, the script a.pl should be run? And after the 30 secs, another run of a.pl should be scheduled based on the file (which might have changed in the meantime, hence "dynamic")? But you do not want to start a new b.pl that is scheduled to happen in 5 seconds - but what if there is a new line in the file saying
    c.pl 15
    Please, be much more specific.
      What I want is, for example the script invoker.pl will read the file conf.txt:
      a.pl 30 b.pl 20
      Split each line and validate *.pl and a digit and run a.pl at every 30 minutes and b.pl for every 20 minutes. If invoker.pl dies then when again I will run the script, the contents of conf.txt may get changed. Hope this will make more understanding.

      The challenge here is to run each script for the specified interval continuously. Can we do that?

      Thanks in advance.

      Thanks,
      Ashok
Re: Help with Perl
by choroba (Cardinal) on Jan 24, 2012 at 18:03 UTC
    Searching for "timer" on CPAN can give you some solutions, e.g. IO::Async::Timer::Periodic (not tested myself). Or, you can write your own:
    #!/usr/bin/perl use warnings; use strict; my $start_time = time; my %dispatch; my %interval_of; while (<>) { my ($script, $interval) = split; $interval *= 60; push @{ $dispatch{ $start_time + $interval } }, $script; $interval_of{$script} = $interval; } while (1) { foreach my $time (keys %dispatch) { if (time >= $time) { for (@{ $dispatch{$time} }) { system "$_ &"; push @{ $dispatch{ $time + $interval_of{$_} } }, $_; } delete $dispatch{$time}; } } sleep 1; }