Hi all,

I'm trying to write a daemon to emulate the cron scheduler for a collection of miscellaneous Perl scripts lying around our servers. Essentially, crontab entries will be stored in a database table and this daemon should poll the db every so often to refresh my psuedo crontab file. Once a minute, it will determine which scripts to run, and fork off a new process to exec() it.

There are two reasons we're not using cron here. First is that we don't want to allow people to edit crontabs willy-nilly as they create custom scripts they want run periodically. And secondly, as far as I know, cron doesn't have any sort of logging feature. We need to track what scripts ran, what kind of exit codes they produced when (if) they completed, etc. in the case of database or server outages. It'll make our lives a WHOLE lot easier if we could track down what needed to be rerun and why. Right now, no such mechanism is in place and system downtime is a disaster.

Finally, my question. This daemon wakes up once a minute and forks off processes as necessary. The problem are the incoming SIGCHLD signals the daemon receives during this time and, more critically, while its sleeping off the remainder of the minute before the next iteration. If I set $SIG{CHLD} to 'IGNORE' I don't have to worry about reaping the children as they die, but I also can't track exit statuses. However, if I set up any kind of handler, it can interrupt the process as it sleeps or at any other time, even with safe signals in 5.8.7.

So, is there a clean way to avoid this problem? Ideally, I'd like a system that can avoid defunct processes sitting around in the process table at all, but that's livable provided they're reaped and their exit statuses returned to me in a timely fashion.

There are two approaches that I've thought of, but can't seem to implement either. Any advice would be helpful:

1) A dedicated signal handling thread. I know of the Thread::Signal module for 5005threads, but is there a similar technique for Perl's ithreads? If the daemon process could redirect all incoming CHLD signals to a dedicated handling thread without interrupting its rest, that would be terrific. I don't actually need to go through the exit statuses immediately, but I'd like to reap the children as soon as possible. I can let the exit statuses sit in a hash until I get around to it in the next iteration.

-or-

2) Call a reaper function at the beginning of each minute's iteration to clean up any processes that have completed since the last harvest. Is there a way to defer any CHLD signals until after the daemon has forked off any necessary children and slept? This is the only way I could foresee this particular approach being successful, though again I'm open to suggestion. I've tried using sigprocmask, but it seems finicky at best as the signals I know have been generated are skipped for at least one additional iteration before they're received.

Clearly option 1 is the cleanest approach, but is it possible to accomplish?

Thanks for all of your help,
--overbyte

In reply to SIGCHLD and sleep() by overbyte

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.