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

I had searched with the Super Search and quite frankly I realy had no idea as to what keywords to use for this type of problem. So forgive me if this has been answered dozens of times.

I'm writing a server type program that backgrounds itself. So it will be running continuously until its killed. What I need to do is to be able to schedule a process within the server to run once every half hour or so and telling it to sleep is not an option since it needs to listen for connections. I came up with this code but as I see it its completely unacceptable since it would run over and over again for a minute. A valiant attempt, however I fell in the moat halfway over.

This attempt uses Date::Calc's Today_and_Now
sub is_it_time { my ($year,$month,$day, $hour,$min,$sec) = Today_and_Now(); if ($min == 29) { return 1; } else { return 0; } }
Any ideas as to how to mimic cronlike scheduling within a perl program for running subroutines without blocking other processes?

I am at your mercy,
Brother BMaximus
  • Comment on Scheduling internal functions/processes to run within a program (like cron does programs)
  • Download Code

Replies are listed 'Best First'.
Re: Scheduling internal functions/processes to run within a program (like cron does programs)
by Corion (Patriarch) on May 23, 2001 at 13:42 UTC

    I see two possible ways of approaching this :

    First, you use fork(), and spawn off all the periodic children as children who sleep(). This is easy, as long as you don't need elaborate communication between your children.

    The other method would be to implement your own version of cooperative multitasking. I've done something like that in Push HTTP Server, but before you embark on anything like this, have a look at POE, which also does this. Before you choose to go down that way, note that you can't allow any long operations unless you can stomach your whole server being non-respondant. This also means that you could want to look a bit at asynchronous IO, as far as your OS supports it (and Perl).

      You know. After some mucking around in CPAN's search. I found Schedule::Cron. Which basicaly is exactly what I wanted.

      The moral of this story. Search CPAN first.

      BMaximus

        I'm awfully happy to see you found this on your own. ;-)

        I was getting ready to reply to you with "Check CPAN for Schedule::Cron!"

        All's well that ends well...

        ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        Peter L. Berghold --- Peter@Berghold.Net
        "Those who fail to learn from history are condemned to repeat it."
        
Re: Scheduling internal functions/processes to run within a program (like cron does programs)
by arhuman (Vicar) on May 23, 2001 at 14:26 UTC
    Rather than the sleep, you could use the asynchronous method :
    alarm and a signal handler
    (can be combined with fork)
    $SIG{ALRM} = sub { #Your code here }; eval { alarm(60); # Your code will be executed in 60 seconds # do something here # anytime during this 60 sec you can cancel the alarm with alarm(0 +) };
    Example of use:
    You can manage timeout by limiting the time allowed to answer
    (and/or even pop up a message to say "$x sec remaining...")

    UPDATE :
    As my previous example seems to be unclear, here is a complete example from a previous post to manage the timeout :
    #!/usr/local/bin/perl -w use strict; use IO::Socket; { my $timeout = 0; my $sock = undef; $SIG{ALRM} = sub {$timeout = 1; die}; eval { alarm (2); $sock = new IO::Socket::INET(PeerAddr=> '10.1.1.18',PeerPort => + 29,); alarm (0); } die "Can't open socket: timeout=$timeout\n" if ($timeout or !$sock); print "I would print to the socket now, if I knew what I was connecte +d to\n"; close ($sock); }


    "Only Bad Coders Badly Code In Perl" (OBC2IP)

      Until "safe Perl signal handlers" gets rolled out in a future version of Perl, I'd avoid this type of solution as each instance of a Perl signal handler running introduces a small but non-zero chance that Perl will corrupt some of its internal structures, eventually leading the script misbehaving.

              - tye (but my friends call me "Tye")
      two words arhuman - "split infinitive" :-D
        "Personally, I like to defiantly split my infinitives. :-) "
        -- Larry Wall

        Found today on Perlarchive ;-)

        But, as I'm not larry =>

        "Only Bad Coders Code Badly In Perl" (OBC2BIP)