Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

breathe - beyond 'nice'

by tye (Sage)
on Jan 02, 2003 at 17:27 UTC ( [id://223804]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Scripts
Author/Contact Info tye
Description:

Run code in the background even more nicely than is possible with 'nice'.

We have administrative tasks that run on the PerlMonks database server regularly. These make the site quite sluggish even if run via "nice -99". So I wrote this.

It runs a command nice'd but every few seconds it suspends the command for several seconds.

Updated.

#!/usr/bin/perl -w

use strict;
use POSIX "WNOHANG";

Main( @ARGV );
exit( 0 );

sub Spawn {
    my $pid= fork();
    die "Can't fork: $!\n"
      if  ! defined $pid;
    return  $pid   if  $pid;
    exec( @_ );
    die "Can't exec $_[0]: $!\n";
}

sub Sleep {
    my $secs= shift( @_ );
    select( undef, undef, undef, $secs );
}

sub Main {
    die qq[Usage: $0 [work wait [nice]] command [args]
      work  Number of seconds to let "command" work at a time [3]
      wait  Number of seconds to make "command" wait inbetween [6]
      nice  Optional command like "nice" or [nice -20]\n]
      unless  @_;
    unshift @_, qw( 3 6 nice -20 )
      unless  $_[0] =~ /^\d*\.?\d+$/;
    my $work= shift( @_ );
    my $wait= shift( @_ );
    my $kid= Spawn( @_ );
    while(  $kid != waitpid( $kid, WNOHANG() )  ) {
        Sleep( $work );
        kill 'STOP', $kid;
        Sleep( $wait );
        kill 'CONT', $kid;
    }
    exit( $? >> 8 );
}
Replies are listed 'Best First'.
Re: breathe - beyond 'nice'
by dragonchild (Archbishop) on Feb 18, 2004 at 01:52 UTC
    I'm curious - why would you choose to parse @ARGV yourself instead of using something like Getopt::Long?

    ------
    We are the carpenters and bricklayers of the Information Age.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      Well, for one thing: the program doesn't handle any options (command-line arguments that start with '-'). And I think that's a pretty good reason for not using a module that handles command-line options! (:

      For another, even if there was a module to handle "use these default prefix arguments if the first argument isn't a number," I doubt that using it would be any simpler than the two-line construct I used:

      unshift @_, qw( 3 6 nice -20 ) unless $_[0] =~ /^\d*\.?\d+$/;

      Note that I left it to Perl to warn the user if their second argument "isn't numeric" (if the first was).

      I suppose I could go for a more complicated (to implement, to use, and to explain) usage, but it didn't seem worthwhile. Maybe if I'd already picked one of the many, many command-line option modules as my favorite and committed the details of how to use it to memory, then I might have gone that route without much extra work.

      Just like I sometimes use named arguments to subroutines if there is enough reason but, if some order of arguments "makes sense" and there aren't very many, I'll just use the simpler positional arguments.

      Even trying to think in terms of Getop:: command-line design, I don't see a usage that I really prefer. For example, something like one of these:

      breathe [-r RUN] [-s SUSPEND] [-n "NICE OPT"] CMD [ARG ...] breathe [-r RUN] [-s SUSPEND] [-n] [NICE OPT] CMD [ARG ...]

      would mean that I could specify one or two non-default values while using the other default(s), but I prefer to specify both WORK and WAIT together if I change one (their ratio is more important than their individual values but having the user specify a 'ratio' and 'granularity' just makes it harder to explain).

      And I don't like requiring quotes nor splitting '-n' (for 'no default "nice -20"') from specifying the replacement 'nice' nor reimplementing nice's option handling (not shown).

      And I'd have to remember 'r' for 'run'/'resume' (not 'w' for 'work' nor 'e'/'x' for 'execute' nor 'c' for 'continue' ...) and 's' for 'suspend'/'sleep' (not 'w' for 'wait' nor 'p' for 'pause' nor 'd' for 'delay' ...) or I'd have the same problem remembering '--run' etc. While I have no problem remembering 'work then wait', since that is how it must happen (you can't spawn a pre-suspended subprocess) so I don't have to consult the usage message.

      Now, if I one day want to add another option, I may decide it is worth splitting things up. It is certainly near the edge of that point. :)

      - tye        

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://223804]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (2)
As of 2024-04-16 21:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found