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

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

crontab? File locks? docker???

Writing a simple cyclic thingy isn't that hard. Let's say you have a program that calculates the meaning of life, the universe and everything. It takes a varying time to execute. You want to call it every ten seconds or so, except when it takes longer to run. First, we need the program:

#!/usr/bin/env perl use strict; use warnings; sleep(int(rand(10) + 5)); print "42\n";

Then we write a cyclic executive that keeps track of the run time of the external program (=the scheduler):

#!/usr/bin/env perl use strict; use warnings; use Time::HiRes qw(time sleep); my $cmd = "./meaningoflifetheuniverseandeverything.pl"; my $cycletime = 10; while(1) { my $starttime = time; `$cmd`; my $endtime = time; my $timetaken = $endtime - $starttime; if($timetaken >= $cycletime) { print "Immediate restart\n"; next; } my $sleeptime = $cycletime - $timetaken; print "Sleeping for $sleeptime\n"; sleep($sleeptime); }

This effectively implements a simple "minimum cycle time" scheduler:

Sleeping for 0.986798048019409 Sleeping for 4.98646092414856 Sleeping for 3.98296499252319 Immediate restart Immediate restart Immediate restart Immediate restart

If you want a more crontab like behaviour with start times aligned to specific times, you can use take the current time, calculate the modulos (division remainder) for the cycle time. Then calculate difference between that and a full cycle time interval how long to sleep. Like this:

#!/usr/bin/env perl use strict; use warnings; use Time::HiRes qw(time sleep); my $cmd = "./meaningoflifetheuniverseandeverything.pl"; my $cycletime = 10; while(1) { my $endtime = time; my $sleeptime = $cycletime - ($endtime % $cycletime) - 1; if($sleeptime) { print "Sleeping for $sleeptime\n"; sleep($sleeptime); } `$cmd`; }

Result:

Sleeping for 9 Sleeping for 5 Sleeping for 9 Sleeping for 6 Sleeping for 6 Sleeping for 7

This has a jitter of up to one second, but that should be acceptable enough, i think. Depending on your required time zone settings, you also might have to tweak the whole thing by about 37 seconds, plus/minus a couple of leap seconds every few years, something like this:

my $TAIoffset = -37; ... my $endtime = time + $TAIoffset;

But that's probably overkill for most purposes.

perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'

In reply to Re^2: singleton lock not reliable by cavac
in thread singleton lock not reliable by pidloop

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



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2022-08-08 11:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?